refactory: added UI removed from core plugin.
authorincastrix <incastrix>
Fri, 2 Oct 2009 22:13:12 +0000 (22:13 +0000)
committerincastrix <incastrix>
Fri, 2 Oct 2009 22:13:12 +0000 (22:13 +0000)
558 files changed:
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationSettings.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/GetterSetterUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/IRequestQuery.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/StubUtility.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplateContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplateContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplates.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitCompletion.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/HTMLContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/HTMLUnitContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaDocContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaDocContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaFormatter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaTemplateMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaTemplateMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/TemplateSet.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/Templates.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/IJavaHelpContextIds.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/IJavaStatusConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/JavaElementAdapterFactory.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/JavaElementProperties.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIException.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/ResourceAdapterFactory.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AbstractToggleLinkingAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AddBlockCommentAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AddTaskAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/BlockCommentAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/CompositeActionGroup.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingActionGroup.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingExpandAllRulerAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingToggleRulerAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/IndentAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/OpenActionUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/RemoveBlockCommentAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/SelectionConverter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/SelectionDispatchAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/WorkbenchRunnableAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/AbstractElementListSelectionDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/CheckedTreeSelectionDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/ElementListSelectionDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/ISelectionValidator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/MessageLine.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/SelectionStatusDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusInfo.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/BasicSelectionTransferDragAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDragAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDropAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDragAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/LocalSelectionTransfer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/ResourceTransferDragAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDragSourceListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDropTargetListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ClassFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ClosedProjectFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/CustomFiltersDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FieldsFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterDescriptor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ImportDeclarationFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/InterfaceFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/JavaFileFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NamePatternFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaElementFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaProjectsFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicTypeFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonSharedProjectFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/OutputFolderFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/StaticsFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/AbstractConfigurationBlockPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeAssistConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeAssistPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeFormatterPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeFormatterPreviewCode.txt [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeTemplateBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeTemplatePreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/ColorEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/ColorSettingPreviewCode.txt [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerPropertyPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditTemplateDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditorConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditorPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/FoldingConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/IPreferenceConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorHoverConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaPreferencesSettings.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaSourcePreviewerUpdater.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaTemplatePreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MarkOccurrencesConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MarkOccurrencesPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferenceCache.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MockupPreferenceStore.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/OptionsConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/OverlayPreferenceStore.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/SpellingConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/SpellingPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TemplateEditorSourceViewerConfiguration.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskConfigurationBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskInputDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskPropertyPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/AbstractJavaScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/BufferedDocumentScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CombinedWordRule.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CompositeReconcilingStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/ContentAssistPreference.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CustomSourceInformationControl.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/DocumentCharacterIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/FastJavaPartitionScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTML2TextReader.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTMLPrinter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTMLTextPresenter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/IPHPPartitions.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/ITypingRunListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaAnnotationHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaBreakIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaColorManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaCompositeReconcilingStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaElementProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaHeuristicScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaOutlineInformationControl.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaPresentationReconciler.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaReconciler.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaWordIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/LineBreakingReader.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PHPCodeReader.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PHPPairMatcher.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PreferencesAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SequenceCharacterIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SmartBackspaceManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SubstitutionTextReader.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/Symbols.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRun.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRunDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/comment/CommentFormattingContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingStructureProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/EmptyJavaFoldingPreferenceBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/FoldingMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/FoldingMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/JavaFoldingStructureProviderDescriptor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/JavaFoldingStructureProviderRegistry.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IInvocationContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaReconcilingListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IPHPCompletionProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IProblemRequestorExtension.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IReconcilingParticipant.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaFormattingStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaParameterListValidator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaReconcilingStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategyDQ.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategySQ.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/PHPCompletionProposalComparator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractAnnotationHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/BestMatchHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverDescriptor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverProxy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaSourceHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaTypeHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/ProblemHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/SourceViewerInformationControl.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/ILinkedPositionListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionUI.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/ProposalPosition.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/IHtmlTagConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/IJavaDocTagConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/JavaDocAutoIndentStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCodeScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCompletionProcessor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/AddWordProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/ChangeCaseProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/HtmlTagDictionary.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/JavaDocTagDictionary.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellCheckEngine.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellCheckIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellReconcileDictionary.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellReconcileStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/TaskTagDictionary.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/WordCorrectionProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/WordIgnoreProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/AbstractSpellDictionary.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultPhoneticDistanceAlgorithm.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultPhoneticHashProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultSpellChecker.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/IPhoneticDistanceAlgorithm.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/IPhoneticHashProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckEngine.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckPreferenceKeys.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellChecker.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellDictionary.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellEvent.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellEventListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/LocaleSensitiveSpellDictionary.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/PersistentSpellDictionary.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/RankedWordProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/SpellEvent.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/package.html [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/package.html [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/AbstractProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/BuiltInEngine.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/BuiltInProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/IdentifierEngine.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/IdentifierProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/LocalVariableProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/SQLProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/InclusivePositionUpdater.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/MultiVariable.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/MultiVariableGuess.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/PositionBasedCompletionProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateContentAssistMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateContentAssistMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateEngine.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateInformationControlCreator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/VariablePosition.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplatePreferencesMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplatePreferencesMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplateVariableProcessor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplateVariableProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/DirectorySelector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/ExceptionHandler.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/FilteredList.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPElementVisitor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPFileSelector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPFileUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPProjectSelector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PixelConverter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/ResourceSelector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/SWTUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/StreamUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/StringMatcher.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TabFolderLayout.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TableLayoutComposite.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TwoArrayQuickSorter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/AppearanceAwareLabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ContainerCheckedTreeViewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/DecoratingJavaLabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/FilterUpdater.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/IProblemChangedListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ISelectionListenerWithAST.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/IViewPartInputProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageDescriptorRegistry.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageImageDescriptor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementImageProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementLabels.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaUILabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ListContentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilterAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemMarkerManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemTableViewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemTreeViewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ResourceToItemsMapper.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/StatusBarUpdater.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/StorageLabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/IStatusChangeListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewClassCreationWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewElementWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/CheckedListDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ComboDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/DialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IDialogFieldListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IListAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IStringButtonAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ITreeListAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/LayoutUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ListDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogFieldGroup.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/Separator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonStatusDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/TreeListDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/UITexts.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/actions/RenameLocalVariable.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/actions/RenamePHPIdentifier.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/uitexts.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameIdentifierPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameIdentifierWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameLocalVariablePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameLocalVariableWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/CodeGeneration.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IContextMenuConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IJavaElementSearchConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IPackagesViewPart.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/ITypeHierarchyViewPart.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyManagerExtension.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementImageDescriptor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementLabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementSorter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaUI.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/OverrideIndicatorLabelDecorator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/PreferenceConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/ProblemsLabelDecorator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/CustomFiltersActionGroup.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/GenerateActionGroup.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/GotoMatchingBracketAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/MemberFilterActionGroup.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/OpenEditorActionGroup.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/OpenPHPPerspectiveAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/PHPdtActionConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/SelectionDispatchAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IColorManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IColorManagerExtension.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IJavaColorConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/PHPStringDQCodeScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/SingleTokenPHPScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/IJavaFoldingPreferenceBlock.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/IJavaFoldingStructureProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/package.html [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/java/hover/IJavaEditorTextHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/java/hover/package.html [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewClassWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewElementWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewTypeWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/IncludesScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/OpenDeclarationEditorAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPActionMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPActionMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPEclipseShowAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenAllIncludesEditorAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationEditorAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/ExternalEditorInput.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/ExternalStorageDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/FileStorage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/PHPIdentifierLocation.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorIgnoreSet.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorIgnores.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass1Exporter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass2Exporter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/PHPIdentifier.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/default-obfuscator.xml [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportOperation.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/WizardObfuscatorResourceExportPage1.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/messages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/AnnotationType.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BasicEditorActionContributor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BasicJavaEditorActionContributor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BracketPainter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BreakpointImageProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitAnnotationModelEvent.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitEditorActionContributor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/EditorHighlightingSynchronizer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/GotoAnnotationAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/GotoErrorAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/HTMLDocumentSetupParticipant.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ICompilationUnitDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IJavaAnnotation.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IJavaEditorActionConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IPainter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IPositionManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IProblemAnnotation.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ISavePolicy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationImageProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentFactory.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentSetupParticipant.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaEditorErrorTickUpdater.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaMarkerAnnotation.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction2.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectRulerAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaStorageDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/LinePainter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPAnnotationHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxRdr.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PartiallySynchronizedDocument.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PresentationAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PrintMarginPainter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ProblemAnnotationIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ProblemPainter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/SmartyDocumentSetupParticipant.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ToggleCommentAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/TogglePresentationAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/WorkingCopyManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/actions/RTrimAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/java.gif [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCodeScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCompletionProcessor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLWordExtractor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPAutoIndentStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPConstant.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDoubleClickSelector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPEditorMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPElement.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPFunction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeyword.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPType.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPWordExtractor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyDocCodeScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/syntax.xml [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/togglepresentation.gif [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/HTMLWordDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPColorProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPVariableDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPWhitespaceDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPWordDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/ColorEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/OverlayPreferenceStore.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPPreferencesMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPPreferencesMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPProjectLibraryPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPProjectPropertyPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/HTMLFileWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/HTMLFileWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/NewProjectCreationWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPFileWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPFileWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPWizardMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPWizardMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/TempnewPHPProject.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/EditElementWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/EditElementWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/ElementWriter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/FormElementWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/HTMLUtilities.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/IPreviewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/InsertHTMLElementAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/ListElementWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/NewElementWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/NumVerifyListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/SomeItemInputDialog.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/StringDivider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementCellModifier.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementContentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementLabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementModel.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/UnknownElementWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPlugin.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPluginResources.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewerCreator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewerCreator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/DTDEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentSetupParticipant.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorActionContributor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineContentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineLabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlinePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/ContentAssistPreference.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLPreferenceInitializer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLSyntaxPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/preview.xml [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AbstractDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AnnotationAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AttValueDoubleClickStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDConfiguration.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DeclScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/EntityRule.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NameDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NmtokenDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/PHPXMLPartitionScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SimpleDoubleClickStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SingleTokenScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TagDoubleClickStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TextScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/WhitespaceDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotation.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLCDATAScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLConfiguration.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcileStep.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcilingStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagRule.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTextHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLWordFinder.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/DTDTextTools.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/IXMLSyntaxConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/XMLTextTools.java [new file with mode: 0644]

diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationMessages.java
new file mode 100644 (file)
index 0000000..b308d22
--- /dev/null
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.codemanipulation;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class CodeGenerationMessages {
+
+       private static final String RESOURCE_BUNDLE = CodeGenerationMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private CodeGenerationMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationMessages.properties
new file mode 100644 (file)
index 0000000..7c41c12
--- /dev/null
@@ -0,0 +1,27 @@
+###############################################################################
+# Copyright (c) 2000, 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+AddGetterSetterOperation.description=Generate Getters and Setters...
+
+AddImportsOperation.description=Adding import...
+
+AddMethodStubOperation.description=Create method...
+
+AddUnimplementedMethodsOperation.description=Evaluating and adding unimplemented methods...
+
+AddCustomConstructorOperation.description=Evaluating and adding new constructor...
+
+OrganizeImportsOperation.description=Organizing imports of {0}...
+
+AddJavaDocStubOperation.description=Create Javadoc stub...
+
+AddDelegateMethodsOperation.monitor.message=Creating {0} methods...
+ImportsStructure.operation.description=Updating imports...
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationSettings.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/CodeGenerationSettings.java
new file mode 100644 (file)
index 0000000..8206056
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.codemanipulation;
+
+public class CodeGenerationSettings {
+
+       /**
+        * @deprecated
+        */
+       public boolean createFileComments = true;
+
+       public boolean createComments = true;
+
+       public boolean useKeywordThis = false;
+
+       /**
+        * @deprecated
+        */
+       public boolean createNonJavadocComments = true;
+
+       // public String[] importOrder= new String[0];
+       public int importThreshold = 99;
+
+       public int tabWidth;
+
+       public void setSettings(CodeGenerationSettings settings) {
+               settings.createComments = createComments;
+               settings.useKeywordThis = useKeywordThis;
+               // settings.importOrder= importOrder;
+               settings.importThreshold = importThreshold;
+               settings.tabWidth = tabWidth;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/GetterSetterUtil.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/GetterSetterUtil.java
new file mode 100644 (file)
index 0000000..2ac2194
--- /dev/null
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.codemanipulation;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IField;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.NamingConventions;
+import net.sourceforge.phpdt.core.Signature;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+import net.sourceforge.phpdt.internal.corext.util.JdtFlags;
+import net.sourceforge.phpdt.ui.CodeGeneration;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.core.runtime.CoreException;
+
+public class GetterSetterUtil {
+
+       private static final String[] EMPTY = new String[0];
+
+       // no instances
+       private GetterSetterUtil() {
+       }
+
+       public static String getGetterName(IField field, String[] excludedNames)
+                       throws JavaModelException {
+               boolean useIs = PreferenceConstants.getPreferenceStore().getBoolean(
+                               PreferenceConstants.CODEGEN_IS_FOR_GETTERS);
+               return getGetterName(field, excludedNames, useIs);
+       }
+
+       private static String getGetterName(IField field, String[] excludedNames,
+                       boolean useIsForBoolGetters) throws JavaModelException {
+               if (excludedNames == null) {
+                       excludedNames = EMPTY;
+               }
+               return getGetterName(field.getJavaProject(), field.getElementName(),
+                               field.getFlags(), useIsForBoolGetters
+                                               && JavaModelUtil.isBoolean(field), excludedNames);
+       }
+
+       public static String getGetterName(IJavaProject project, String fieldName,
+                       int flags, boolean isBoolean, String[] excludedNames) {
+               return NamingConventions.suggestGetterName(project, fieldName, flags,
+                               isBoolean, excludedNames);
+       }
+
+       public static String getSetterName(IJavaProject project, String fieldName,
+                       int flags, boolean isBoolean, String[] excludedNames) {
+               return NamingConventions.suggestSetterName(project, fieldName, flags,
+                               isBoolean, excludedNames);
+       }
+
+       public static String getSetterName(IField field, String[] excludedNames)
+                       throws JavaModelException {
+               if (excludedNames == null) {
+                       excludedNames = EMPTY;
+               }
+               return NamingConventions.suggestSetterName(field.getJavaProject(),
+                               field.getElementName(), field.getFlags(), JavaModelUtil
+                                               .isBoolean(field), excludedNames);
+       }
+
+       public static IMethod getGetter(IField field) throws JavaModelException {
+               IMethod primaryCandidate = JavaModelUtil.findMethod(getGetterName(
+                               field, EMPTY, true), new String[0], false, field
+                               .getDeclaringType());
+               if (!JavaModelUtil.isBoolean(field)
+                               || (primaryCandidate != null && primaryCandidate.exists()))
+                       return primaryCandidate;
+               // bug 30906 describes why we need to look for other alternatives here
+               String secondCandidateName = getGetterName(field, EMPTY, false);
+               return JavaModelUtil.findMethod(secondCandidateName, new String[0],
+                               false, field.getDeclaringType());
+       }
+
+       public static IMethod getSetter(IField field) throws JavaModelException {
+               String[] args = new String[] { field.getTypeSignature() };
+               return JavaModelUtil.findMethod(getSetterName(field, EMPTY), args,
+                               false, field.getDeclaringType());
+       }
+
+       /**
+        * Create a stub for a getter of the given field using getter/setter
+        * templates. The resulting code has to be formatted and indented.
+        * 
+        * @param field
+        *            The field to create a getter for
+        * @param setterName
+        *            The chosen name for the setter
+        * @param addComments
+        *            If <code>true</code>, comments will be added.
+        * @param flags
+        *            The flags signaling visibility, if static, synchronized or
+        *            final
+        * @return Returns the generated stub.
+        * @throws CoreException
+        */
+       public static String getSetterStub(IField field, String setterName,
+                       boolean addComments, int flags) throws CoreException {
+
+               String fieldName = field.getElementName();
+               IType parentType = field.getDeclaringType();
+
+               String returnSig = field.getTypeSignature();
+               String typeName = Signature.toString(returnSig);
+
+               IJavaProject project = field.getJavaProject();
+
+               String accessorName = NamingConventions
+                               .removePrefixAndSuffixForFieldName(project, fieldName, field
+                                               .getFlags());
+               String argname = StubUtility.suggestArgumentName(project, accessorName,
+                               EMPTY);
+
+               boolean isStatic = Flags.isStatic(flags);
+               // boolean isSync= Flags.isSynchronized(flags);
+               boolean isFinal = Flags.isFinal(flags);
+
+               // create the setter stub
+               StringBuffer buf = new StringBuffer();
+               if (addComments) {
+                       String comment = CodeGeneration.getSetterComment(field
+                                       .getCompilationUnit(),
+                                       parentType.getTypeQualifiedName('.'), setterName, field
+                                                       .getElementName(), typeName, argname, accessorName,
+                                       String.valueOf('\n'));
+                       if (comment != null) {
+                               buf.append(comment);
+                               buf.append('\n');
+                       }
+               }
+               buf.append(JdtFlags.getVisibilityString(flags));
+               buf.append(' ');
+               if (isStatic)
+                       buf.append("static "); //$NON-NLS-1$
+                       // if (isSync)
+                       // buf.append("synchronized "); //$NON-NLS-1$
+               if (isFinal)
+                       buf.append("final "); //$NON-NLS-1$                             
+
+               buf.append("void "); //$NON-NLS-1$
+               buf.append(setterName);
+               buf.append('(');
+               buf.append(typeName);
+               buf.append(' ');
+               buf.append(argname);
+               buf.append(") {\n"); //$NON-NLS-1$
+
+               boolean useThis = PreferenceConstants.getPreferenceStore().getBoolean(
+                               PreferenceConstants.CODEGEN_KEYWORD_THIS);
+               if (argname.equals(fieldName) || (useThis && !isStatic)) {
+                       if (isStatic)
+                               fieldName = parentType.getElementName() + '.' + fieldName;
+                       else
+                               fieldName = "this." + fieldName; //$NON-NLS-1$
+               }
+               String body = CodeGeneration.getSetterMethodBodyContent(field
+                               .getCompilationUnit(), parentType.getTypeQualifiedName('.'),
+                               setterName, fieldName, argname, String.valueOf('\n'));
+               if (body != null) {
+                       buf.append(body);
+               }
+               buf.append("}\n"); //$NON-NLS-1$                
+               return buf.toString();
+       }
+
+       /**
+        * Create a stub for a getter of the given field using getter/setter
+        * templates. The resulting code has to be formatted and indented.
+        * 
+        * @param field
+        *            The field to create a getter for
+        * @param getterName
+        *            The chosen name for the getter
+        * @param addComments
+        *            If <code>true</code>, comments will be added.
+        * @param flags
+        *            The flags signaling visibility, if static, synchronized or
+        *            final
+        * @return Returns the generated stub.
+        * @throws CoreException
+        */
+       public static String getGetterStub(IField field, String getterName,
+                       boolean addComments, int flags) throws CoreException {
+               String fieldName = field.getElementName();
+               IType parentType = field.getDeclaringType();
+
+               boolean isStatic = Flags.isStatic(flags);
+               // boolean isSync= Flags.isSynchronized(flags);
+               boolean isFinal = Flags.isFinal(flags);
+
+               String typeName = Signature.toString(field.getTypeSignature());
+               String accessorName = NamingConventions
+                               .removePrefixAndSuffixForFieldName(field.getJavaProject(),
+                                               fieldName, field.getFlags());
+
+               // create the getter stub
+               StringBuffer buf = new StringBuffer();
+               if (addComments) {
+                       String comment = CodeGeneration.getGetterComment(field
+                                       .getCompilationUnit(),
+                                       parentType.getTypeQualifiedName('.'), getterName, field
+                                                       .getElementName(), typeName, accessorName, String
+                                                       .valueOf('\n'));
+                       if (comment != null) {
+                               buf.append(comment);
+                               buf.append('\n');
+                       }
+               }
+
+               buf.append(JdtFlags.getVisibilityString(flags));
+               buf.append(' ');
+               if (isStatic)
+                       buf.append("static "); //$NON-NLS-1$
+                       // if (isSync)
+                       // buf.append("synchronized "); //$NON-NLS-1$
+               if (isFinal)
+                       buf.append("final "); //$NON-NLS-1$
+
+               buf.append(typeName);
+               buf.append(' ');
+               buf.append(getterName);
+               buf.append("() {\n"); //$NON-NLS-1$
+
+               boolean useThis = PreferenceConstants.getPreferenceStore().getBoolean(
+                               PreferenceConstants.CODEGEN_KEYWORD_THIS);
+               if (useThis && !isStatic) {
+                       fieldName = "this." + fieldName; //$NON-NLS-1$
+               }
+
+               String body = CodeGeneration.getGetterMethodBodyContent(field
+                               .getCompilationUnit(), parentType.getTypeQualifiedName('.'),
+                               getterName, fieldName, String.valueOf('\n'));
+               if (body != null) {
+                       buf.append(body);
+               }
+               buf.append("}\n"); //$NON-NLS-1$
+               return buf.toString();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/IRequestQuery.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/IRequestQuery.java
new file mode 100644 (file)
index 0000000..a7b9989
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.codemanipulation;
+
+import net.sourceforge.phpdt.core.IMember;
+
+/**
+ * Query object to let operations callback the actions. Example is a callback to
+ * ask if a existing method should be replaced.
+ */
+public interface IRequestQuery {
+
+       // return codes
+       public static final int CANCEL = 0;
+
+       public static final int NO = 1;
+
+       public static final int YES = 2;
+
+       public static final int YES_ALL = 3;
+
+       /**
+        * Do the callback. Returns YES, NO, YES_ALL or CANCEL
+        */
+       int doQuery(IMember member);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/StubUtility.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/codemanipulation/StubUtility.java
new file mode 100644 (file)
index 0000000..cd11e2a
--- /dev/null
@@ -0,0 +1,1446 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.codemanipulation;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IBuffer;
+import net.sourceforge.phpdt.core.ICodeFormatter;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.Signature;
+import net.sourceforge.phpdt.core.ToolFactory;
+import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+import net.sourceforge.phpdt.internal.corext.util.Strings;
+import net.sourceforge.phpdt.internal.corext.util.PHPUIStatus;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.swt.SWT;
+
+public class StubUtility {
+
+       public static class GenStubSettings extends CodeGenerationSettings {
+
+               public boolean callSuper;
+
+               public boolean methodOverwrites;
+
+               public boolean noBody;
+
+               public int methodModifiers;
+
+               public GenStubSettings(CodeGenerationSettings settings) {
+                       settings.setSettings(this);
+                       methodModifiers = -1;
+               }
+
+       }
+
+       private static final String[] EMPTY = new String[0];
+
+       /**
+        * Generates a method stub including the method comment. Given a template
+        * method, a stub with the same signature will be constructed so it can be
+        * added to a type. The method body will be empty or contain a return or
+        * super call.
+        * 
+        * @param destTypeName
+        *            The name of the type to which the method will be added to
+        * @param method
+        *            A method template (method belongs to different type than the
+        *            parent)
+        * @param definingType
+        *            The type that defines the method.
+        * @param settings
+        *            Options as defined above (<code>GenStubSettings</code>)
+        * @param imports
+        *            Imports required by the stub are added to the imports
+        *            structure. If imports structure is <code>null</code> all
+        *            type names are qualified.
+        * @throws JavaModelException
+        */
+       public static String genStub(ICompilationUnit cu, String destTypeName,
+                       IMethod method, IType definingType, GenStubSettings settings)
+                       throws CoreException {
+               // IImportsStructure imports) throws CoreException {
+               String methName = method.getElementName();
+               String[] paramNames = suggestArgumentNames(method.getJavaProject(),
+                               method.getParameterNames());
+               String returnType = method.isConstructor() ? null : method
+                               .getReturnType();
+               String lineDelimiter = String.valueOf('\n'); // reformatting required
+
+               StringBuffer buf = new StringBuffer();
+               // add method comment
+               if (settings.createComments && cu != null) {
+                       IMethod overridden = null;
+                       if (settings.methodOverwrites && returnType != null) {
+                               overridden = JavaModelUtil.findMethod(methName, method
+                                               .getParameterTypes(), false, definingType.getMethods());
+                       }
+                       String comment = getMethodComment(cu, destTypeName, methName,
+                                       paramNames, method.getExceptionTypes(), returnType,
+                                       overridden, lineDelimiter);
+                       if (comment != null) {
+                               buf.append(comment);
+                       } else {
+                               buf.append("/**").append(lineDelimiter); //$NON-NLS-1$
+                               buf.append(" *").append(lineDelimiter); //$NON-NLS-1$
+                               buf.append(" */").append(lineDelimiter); //$NON-NLS-1$                                                  
+                       }
+                       buf.append(lineDelimiter);
+               }
+               // add method declaration
+               String bodyContent = null;
+               if (!settings.noBody) {
+                       String bodyStatement = getDefaultMethodBodyStatement(methName,
+                                       paramNames, returnType, settings.callSuper);
+                       bodyContent = getMethodBodyContent(returnType == null, method
+                                       .getJavaProject(), destTypeName, methName, bodyStatement,
+                                       lineDelimiter);
+                       if (bodyContent == null) {
+                               bodyContent = ""; //$NON-NLS-1$
+                       }
+               }
+               int flags = settings.methodModifiers;
+               if (flags == -1) {
+                       flags = method.getFlags();
+               }
+
+               genMethodDeclaration(destTypeName, method, flags, bodyContent, buf); // imports,
+                                                                                                                                                               // buf);
+               return buf.toString();
+       }
+
+       /**
+        * Generates a method stub not including the method comment. Given a
+        * template method and the body content, a stub with the same signature will
+        * be constructed so it can be added to a type.
+        * 
+        * @param destTypeName
+        *            The name of the type to which the method will be added to
+        * @param method
+        *            A method template (method belongs to different type than the
+        *            parent)
+        * @param bodyContent
+        *            Content of the body
+        * @param imports
+        *            Imports required by the stub are added to the imports
+        *            structure. If imports structure is <code>null</code> all
+        *            type names are qualified.
+        * @param buf
+        *            The buffer to append the gerenated code.
+        * @throws JavaModelException
+        */
+       public static void genMethodDeclaration(String destTypeName,
+                       IMethod method, String bodyContent, StringBuffer buf)
+                       throws CoreException { // IImportsStructure imports, StringBuffer
+                                                                       // buf) throws CoreException {
+               genMethodDeclaration(destTypeName, method, method.getFlags(),
+                               bodyContent, buf);
+       }
+
+       /**
+        * Generates a method stub not including the method comment. Given a
+        * template method and the body content, a stub with the same signature will
+        * be constructed so it can be added to a type.
+        * 
+        * @param destTypeName
+        *            The name of the type to which the method will be added to
+        * @param method
+        *            A method template (method belongs to different type than the
+        *            parent)
+        * @param bodyContent
+        *            Content of the body
+        * @param imports
+        *            Imports required by the stub are added to the imports
+        *            structure. If imports structure is <code>null</code> all
+        *            type names are qualified.
+        * @param buf
+        *            The buffer to append the gerenated code.
+        * @throws JavaModelException
+        */
+       public static void genMethodDeclaration(String destTypeName,
+                       IMethod method, int flags, String bodyContent, StringBuffer buf)
+                       throws CoreException {
+               // IImportsStructure imports, StringBuffer buf) throws CoreException {
+               IType parentType = method.getDeclaringType();
+               String methodName = method.getElementName();
+               String[] paramTypes = method.getParameterTypes();
+               String[] paramNames = suggestArgumentNames(parentType.getJavaProject(),
+                               method.getParameterNames());
+
+               String[] excTypes = method.getExceptionTypes();
+
+               boolean isConstructor = method.isConstructor();
+               String retTypeSig = isConstructor ? null : method.getReturnType();
+
+               int lastParam = paramTypes.length - 1;
+
+               if (Flags.isPublic(flags)
+                               || (parentType.isInterface() && bodyContent != null)) {
+                       buf.append("public "); //$NON-NLS-1$
+               } else if (Flags.isProtected(flags)) {
+                       buf.append("protected "); //$NON-NLS-1$
+               } else if (Flags.isPrivate(flags)) {
+                       buf.append("private "); //$NON-NLS-1$
+               }
+               // if (Flags.isSynchronized(flags)) {
+               // buf.append("synchronized "); //$NON-NLS-1$
+               // }
+               // if (Flags.isVolatile(flags)) {
+               // buf.append("volatile "); //$NON-NLS-1$
+               // }
+               // if (Flags.isStrictfp(flags)) {
+               // buf.append("strictfp "); //$NON-NLS-1$
+               // }
+               if (Flags.isStatic(flags)) {
+                       buf.append("static "); //$NON-NLS-1$
+               }
+
+               if (isConstructor) {
+                       buf.append(destTypeName);
+               } else {
+                       String retTypeFrm;
+                       if (!isPrimitiveType(retTypeSig)) {
+                               retTypeFrm = resolveAndAdd(retTypeSig, parentType);
+                       } else {
+                               retTypeFrm = Signature.toString(retTypeSig);
+                       }
+                       buf.append(retTypeFrm);
+                       buf.append(' ');
+                       buf.append(methodName);
+               }
+               buf.append('(');
+               for (int i = 0; i <= lastParam; i++) {
+                       String paramTypeSig = paramTypes[i];
+                       String paramTypeFrm;
+
+                       if (!isPrimitiveType(paramTypeSig)) {
+                               paramTypeFrm = resolveAndAdd(paramTypeSig, parentType);
+                       } else {
+                               paramTypeFrm = Signature.toString(paramTypeSig);
+                       }
+                       buf.append(paramTypeFrm);
+                       buf.append(' ');
+                       buf.append(paramNames[i]);
+                       if (i < lastParam) {
+                               buf.append(", "); //$NON-NLS-1$
+                       }
+               }
+               buf.append(')');
+
+               int lastExc = excTypes.length - 1;
+               if (lastExc >= 0) {
+                       buf.append(" throws "); //$NON-NLS-1$
+                       for (int i = 0; i <= lastExc; i++) {
+                               String excTypeSig = excTypes[i];
+                               String excTypeFrm = resolveAndAdd(excTypeSig, parentType);
+                               buf.append(excTypeFrm);
+                               if (i < lastExc) {
+                                       buf.append(", "); //$NON-NLS-1$
+                               }
+                       }
+               }
+               if (bodyContent == null) {
+                       buf.append(";\n\n"); //$NON-NLS-1$
+               } else {
+                       buf.append(" {\n\t"); //$NON-NLS-1$
+                       if ((bodyContent != null) && (bodyContent.length() > 0)) {
+                               buf.append(bodyContent);
+                               buf.append('\n');
+                       }
+                       buf.append("}\n"); //$NON-NLS-1$
+               }
+       }
+
+       public static String getDefaultMethodBodyStatement(String methodName,
+                       String[] paramNames, String retTypeSig, boolean callSuper) {
+               StringBuffer buf = new StringBuffer();
+               if (callSuper) {
+                       if (retTypeSig != null) {
+                               if (!Signature.SIG_VOID.equals(retTypeSig)) {
+                                       buf.append("return "); //$NON-NLS-1$
+                               }
+                               buf.append("super."); //$NON-NLS-1$
+                               buf.append(methodName);
+                       } else {
+                               buf.append("super"); //$NON-NLS-1$
+                       }
+                       buf.append('(');
+                       for (int i = 0; i < paramNames.length; i++) {
+                               if (i > 0) {
+                                       buf.append(", "); //$NON-NLS-1$
+                               }
+                               buf.append(paramNames[i]);
+                       }
+                       buf.append(");"); //$NON-NLS-1$
+               } else {
+                       if (retTypeSig != null && !retTypeSig.equals(Signature.SIG_VOID)) {
+                               if (!isPrimitiveType(retTypeSig)
+                                               || Signature.getArrayCount(retTypeSig) > 0) {
+                                       buf.append("return null;"); //$NON-NLS-1$
+                               } else if (retTypeSig.equals(Signature.SIG_BOOLEAN)) {
+                                       buf.append("return false;"); //$NON-NLS-1$
+                               } else {
+                                       buf.append("return 0;"); //$NON-NLS-1$
+                               }
+                       }
+               }
+               return buf.toString();
+       }
+
+       public static String getMethodBodyContent(boolean isConstructor,
+                       IJavaProject project, String destTypeName, String methodName,
+                       String bodyStatement, String lineDelimiter) throws CoreException {
+               String templateName = isConstructor ? CodeTemplateContextType.CONSTRUCTORSTUB
+                               : CodeTemplateContextType.METHODSTUB;
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(templateName);
+               if (template == null) {
+                       return bodyStatement;
+               }
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), project, lineDelimiter);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
+                               methodName);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE,
+                               destTypeName);
+               context.setVariable(CodeTemplateContextType.BODY_STATEMENT,
+                               bodyStatement);
+               String str = evaluateTemplate(context, template);
+               if (str == null && !Strings.containsOnlyWhitespaces(bodyStatement)) {
+                       return bodyStatement;
+               }
+               return str;
+       }
+
+       public static String getGetterMethodBodyContent(IJavaProject project,
+                       String destTypeName, String methodName, String fieldName,
+                       String lineDelimiter) throws CoreException {
+               String templateName = CodeTemplateContextType.GETTERSTUB;
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(templateName);
+               if (template == null) {
+                       return null;
+               }
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), project, lineDelimiter);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
+                               methodName);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE,
+                               destTypeName);
+               context.setVariable(CodeTemplateContextType.FIELD, fieldName);
+
+               return evaluateTemplate(context, template);
+       }
+
+       public static String getSetterMethodBodyContent(IJavaProject project,
+                       String destTypeName, String methodName, String fieldName,
+                       String paramName, String lineDelimiter) throws CoreException {
+               String templateName = CodeTemplateContextType.SETTERSTUB;
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(templateName);
+               if (template == null) {
+                       return null;
+               }
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), project, lineDelimiter);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
+                               methodName);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE,
+                               destTypeName);
+               context.setVariable(CodeTemplateContextType.FIELD, fieldName);
+               context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldName);
+               context.setVariable(CodeTemplateContextType.PARAM, paramName);
+
+               return evaluateTemplate(context, template);
+       }
+
+       public static String getCatchBodyContent(ICompilationUnit cu,
+                       String exceptionType, String variableName, String lineDelimiter)
+                       throws CoreException {
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(
+                                               CodeTemplateContextType.CATCHBLOCK);
+               if (template == null) {
+                       return null;
+               }
+
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
+               context.setVariable(CodeTemplateContextType.EXCEPTION_TYPE,
+                               exceptionType);
+               context
+                               .setVariable(CodeTemplateContextType.EXCEPTION_VAR,
+                                               variableName); //$NON-NLS-1$
+               return evaluateTemplate(context, template);
+       }
+
+       /**
+        * @see net.sourceforge.phpdt.ui.CodeGeneration#getTypeComment(ICompilationUnit,
+        *      String, String)
+        */
+       public static String getCompilationUnitContent(ICompilationUnit cu,
+                       String typeComment, String typeContent, String lineDelimiter)
+                       throws CoreException {
+               IPackageFragment pack = (IPackageFragment) cu.getParent();
+               String packDecl = pack.isDefaultPackage() ? "" : "package " + pack.getElementName() + ';'; //$NON-NLS-1$ //$NON-NLS-2$
+
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(
+                                               CodeTemplateContextType.NEWTYPE);
+               if (template == null) {
+                       return null;
+               }
+
+               IJavaProject project = cu.getJavaProject();
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), project, lineDelimiter);
+               context.setCompilationUnitVariables(cu);
+               context.setVariable(CodeTemplateContextType.PACKAGE_DECLARATION,
+                               packDecl);
+               context.setVariable(CodeTemplateContextType.TYPE_COMMENT,
+                               typeComment != null ? typeComment : ""); //$NON-NLS-1$
+               context.setVariable(CodeTemplateContextType.TYPE_DECLARATION,
+                               typeContent);
+               context.setVariable(CodeTemplateContextType.TYPENAME, Signature
+                               .getQualifier(cu.getElementName()));
+               return evaluateTemplate(context, template);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.CodeGeneration#getTypeComment(ICompilationUnit,
+        *      String, String)
+        */
+       public static String getTypeComment(ICompilationUnit cu,
+                       String typeQualifiedName, String lineDelim) throws CoreException {
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(
+                                               CodeTemplateContextType.TYPECOMMENT);
+               if (template == null) {
+                       return null;
+               }
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), cu.getJavaProject(), lineDelim);
+               context.setCompilationUnitVariables(cu);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, Signature
+                               .getQualifier(typeQualifiedName));
+               context.setVariable(CodeTemplateContextType.TYPENAME, Signature
+                               .getSimpleName(typeQualifiedName));
+               return evaluateTemplate(context, template);
+       }
+
+       // private static String[] getParameterTypesQualifiedNames(IMethodBinding
+       // binding) {
+       // ITypeBinding[] typeBindings= binding.getParameterTypes();
+       // String[] result= new String[typeBindings.length];
+       // for (int i= 0; i < result.length; i++) {
+       // result[i]= typeBindings[i].getQualifiedName();
+       // }
+       // return result;
+       // }
+
+       private static String getSeeTag(String declaringClassQualifiedName,
+                       String methodName, String[] parameterTypesQualifiedNames) {
+               StringBuffer buf = new StringBuffer();
+               buf.append("@see "); //$NON-NLS-1$
+               buf.append(declaringClassQualifiedName);
+               buf.append('#');
+               buf.append(methodName);
+               buf.append('(');
+               for (int i = 0; i < parameterTypesQualifiedNames.length; i++) {
+                       if (i > 0) {
+                               buf.append(", "); //$NON-NLS-1$
+                       }
+                       buf.append(parameterTypesQualifiedNames[i]);
+               }
+               buf.append(')');
+               return buf.toString();
+       }
+
+       private static String getSeeTag(IMethod overridden)
+                       throws JavaModelException {
+               IType declaringType = overridden.getDeclaringType();
+               StringBuffer buf = new StringBuffer();
+               buf.append("@see "); //$NON-NLS-1$
+               buf.append(declaringType.getFullyQualifiedName('.'));
+               buf.append('#');
+               buf.append(overridden.getElementName());
+               buf.append('(');
+               String[] paramTypes = overridden.getParameterTypes();
+               for (int i = 0; i < paramTypes.length; i++) {
+                       if (i > 0) {
+                               buf.append(", "); //$NON-NLS-1$
+                       }
+                       String curr = paramTypes[i];
+                       buf.append(JavaModelUtil.getResolvedTypeName(curr, declaringType));
+                       int arrayCount = Signature.getArrayCount(curr);
+                       while (arrayCount > 0) {
+                               buf.append("[]"); //$NON-NLS-1$
+                               arrayCount--;
+                       }
+               }
+               buf.append(')');
+               return buf.toString();
+       }
+
+       /**
+        * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(IMethod,IMethod,String)
+        */
+       public static String getMethodComment(IMethod method, IMethod overridden,
+                       String lineDelimiter) throws CoreException {
+               String retType = method.isConstructor() ? null : method.getReturnType();
+               String[] paramNames = method.getParameterNames();
+
+               return getMethodComment(method.getCompilationUnit(), method
+                               .getDeclaringType().getElementName(), method.getElementName(),
+                               paramNames, method.getExceptionTypes(), retType, overridden,
+                               lineDelimiter);
+       }
+
+       /**
+        * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(ICompilationUnit,
+        *      String, String, String[], String[], String, IMethod, String)
+        */
+       public static String getMethodComment(ICompilationUnit cu, String typeName,
+                       String methodName, String[] paramNames, String[] excTypeSig,
+                       String retTypeSig, IMethod overridden, String lineDelimiter)
+                       throws CoreException {
+               String templateName = CodeTemplateContextType.METHODCOMMENT;
+               if (retTypeSig == null) {
+                       templateName = CodeTemplateContextType.CONSTRUCTORCOMMENT;
+               } else if (overridden != null) {
+                       templateName = CodeTemplateContextType.OVERRIDECOMMENT;
+               }
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(templateName);
+               if (template == null) {
+                       return null;
+               }
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
+               context.setCompilationUnitVariables(cu);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
+                               methodName);
+
+               if (retTypeSig != null) {
+                       context.setVariable(CodeTemplateContextType.RETURN_TYPE, Signature
+                                       .toString(retTypeSig));
+               }
+               if (overridden != null) {
+                       context.setVariable(CodeTemplateContextType.SEE_TAG,
+                                       getSeeTag(overridden));
+               }
+               TemplateBuffer buffer;
+               try {
+                       buffer = context.evaluate(template);
+               } catch (BadLocationException e) {
+                       throw new CoreException(Status.CANCEL_STATUS);
+               } catch (TemplateException e) {
+                       throw new CoreException(Status.CANCEL_STATUS);
+               }
+               if (buffer == null) {
+                       return null;
+               }
+
+               String str = buffer.getString();
+               if (Strings.containsOnlyWhitespaces(str)) {
+                       return null;
+               }
+               TemplateVariable position = findTagVariable(buffer); // look if
+                                                                                                                               // Javadoc tags
+                                                                                                                               // have to be
+                                                                                                                               // added
+               if (position == null) {
+                       return str;
+               }
+
+               IDocument textBuffer = new Document(str);
+               String[] exceptionNames = new String[excTypeSig.length];
+               for (int i = 0; i < excTypeSig.length; i++) {
+                       exceptionNames[i] = Signature.toString(excTypeSig[i]);
+               }
+               String returnType = retTypeSig != null ? Signature.toString(retTypeSig)
+                               : null;
+               int[] tagOffsets = position.getOffsets();
+               for (int i = tagOffsets.length - 1; i >= 0; i--) { // from last to
+                                                                                                                       // first
+                       try {
+                               insertTag(textBuffer, tagOffsets[i], position.getLength(),
+                                               paramNames, exceptionNames, returnType, false,
+                                               lineDelimiter);
+                       } catch (BadLocationException e) {
+                               throw new CoreException(PHPUIStatus.createError(IStatus.ERROR,
+                                               e));
+                       }
+               }
+               return textBuffer.get();
+       }
+
+       public static String getFieldComment(ICompilationUnit cu, String typeName,
+                       String fieldName, String lineDelimiter) throws CoreException {
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(
+                                               CodeTemplateContextType.FIELDCOMMENT);
+               if (template == null) {
+                       return null;
+               }
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
+               context.setCompilationUnitVariables(cu);
+               context.setVariable(CodeTemplateContextType.FIELD_TYPE, typeName);
+               context.setVariable(CodeTemplateContextType.FIELD, fieldName);
+
+               return evaluateTemplate(context, template);
+       }
+
+       /**
+        * @see net.sourceforge.phpdt.ui.CodeGeneration#getSetterComment(ICompilationUnit,
+        *      String, String, String, String, String, String, String)
+        */
+       public static String getSetterComment(ICompilationUnit cu, String typeName,
+                       String methodName, String fieldName, String fieldType,
+                       String paramName, String bareFieldName, String lineDelimiter)
+                       throws CoreException {
+               String templateName = CodeTemplateContextType.SETTERCOMMENT;
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(templateName);
+               if (template == null) {
+                       return null;
+               }
+
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
+               context.setCompilationUnitVariables(cu);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
+                               methodName);
+               context.setVariable(CodeTemplateContextType.FIELD, fieldName);
+               context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
+               context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME,
+                               bareFieldName);
+               context.setVariable(CodeTemplateContextType.PARAM, paramName);
+
+               return evaluateTemplate(context, template);
+       }
+
+       /**
+        * @see net.sourceforge.phpdt.ui.CodeGeneration#getGetterComment(ICompilationUnit,
+        *      String, String, String, String, String, String)
+        */
+       public static String getGetterComment(ICompilationUnit cu, String typeName,
+                       String methodName, String fieldName, String fieldType,
+                       String bareFieldName, String lineDelimiter) throws CoreException {
+               String templateName = CodeTemplateContextType.GETTERCOMMENT;
+               Template template = WebUI.getDefault()
+                               .getCodeTemplateStore().findTemplate(templateName);
+               if (template == null) {
+                       return null;
+               }
+               CodeTemplateContext context = new CodeTemplateContext(template
+                               .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
+               context.setCompilationUnitVariables(cu);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
+               context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
+                               methodName);
+               context.setVariable(CodeTemplateContextType.FIELD, fieldName);
+               context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
+               context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME,
+                               bareFieldName);
+
+               return evaluateTemplate(context, template);
+       }
+
+       public static String evaluateTemplate(CodeTemplateContext context,
+                       Template template) throws CoreException {
+               TemplateBuffer buffer;
+               try {
+                       buffer = context.evaluate(template);
+               } catch (BadLocationException e) {
+                       throw new CoreException(Status.CANCEL_STATUS);
+               } catch (TemplateException e) {
+                       throw new CoreException(Status.CANCEL_STATUS);
+               }
+               if (buffer == null)
+                       return null;
+               String str = buffer.getString();
+               if (Strings.containsOnlyWhitespaces(str)) {
+                       return null;
+               }
+               return str;
+       }
+
+       /**
+        * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(ICompilationUnit,
+        *      String, MethodDeclaration, IMethodBinding, String)
+        */
+       // public static String getMethodComment(ICompilationUnit cu, String
+       // typeName, IMethodBinding overridden, String lineDelimiter) throws
+       // CoreException {
+       // if (overridden != null) {
+       // String declaringClassQualifiedName=
+       // overridden.getDeclaringClass().getQualifiedName();
+       // String[] parameterTypesQualifiedNames=
+       // getParameterTypesQualifiedNames(overridden);
+       // return getMethodComment(cu, typeName, decl, true,
+       // overridden.isDeprecated(), declaringClassQualifiedName,
+       // parameterTypesQualifiedNames, lineDelimiter);
+       // } else {
+       // return getMethodComment(cu, typeName, decl, false, false, null, null,
+       // lineDelimiter);
+       // }
+       // }
+       /**
+        * Returns the comment for a method using the comment code templates.
+        * <code>null</code> is returned if the template is empty.
+        * 
+        * @param cu
+        *            The compilation unit to which the method belongs
+        * @param typeName
+        *            Name of the type to which the method belongs.
+        * @param decl
+        *            The AST MethodDeclaration node that will be added as new
+        *            method.
+        * @param isOverridden
+        *            <code>true</code> iff decl overrides another method
+        * @param isDeprecated
+        *            <code>true</code> iff the method that decl overrides is
+        *            deprecated. Note: it must not be <code>true</code> if
+        *            isOverridden is <code>false</code>.
+        * @param declaringClassQualifiedName
+        *            Fully qualified name of the type in which the overriddden
+        *            method (if any exists) in declared. If isOverridden is
+        *            <code>false</code>, this is ignored.
+        * @param parameterTypesQualifiedNames
+        *            Fully qualified names of parameter types of the type in which
+        *            the overriddden method (if any exists) in declared. If
+        *            isOverridden is <code>false</code>, this is ignored.
+        * @return String Returns the method comment or <code>null</code> if the
+        *         configured template is empty. (formatting required)
+        * @throws CoreException
+        */
+       // public static String getMethodComment(ICompilationUnit cu, String
+       // typeName, MethodDeclaration decl, boolean isOverridden, boolean
+       // isDeprecated, String declaringClassQualifiedName, String[]
+       // parameterTypesQualifiedNames, String lineDelimiter) throws CoreException
+       // {
+       // String templateName= CodeTemplateContextType.METHODCOMMENT;
+       // if (decl.isConstructor()) {
+       // templateName= CodeTemplateContextType.CONSTRUCTORCOMMENT;
+       // } else if (isOverridden) {
+       // templateName= CodeTemplateContextType.OVERRIDECOMMENT;
+       // }
+       // Template template=
+       // PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
+       // if (template == null) {
+       // return null;
+       // }
+       // CodeTemplateContext context= new
+       // CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(),
+       // lineDelimiter);
+       // context.setCompilationUnitVariables(cu);
+       // context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
+       // context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
+       // decl.getName().getIdentifier());
+       // if (!decl.isConstructor()) {
+       // context.setVariable(CodeTemplateContextType.RETURN_TYPE,
+       // ASTNodes.asString(decl.getReturnType()));
+       // }
+       // if (isOverridden) {
+       // String methodName= decl.getName().getIdentifier();
+       // context.setVariable(CodeTemplateContextType.SEE_TAG,
+       // getSeeTag(declaringClassQualifiedName, methodName,
+       // parameterTypesQualifiedNames));
+       // }
+       //                      
+       // TemplateBuffer buffer;
+       // try {
+       // buffer= context.evaluate(template);
+       // } catch (BadLocationException e) {
+       // throw new CoreException(Status.CANCEL_STATUS);
+       // } catch (TemplateException e) {
+       // throw new CoreException(Status.CANCEL_STATUS);
+       // }
+       // if (buffer == null)
+       // return null;
+       // String str= buffer.getString();
+       // if (Strings.containsOnlyWhitespaces(str)) {
+       // return null;
+       // }
+       // TemplateVariable position= findTagVariable(buffer); // look if Javadoc
+       // tags have to be added
+       // if (position == null) {
+       // return str;
+       // }
+       //                              
+       // IDocument textBuffer= new Document(str);
+       // List params= decl.parameters();
+       // String[] paramNames= new String[params.size()];
+       // for (int i= 0; i < params.size(); i++) {
+       // SingleVariableDeclaration elem= (SingleVariableDeclaration)
+       // params.get(i);
+       // paramNames[i]= elem.getName().getIdentifier();
+       // }
+       // List exceptions= decl.thrownExceptions();
+       // String[] exceptionNames= new String[exceptions.size()];
+       // for (int i= 0; i < exceptions.size(); i++) {
+       // exceptionNames[i]= ASTNodes.getSimpleNameIdentifier((Name)
+       // exceptions.get(i));
+       // }
+       // String returnType= !decl.isConstructor() ?
+       // ASTNodes.asString(decl.getReturnType()) : null;
+       // int[] tagOffsets= position.getOffsets();
+       // for (int i= tagOffsets.length - 1; i >= 0; i--) { // from last to first
+       // try {
+       // insertTag(textBuffer, tagOffsets[i], position.getLength(), paramNames,
+       // exceptionNames, returnType, isDeprecated, lineDelimiter);
+       // } catch (BadLocationException e) {
+       // throw new CoreException(PHPUIStatus.createError(IStatus.ERROR, e));
+       // }
+       // }
+       // return textBuffer.get();
+       // }
+       private static TemplateVariable findTagVariable(TemplateBuffer buffer) {
+               TemplateVariable[] positions = buffer.getVariables();
+               for (int i = 0; i < positions.length; i++) {
+                       TemplateVariable curr = positions[i];
+                       if (CodeTemplateContextType.TAGS.equals(curr.getType())) {
+                               return curr;
+                       }
+               }
+               return null;
+       }
+
+       private static void insertTag(IDocument textBuffer, int offset, int length,
+                       String[] paramNames, String[] exceptionNames, String returnType,
+                       boolean isDeprecated, String lineDelimiter)
+                       throws BadLocationException {
+               IRegion region = textBuffer.getLineInformationOfOffset(offset);
+               if (region == null) {
+                       return;
+               }
+               String lineStart = textBuffer.get(region.getOffset(), offset
+                               - region.getOffset());
+
+               StringBuffer buf = new StringBuffer();
+               for (int i = 0; i < paramNames.length; i++) {
+                       if (buf.length() > 0) {
+                               buf.append(lineDelimiter);
+                               buf.append(lineStart);
+                       }
+                       buf.append("@param ");buf.append(paramNames[i]); //$NON-NLS-1$
+               }
+               if (returnType != null && !returnType.equals("void")) { //$NON-NLS-1$
+                       if (buf.length() > 0) {
+                               buf.append(lineDelimiter);
+                               buf.append(lineStart);
+                       }
+                       buf.append("@return"); //$NON-NLS-1$
+               }
+               if (exceptionNames != null) {
+                       for (int i = 0; i < exceptionNames.length; i++) {
+                               if (buf.length() > 0) {
+                                       buf.append(lineDelimiter);
+                                       buf.append(lineStart);
+                               }
+                               buf.append("@throws ");buf.append(exceptionNames[i]); //$NON-NLS-1$
+                       }
+               }
+               if (isDeprecated) {
+                       if (buf.length() > 0) {
+                               buf.append(lineDelimiter);
+                               buf.append(lineStart);
+                       }
+                       buf.append("@deprecated"); //$NON-NLS-1$
+               }
+               textBuffer.replace(offset, length, buf.toString());
+       }
+
+       private static boolean isPrimitiveType(String typeName) {
+               char first = Signature.getElementType(typeName).charAt(0);
+               return (first != Signature.C_RESOLVED && first != Signature.C_UNRESOLVED);
+       }
+
+       private static String resolveAndAdd(String refTypeSig, IType declaringType)
+                       throws JavaModelException {// , IImportsStructure imports) throws
+                                                                               // JavaModelException {
+               String resolvedTypeName = JavaModelUtil.getResolvedTypeName(refTypeSig,
+                               declaringType);
+               if (resolvedTypeName != null) {
+                       StringBuffer buf = new StringBuffer();
+                       // if (imports != null) {
+                       // buf.append(imports.addImport(resolvedTypeName));
+                       // } else {
+                       buf.append(resolvedTypeName);
+                       // }
+                       int arrayCount = Signature.getArrayCount(refTypeSig);
+                       for (int i = 0; i < arrayCount; i++) {
+                               buf.append("[]"); //$NON-NLS-1$
+                       }
+                       return buf.toString();
+               }
+               return Signature.toString(refTypeSig);
+       }
+
+       /**
+        * Finds a method in a list of methods.
+        * 
+        * @return The found method or null, if nothing found
+        */
+       private static IMethod findMethod(IMethod method, List allMethods)
+                       throws JavaModelException {
+               String name = method.getElementName();
+               String[] paramTypes = method.getParameterTypes();
+               boolean isConstructor = method.isConstructor();
+
+               for (int i = allMethods.size() - 1; i >= 0; i--) {
+                       IMethod curr = (IMethod) allMethods.get(i);
+                       if (JavaModelUtil.isSameMethodSignature(name, paramTypes,
+                                       isConstructor, curr)) {
+                               return curr;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Creates needed constructors for a type.
+        * 
+        * @param type
+        *            The type to create constructors for
+        * @param supertype
+        *            The type's super type
+        * @param settings
+        *            Options for comment generation
+        * @param imports
+        *            Required imports are added to the import structure. Structure
+        *            can be <code>null</code>, types are qualified then.
+        * @return Returns the generated stubs or <code>null</code> if the
+        *         creation has been canceled
+        */
+       // public static String[] evalConstructors(IType type, IType supertype,
+       // IImportsStructure imports) throws CoreException {
+       // IMethod[] superMethods= supertype.getMethods();
+       // String typeName= type.getElementName();
+       // ICompilationUnit cu= type.getCompilationUnit();
+       // IMethod[] methods= type.getMethods();
+       // GenStubSettings genStubSettings= new GenStubSettings(settings);
+       // genStubSettings.callSuper= true;
+       //                      
+       // ArrayList newMethods= new ArrayList(superMethods.length);
+       // for (int i= 0; i < superMethods.length; i++) {
+       // IMethod curr= superMethods[i];
+       // if (curr.isConstructor() && (JavaModelUtil.isVisibleInHierarchy(curr,
+       // type.getPackageFragment()))) {
+       // if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true,
+       // methods) == null) {
+       // genStubSettings.methodModifiers= Flags.AccPublic |
+       // JdtFlags.clearAccessModifiers(curr.getFlags());
+       // String newStub= genStub(cu, typeName, curr, curr.getDeclaringType(),
+       // genStubSettings, imports);
+       // newMethods.add(newStub);
+       // }
+       // }
+       // }
+       // return (String[]) newMethods.toArray(new String[newMethods.size()]);
+       // }
+       /**
+        * Returns all unimplemented constructors of a type including root type
+        * default constructors if there are no other superclass constructors
+        * unimplemented.
+        * 
+        * @param type
+        *            The type to create constructors for
+        * @return Returns the generated stubs or <code>null</code> if the
+        *         creation has been canceled
+        */
+       // public static IMethod[] getOverridableConstructors(IType type) throws
+       // CoreException {
+       // List constructorMethods= new ArrayList();
+       // ITypeHierarchy hierarchy= type.newSupertypeHierarchy(null);
+       // IType supertype= hierarchy.getSuperclass(type);
+       // if (supertype == null)
+       // return (new IMethod[0]);
+       //
+       // IMethod[] superMethods= supertype.getMethods();
+       // boolean constuctorFound= false;
+       // String typeName= type.getElementName();
+       // IMethod[] methods= type.getMethods();
+       // for (int i= 0; i < superMethods.length; i++) {
+       // IMethod curr= superMethods[i];
+       // if (curr.isConstructor()) {
+       // constuctorFound= true;
+       // if (JavaModelUtil.isVisibleInHierarchy(curr, type.getPackageFragment()))
+       // if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true,
+       // methods) == null)
+       // constructorMethods.add(curr);
+       //                      
+       // }
+       // }
+       //                      
+       // // http://bugs.eclipse.org/bugs/show_bug.cgi?id=38487
+       // if (!constuctorFound) {
+       // IType objectType= type.getJavaProject().findType("java.lang.Object");
+       // //$NON-NLS-1$
+       // IMethod curr= objectType.getMethod("Object", EMPTY); //$NON-NLS-1$
+       // if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true,
+       // methods) == null) {
+       // constructorMethods.add(curr);
+       // }
+       // }
+       // return (IMethod[]) constructorMethods.toArray(new
+       // IMethod[constructorMethods.size()]);
+       // }
+       /**
+        * Returns all overridable methods of a type
+        * 
+        * @param type
+        *            The type to search the overridable methods for
+        * @param hierarchy
+        *            The type hierarchy of the type
+        * @param isSubType
+        *            If set, the result can include methods of the passed type, if
+        *            not only methods from super types are considered
+        * @return Returns the all methods that can be overridden
+        */
+       // public static IMethod[] getOverridableMethods(IType type, ITypeHierarchy
+       // hierarchy, boolean isSubType) throws JavaModelException {
+       // List allMethods= new ArrayList();
+       //
+       // IMethod[] typeMethods= type.getMethods();
+       // for (int i= 0; i < typeMethods.length; i++) {
+       // IMethod curr= typeMethods[i];
+       // if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) &&
+       // !Flags.isPrivate(curr.getFlags())) {
+       // allMethods.add(curr);
+       // }
+       // }
+       //
+       // IType[] superTypes= hierarchy.getAllSuperclasses(type);
+       // for (int i= 0; i < superTypes.length; i++) {
+       // IMethod[] methods= superTypes[i].getMethods();
+       // for (int k= 0; k < methods.length; k++) {
+       // IMethod curr= methods[k];
+       // if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) &&
+       // !Flags.isPrivate(curr.getFlags())) {
+       // if (findMethod(curr, allMethods) == null) {
+       // allMethods.add(curr);
+       // }
+       // }
+       // }
+       // }
+       //
+       // IType[] superInterfaces= hierarchy.getAllSuperInterfaces(type);
+       // for (int i= 0; i < superInterfaces.length; i++) {
+       // IMethod[] methods= superInterfaces[i].getMethods();
+       // for (int k= 0; k < methods.length; k++) {
+       // IMethod curr= methods[k];
+       //
+       // // binary interfaces can contain static initializers (variable
+       // intializations)
+       // // 1G4CKUS
+       // if (!Flags.isStatic(curr.getFlags())) {
+       // IMethod impl= findMethod(curr, allMethods);
+       // if (impl == null || !JavaModelUtil.isVisibleInHierarchy(impl,
+       // type.getPackageFragment()) || prefereInterfaceMethod(hierarchy, curr,
+       // impl)) {
+       // if (impl != null) {
+       // allMethods.remove(impl);
+       // }
+       // // implement an interface method when it does not exist in the hierarchy
+       // // or when it throws less exceptions that the implemented
+       // allMethods.add(curr);
+       // }
+       // }
+       // }
+       // }
+       // if (!isSubType) {
+       // allMethods.removeAll(Arrays.asList(typeMethods));
+       // }
+       // // remove finals
+       // for (int i= allMethods.size() - 1; i >= 0; i--) {
+       // IMethod curr= (IMethod) allMethods.get(i);
+       // if (Flags.isFinal(curr.getFlags())) {
+       // allMethods.remove(i);
+       // }
+       // }
+       // return (IMethod[]) allMethods.toArray(new IMethod[allMethods.size()]);
+       // }
+       // private static boolean prefereInterfaceMethod(ITypeHierarchy hierarchy,
+       // IMethod interfaceMethod, IMethod curr) throws JavaModelException {
+       // if (Flags.isFinal(curr.getFlags())) {
+       // return false;
+       // }
+       // IType interfaceType= interfaceMethod.getDeclaringType();
+       // IType[] interfaces=
+       // hierarchy.getAllSuperInterfaces(curr.getDeclaringType());
+       // for (int i= 0; i < interfaces.length; i++) {
+       // if (interfaces[i] == interfaceType) {
+       // return false;
+       // }
+       // }
+       // return curr.getExceptionTypes().length >
+       // interfaceMethod.getExceptionTypes().length;
+       // }
+       /**
+        * Generate method stubs for methods to overrride
+        * 
+        * @param type
+        *            The type to search the overridable methods for
+        * @param hierarchy
+        *            The type hierarchy of the type
+        * @param methodsToImplement
+        *            Methods to override or implement
+        * @param settings
+        *            Options for comment generation
+        * @param imports
+        *            Required imports are added to the import structure. Structure
+        *            can be <code>null</code>, types are qualified then.
+        * @return Returns the generated stubs
+        */
+       // public static String[] genOverrideStubs(IMethod[] methodsToImplement,
+       // IType type, ITypeHierarchy hierarchy, CodeGenerationSettings settings,
+       // IImportsStructure imports) throws CoreException {
+       // GenStubSettings genStubSettings= new GenStubSettings(settings);
+       // genStubSettings.methodOverwrites= true;
+       // ICompilationUnit cu= type.getCompilationUnit();
+       // String[] result= new String[methodsToImplement.length];
+       // for (int i= 0; i < methodsToImplement.length; i++) {
+       // IMethod curr= methodsToImplement[i];
+       // IMethod overrides=
+       // JavaModelUtil.findMethodImplementationInHierarchy(hierarchy, type,
+       // curr.getElementName(), curr.getParameterTypes(), curr.isConstructor());
+       // if (overrides != null) {
+       // genStubSettings.callSuper= true;
+       // curr= overrides;
+       // }
+       // genStubSettings.methodModifiers= curr.getFlags();
+       // IMethod desc= JavaModelUtil.findMethodDeclarationInHierarchy(hierarchy,
+       // type, curr.getElementName(), curr.getParameterTypes(),
+       // curr.isConstructor());
+       // if (desc == null) {
+       // desc= curr;
+       // }
+       // result[i]= genStub(cu, type.getElementName(), curr,
+       // desc.getDeclaringType(), genStubSettings, imports);
+       // }
+       // return result;
+       // }
+       /**
+        * Searches for unimplemented methods of a type.
+        * 
+        * @param isSubType
+        *            If set, the evaluation is for a subtype of the given type. If
+        *            not set, the evaluation is for the type itself.
+        * @param settings
+        *            Options for comment generation
+        * @param imports
+        *            Required imports are added to the import structure. Structure
+        *            can be <code>null</code>, types are qualified then.
+        * @return Returns the generated stubs or <code>null</code> if the
+        *         creation has been canceled
+        */
+       // public static String[] evalUnimplementedMethods(IType type,
+       // ITypeHierarchy hierarchy, boolean isSubType, CodeGenerationSettings
+       // settings,
+       // IImportsStructure imports) throws CoreException {
+       //                                              
+       // IMethod[] inheritedMethods= getOverridableMethods(type, hierarchy,
+       // isSubType);
+       //                      
+       // List toImplement= new ArrayList();
+       // for (int i= 0; i < inheritedMethods.length; i++) {
+       // IMethod curr= inheritedMethods[i];
+       // if (JdtFlags.isAbstract(curr)) {
+       // toImplement.add(curr);
+       // }
+       // }
+       // IMethod[] toImplementArray= (IMethod[]) toImplement.toArray(new
+       // IMethod[toImplement.size()]);
+       // return genOverrideStubs(toImplementArray, type, hierarchy, settings,
+       // imports);
+       // }
+       /**
+        * Examines a string and returns the first line delimiter found.
+        */
+       public static String getLineDelimiterUsed(IJavaElement elem)
+                       throws JavaModelException {
+               ICompilationUnit cu = (ICompilationUnit) elem
+                               .getAncestor(IJavaElement.COMPILATION_UNIT);
+               if (cu != null && cu.exists()) {
+                       IBuffer buf = cu.getBuffer();
+                       int length = buf.getLength();
+                       for (int i = 0; i < length; i++) {
+                               char ch = buf.getChar(i);
+                               if (ch == SWT.CR) {
+                                       if (i + 1 < length) {
+                                               if (buf.getChar(i + 1) == SWT.LF) {
+                                                       return "\r\n"; //$NON-NLS-1$
+                                               }
+                                       }
+                                       return "\r"; //$NON-NLS-1$
+                               } else if (ch == SWT.LF) {
+                                       return "\n"; //$NON-NLS-1$
+                               }
+                       }
+               }
+               return System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+       }
+
+       /**
+        * Embodies the policy which line delimiter to use when inserting into a
+        * document.
+        */
+       public static String getLineDelimiterFor(IDocument doc) {
+               // new for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in php editor
+               // inserts lines in wrong format
+               String lineDelim = null;
+               try {
+                       lineDelim = doc.getLineDelimiter(0);
+               } catch (BadLocationException e) {
+               }
+               if (lineDelim == null) {
+                       String systemDelimiter = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+                       String[] lineDelims = doc.getLegalLineDelimiters();
+                       for (int i = 0; i < lineDelims.length; i++) {
+                               if (lineDelims[i].equals(systemDelimiter)) {
+                                       lineDelim = systemDelimiter;
+                                       break;
+                               }
+                       }
+                       if (lineDelim == null) {
+                               lineDelim = lineDelims.length > 0 ? lineDelims[0]
+                                               : systemDelimiter;
+                       }
+               }
+               return lineDelim;
+       }
+
+       /**
+        * Evaluates the indention used by a Java element. (in tabulators)
+        */
+       // public static int getIndentUsed(IJavaElement elem) throws
+       // JavaModelException {
+       // if (elem instanceof ISourceReference) {
+       // ICompilationUnit cu= (ICompilationUnit)
+       // elem.getAncestor(IJavaElement.COMPILATION_UNIT);
+       // if (cu != null) {
+       // IBuffer buf= cu.getBuffer();
+       // int offset= ((ISourceReference)elem).getSourceRange().getOffset();
+       // int i= offset;
+       // // find beginning of line
+       // while (i > 0 && !Strings.isLineDelimiterChar(buf.getChar(i - 1)) ){
+       // i--;
+       // }
+       // return Strings.computeIndent(buf.getText(i, offset - i),
+       // CodeFormatterUtil.getTabWidth());
+       // }
+       // }
+       // return 0;
+       // }
+       public static String codeFormat(String sourceString,
+                       int initialIndentationLevel, String lineDelim) {
+               ICodeFormatter formatter = ToolFactory.createDefaultCodeFormatter(null);
+               return formatter.format(sourceString, initialIndentationLevel, null,
+                               lineDelim);
+       }
+
+       /**
+        * Returns the element after the give element.
+        */
+       // public static IJavaElement findNextSibling(IJavaElement member) throws
+       // JavaModelException {
+       // IJavaElement parent= member.getParent();
+       // if (parent instanceof IParent) {
+       // IJavaElement[] elements= ((IParent)parent).getChildren();
+       // for (int i= elements.length - 2; i >= 0 ; i--) {
+       // if (member.equals(elements[i])) {
+       // return elements[i+1];
+       // }
+       // }
+       // }
+       // return null;
+       // }
+       //      
+       public static String getTodoTaskTag(IJavaProject project) {
+               String markers = null;
+               if (project == null) {
+                       markers = JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS);
+               } else {
+                       markers = project.getOption(JavaCore.COMPILER_TASK_TAGS, true);
+               }
+
+               if (markers != null && markers.length() > 0) {
+                       int idx = markers.indexOf(',');
+                       if (idx == -1) {
+                               return markers;
+                       } else {
+                               return markers.substring(0, idx);
+                       }
+               }
+               return null;
+       }
+
+       /*
+        * Workarounds for bug 38111
+        */
+       // public static String[] getArgumentNameSuggestions(IJavaProject project,
+       // String baseName, int dimensions, String[] excluded) {
+       // String name= workaround38111(baseName);
+       // String[] res= NamingConventions.suggestArgumentNames(project, "", name,
+       // dimensions, excluded); //$NON-NLS-1$
+       // return sortByLength(res); // longest first
+       // }
+       //               
+       // public static String[] getFieldNameSuggestions(IJavaProject project,
+       // String baseName, int dimensions, int modifiers, String[] excluded) {
+       // String name= workaround38111(baseName);
+       // String[] res= NamingConventions.suggestFieldNames(project, "", name,
+       // dimensions, modifiers, excluded); //$NON-NLS-1$
+       // return sortByLength(res); // longest first
+       // }
+       //      
+       // public static String[] getLocalNameSuggestions(IJavaProject project,
+       // String baseName, int dimensions, String[] excluded) {
+       // String name= workaround38111(baseName);
+       // String[] res= NamingConventions.suggestLocalVariableNames(project, "",
+       // name, dimensions, excluded); //$NON-NLS-1$
+       // return sortByLength(res); // longest first
+       // }
+       private static String[] sortByLength(String[] proposals) {
+               Arrays.sort(proposals, new Comparator() {
+                       public int compare(Object o1, Object o2) {
+                               return ((String) o2).length() - ((String) o1).length();
+                       }
+               });
+               return proposals;
+       }
+
+       private static String workaround38111(String baseName) {
+               if (BASE_TYPES.contains(baseName))
+                       return baseName;
+               return Character.toUpperCase(baseName.charAt(0))
+                               + baseName.substring(1);
+       }
+
+       private static final List BASE_TYPES = Arrays
+                       .asList(new String[] {
+                                       "boolean", "byte", "char", "double", "float", "int", "long", "short" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
+
+       public static String suggestArgumentName(IJavaProject project,
+                       String baseName, String[] excluded) {
+               // String[] argnames= getArgumentNameSuggestions(project, baseName, 0,
+               // excluded);
+               // if (argnames.length > 0) {
+               // return argnames[0];
+               // }
+               return baseName;
+       }
+
+       public static String[] suggestArgumentNames(IJavaProject project,
+                       String[] paramNames) {
+               String prefixes = project.getOption(
+                               JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true);
+               String suffixes = project.getOption(
+                               JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true);
+               if (prefixes.length() + suffixes.length() == 0) {
+                       return paramNames;
+               }
+
+               String[] newNames = new String[paramNames.length];
+               // Ensure that the codegeneration preferences are respected
+               for (int i = 0; i < paramNames.length; i++) {
+                       String curr = paramNames[i];
+                       if (!hasPrefixOrSuffix(prefixes, suffixes, curr)) {
+                               newNames[i] = suggestArgumentName(project, paramNames[i], null);
+                       } else {
+                               newNames[i] = curr;
+                       }
+               }
+               return newNames;
+       }
+
+       public static boolean hasFieldName(IJavaProject project, String name) {
+               String prefixes = project.getOption(JavaCore.CODEASSIST_FIELD_PREFIXES,
+                               true);
+               String suffixes = project.getOption(JavaCore.CODEASSIST_FIELD_SUFFIXES,
+                               true);
+               String staticPrefixes = project.getOption(
+                               JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, true);
+               String staticSuffixes = project.getOption(
+                               JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, true);
+
+               return hasPrefixOrSuffix(prefixes, suffixes, name)
+                               || hasPrefixOrSuffix(staticPrefixes, staticSuffixes, name);
+       }
+
+       public static boolean hasParameterName(IJavaProject project, String name) {
+               String prefixes = project.getOption(
+                               JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true);
+               String suffixes = project.getOption(
+                               JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true);
+               return hasPrefixOrSuffix(prefixes, suffixes, name);
+       }
+
+       public static boolean hasLocalVariableName(IJavaProject project, String name) {
+               String prefixes = project.getOption(JavaCore.CODEASSIST_LOCAL_PREFIXES,
+                               true);
+               String suffixes = project.getOption(JavaCore.CODEASSIST_LOCAL_SUFFIXES,
+                               true);
+               return hasPrefixOrSuffix(prefixes, suffixes, name);
+       }
+
+       public static boolean hasConstantName(String name) {
+               return Character.isUpperCase(name.charAt(0));
+       }
+
+       private static boolean hasPrefixOrSuffix(String prefixes, String suffixes,
+                       String name) {
+               final String listSeparartor = ","; //$NON-NLS-1$
+
+               StringTokenizer tok = new StringTokenizer(prefixes, listSeparartor);
+               while (tok.hasMoreTokens()) {
+                       String curr = tok.nextToken();
+                       if (name.startsWith(curr)) {
+                               return true;
+                       }
+               }
+
+               tok = new StringTokenizer(suffixes, listSeparartor);
+               while (tok.hasMoreTokens()) {
+                       String curr = tok.nextToken();
+                       if (name.endsWith(curr)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplateContext.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplateContext.java
new file mode 100644 (file)
index 0000000..3cdda81
--- /dev/null
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateTranslator;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+
+public class CodeTemplateContext extends TemplateContext {
+
+       private String fLineDelimiter;
+
+       private IJavaProject fProject;
+
+       public CodeTemplateContext(String contextTypeName, IJavaProject project,
+                       String lineDelim) {
+               super(WebUI.getDefault().getCodeTemplateContextRegistry()
+                               .getContextType(contextTypeName));
+               fLineDelimiter = lineDelim;
+               fProject = project;
+       }
+
+       public IJavaProject getJavaProject() {
+               return fProject;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.TemplateContext#evaluate(net.sourceforge.phpdt.internal.corext.template.Template)
+        */
+       public TemplateBuffer evaluate(Template template)
+                       throws BadLocationException, TemplateException {
+               // test that all variables are defined
+               Iterator iterator = getContextType().resolvers();
+               while (iterator.hasNext()) {
+                       TemplateVariableResolver var = (TemplateVariableResolver) iterator
+                                       .next();
+                       if (var instanceof CodeTemplateContextType.CodeTemplateVariableResolver) {
+                               // Assert.isNotNull(getVariable(var.getType()), "Variable " +
+                               // var.getType() + "not defined"); //$NON-NLS-1$ //$NON-NLS-2$
+                       }
+               }
+
+               if (!canEvaluate(template))
+                       return null;
+
+               String pattern = changeLineDelimiter(template.getPattern(),
+                               fLineDelimiter);
+
+               TemplateTranslator translator = new TemplateTranslator();
+               TemplateBuffer buffer = translator.translate(pattern);
+               getContextType().resolve(buffer, this);
+
+               return buffer;
+       }
+
+       private static String changeLineDelimiter(String code, String lineDelim) {
+               try {
+                       ILineTracker tracker = new DefaultLineTracker();
+                       tracker.set(code);
+                       int nLines = tracker.getNumberOfLines();
+                       if (nLines == 1) {
+                               return code;
+                       }
+
+                       StringBuffer buf = new StringBuffer();
+                       for (int i = 0; i < nLines; i++) {
+                               if (i != 0) {
+                                       buf.append(lineDelim);
+                               }
+                               IRegion region = tracker.getLineInformation(i);
+                               String line = code.substring(region.getOffset(), region
+                                               .getOffset()
+                                               + region.getLength());
+                               buf.append(line);
+                       }
+                       return buf.toString();
+               } catch (BadLocationException e) {
+                       // can not happen
+                       return code;
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.corext.template.TemplateContext#canEvaluate(net.sourceforge.phpdt.internal.corext.template.Template)
+        */
+       public boolean canEvaluate(Template template) {
+               return true;
+       }
+
+       public void setCompilationUnitVariables(ICompilationUnit cu) {
+               setVariable(CodeTemplateContextType.FILENAME, cu.getElementName());
+               setVariable(CodeTemplateContextType.PACKAGENAME, cu.getParent()
+                               .getElementName());
+               setVariable(CodeTemplateContextType.PROJECTNAME, cu.getJavaProject()
+                               .getElementName());
+       }
+
+       public void setFileNameVariable(String filename, String projectname) {
+               setVariable(CodeTemplateContextType.FILENAME, filename);
+               setVariable(CodeTemplateContextType.PROJECTNAME, projectname);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplateContextType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplateContextType.java
new file mode 100644 (file)
index 0000000..94dd363
--- /dev/null
@@ -0,0 +1,528 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.ToolFactory;
+import net.sourceforge.phpdt.core.compiler.IScanner;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+
+import org.eclipse.jface.text.templates.ContextTypeRegistry;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+
+/**
+ */
+public class CodeTemplateContextType extends TemplateContextType {
+
+       /* context types */
+       public static final String CATCHBLOCK_CONTEXTTYPE = "php_catchblock_context"; //$NON-NLS-1$
+
+       public static final String METHODBODY_CONTEXTTYPE = "php_methodbody_context"; //$NON-NLS-1$
+
+       public static final String CONSTRUCTORBODY_CONTEXTTYPE = "php_constructorbody_context"; //$NON-NLS-1$
+
+       public static final String GETTERBODY_CONTEXTTYPE = "php_getterbody_context"; //$NON-NLS-1$
+
+       public static final String SETTERBODY_CONTEXTTYPE = "php_setterbody_context"; //$NON-NLS-1$
+
+       public static final String NEWTYPE_CONTEXTTYPE = "php_newtype_context"; //$NON-NLS-1$
+
+       public static final String NEWHTML_CONTEXTTYPE = "php_newhtml_context"; //$NON-NLS-1$
+
+       public static final String TYPECOMMENT_CONTEXTTYPE = "php_typecomment_context"; //$NON-NLS-1$
+
+       public static final String FIELDCOMMENT_CONTEXTTYPE = "php_fieldcomment_context"; //$NON-NLS-1$
+
+       public static final String METHODCOMMENT_CONTEXTTYPE = "php_methodcomment_context"; //$NON-NLS-1$
+
+       public static final String CONSTRUCTORCOMMENT_CONTEXTTYPE = "php_constructorcomment_context"; //$NON-NLS-1$
+
+       public static final String OVERRIDECOMMENT_CONTEXTTYPE = "php_overridecomment_context"; //$NON-NLS-1$
+
+       public static final String GETTERCOMMENT_CONTEXTTYPE = "php_gettercomment_context"; //$NON-NLS-1$
+
+       public static final String SETTERCOMMENT_CONTEXTTYPE = "php_settercomment_context"; //$NON-NLS-1$
+
+       /* templates */
+       public static final String COMMENT_SUFFIX = "comment"; //$NON-NLS-1$
+
+       public static final String CATCHBLOCK = "catchblock"; //$NON-NLS-1$
+
+       public static final String METHODSTUB = "methodbody"; //$NON-NLS-1$     
+
+       public static final String NEWTYPE = "newtype"; //$NON-NLS-1$   
+
+       public static final String NEWHTML = "newhtml"; //$NON-NLS-1$   
+
+       public static final String CONSTRUCTORSTUB = "constructorbody"; //$NON-NLS-1$
+
+       public static final String GETTERSTUB = "getterbody"; //$NON-NLS-1$
+
+       public static final String SETTERSTUB = "setterbody"; //$NON-NLS-1$
+
+       public static final String TYPECOMMENT = "type" + COMMENT_SUFFIX; //$NON-NLS-1$
+
+       public static final String FIELDCOMMENT = "field" + COMMENT_SUFFIX; //$NON-NLS-1$
+
+       public static final String METHODCOMMENT = "method" + COMMENT_SUFFIX; //$NON-NLS-1$
+
+       public static final String CONSTRUCTORCOMMENT = "constructor" + COMMENT_SUFFIX; //$NON-NLS-1$
+
+       public static final String OVERRIDECOMMENT = "override" + COMMENT_SUFFIX; //$NON-NLS-1$
+
+       public static final String GETTERCOMMENT = "getter" + COMMENT_SUFFIX; //$NON-NLS-1$
+
+       public static final String SETTERCOMMENT = "setter" + COMMENT_SUFFIX; //$NON-NLS-1$
+
+       /* resolver types */
+       public static final String EXCEPTION_TYPE = "exception_type"; //$NON-NLS-1$
+
+       public static final String EXCEPTION_VAR = "exception_var"; //$NON-NLS-1$
+
+       public static final String ENCLOSING_METHOD = "enclosing_method"; //$NON-NLS-1$
+
+       public static final String ENCLOSING_TYPE = "enclosing_type"; //$NON-NLS-1$
+
+       public static final String BODY_STATEMENT = "body_statement"; //$NON-NLS-1$
+
+       public static final String FIELD = "field"; //$NON-NLS-1$
+
+       public static final String FIELD_TYPE = "field_type"; //$NON-NLS-1$
+
+       public static final String BARE_FIELD_NAME = "bare_field_name"; //$NON-NLS-1$
+
+       public static final String PARAM = "param"; //$NON-NLS-1$
+
+       public static final String RETURN_TYPE = "return_type"; //$NON-NLS-1$
+
+       public static final String SEE_TAG = "see_to_overridden"; //$NON-NLS-1$
+
+       public static final String TAGS = "tags"; //$NON-NLS-1$
+
+       public static final String TYPENAME = "type_name"; //$NON-NLS-1$
+
+       public static final String FILENAME = "file_name"; //$NON-NLS-1$
+
+       public static final String PACKAGENAME = "package_name"; //$NON-NLS-1$
+
+       public static final String PROJECTNAME = "project_name"; //$NON-NLS-1$
+
+       public static final String PACKAGE_DECLARATION = "package_declaration"; //$NON-NLS-1$
+
+       public static final String TYPE_DECLARATION = "type_declaration"; //$NON-NLS-1$
+
+       public static final String TYPE_COMMENT = "typecomment"; //$NON-NLS-1$
+
+       /**
+        * Resolver that resolves to the variable defined in the context.
+        */
+       public static class CodeTemplateVariableResolver extends
+                       TemplateVariableResolver {
+               public CodeTemplateVariableResolver(String type, String description) {
+                       super(type, description);
+               }
+
+               protected String resolve(TemplateContext context) {
+                       return context.getVariable(getType());
+               }
+       }
+
+       /**
+        * Resolver for javadoc tags.
+        */
+       public static class TagsVariableResolver extends TemplateVariableResolver {
+               public TagsVariableResolver() {
+                       super(
+                                       TAGS,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.tags")); //$NON-NLS-1$
+               }
+
+               protected String resolve(TemplateContext context) {
+                       return "@"; //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Resolver for todo tags.
+        */
+       protected static class Todo extends TemplateVariableResolver {
+
+               public Todo() {
+                       super(
+                                       "todo", JavaTemplateMessages.getString("CodeTemplateContextType.variable.description.todo")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+
+               protected String resolve(TemplateContext context) {
+                       String todoTaskTag = StubUtility
+                                       .getTodoTaskTag(((CodeTemplateContext) context)
+                                                       .getJavaProject());
+                       if (todoTaskTag == null)
+                               return "XXX"; //$NON-NLS-1$
+
+                       return todoTaskTag;
+               }
+       }
+
+       private boolean fIsComment;
+
+       public CodeTemplateContextType(String contextName) {
+               super(contextName);
+
+               fIsComment = false;
+
+               // global
+               addResolver(new GlobalTemplateVariables.Dollar());
+               addResolver(new GlobalTemplateVariables.Date());
+               addResolver(new GlobalTemplateVariables.Year());
+               addResolver(new GlobalTemplateVariables.Time());
+               addResolver(new GlobalTemplateVariables.User());
+               addResolver(new Todo());
+
+               if (CATCHBLOCK_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       EXCEPTION_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.exceptiontype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       EXCEPTION_VAR,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.exceptionvar"))); //$NON-NLS-1$
+               } else if (METHODBODY_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_METHOD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingmethod"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       BODY_STATEMENT,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.bodystatement"))); //$NON-NLS-1$
+               } else if (CONSTRUCTORBODY_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       BODY_STATEMENT,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.bodystatement"))); //$NON-NLS-1$
+               } else if (GETTERBODY_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_METHOD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingmethod"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       FIELD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.getterfieldname"))); //$NON-NLS-1$
+               } else if (SETTERBODY_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_METHOD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingmethod"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       FIELD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.getterfieldname"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       PARAM,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.param"))); //$NON-NLS-1$
+               } else if (NEWTYPE_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       TYPENAME,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.typename"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       PACKAGE_DECLARATION,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.packdeclaration"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       TYPE_DECLARATION,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.typedeclaration"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       TYPE_COMMENT,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.typecomment"))); //$NON-NLS-1$
+                       addCompilationUnitVariables();
+               } else if (NEWHTML_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       TYPENAME,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.typename"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       PACKAGE_DECLARATION,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.packdeclaration"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       TYPE_DECLARATION,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.typedeclaration"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       TYPE_COMMENT,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.typecomment"))); //$NON-NLS-1$
+                       addCompilationUnitVariables();
+               } else if (TYPECOMMENT_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       TYPENAME,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.typename"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new TagsVariableResolver());
+                       addCompilationUnitVariables();
+                       fIsComment = true;
+               } else if (FIELDCOMMENT_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       FIELD_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.fieldtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       FIELD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.fieldname"))); //$NON-NLS-1$
+                       addCompilationUnitVariables();
+                       fIsComment = true;
+               } else if (METHODCOMMENT_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_METHOD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingmethod"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       RETURN_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.returntype"))); //$NON-NLS-1$
+                       addResolver(new TagsVariableResolver());
+                       addCompilationUnitVariables();
+                       fIsComment = true;
+               } else if (OVERRIDECOMMENT_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_METHOD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingmethod"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       SEE_TAG,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.seetag"))); //$NON-NLS-1$
+                       addResolver(new TagsVariableResolver());
+                       addCompilationUnitVariables();
+                       fIsComment = true;
+               } else if (CONSTRUCTORCOMMENT_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new TagsVariableResolver());
+                       addCompilationUnitVariables();
+                       fIsComment = true;
+               } else if (GETTERCOMMENT_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       FIELD_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.getterfieldtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       FIELD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.getterfieldname"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_METHOD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingmethod"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       BARE_FIELD_NAME,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.barefieldname"))); //$NON-NLS-1$
+                       addCompilationUnitVariables();
+                       fIsComment = true;
+               } else if (SETTERCOMMENT_CONTEXTTYPE.equals(contextName)) {
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       FIELD_TYPE,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.getterfieldtype"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       FIELD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.getterfieldname"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       ENCLOSING_METHOD,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.enclosingmethod"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       PARAM,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.param"))); //$NON-NLS-1$
+                       addResolver(new CodeTemplateVariableResolver(
+                                       BARE_FIELD_NAME,
+                                       JavaTemplateMessages
+                                                       .getString("CodeTemplateContextType.variable.description.barefieldname"))); //$NON-NLS-1$
+                       addCompilationUnitVariables();
+                       fIsComment = true;
+               }
+       }
+
+       private void addCompilationUnitVariables() {
+               addResolver(new CodeTemplateVariableResolver(
+                               FILENAME,
+                               JavaTemplateMessages
+                                               .getString("CodeTemplateContextType.variable.description.filename"))); //$NON-NLS-1$
+               addResolver(new CodeTemplateVariableResolver(
+                               PACKAGENAME,
+                               JavaTemplateMessages
+                                               .getString("CodeTemplateContextType.variable.description.packagename"))); //$NON-NLS-1$
+               addResolver(new CodeTemplateVariableResolver(
+                               PROJECTNAME,
+                               JavaTemplateMessages
+                                               .getString("CodeTemplateContextType.variable.description.projectname"))); //$NON-NLS-1$
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.ContextType#validateVariables(net.sourceforge.phpdt.internal.corext.template.TemplateVariable[])
+        */
+       protected void validateVariables(TemplateVariable[] variables)
+                       throws TemplateException {
+               ArrayList required = new ArrayList(5);
+               String contextName = getId();
+               // if (NEWTYPE_CONTEXTTYPE.equals(contextName)) {
+               // required.add(PACKAGE_DECLARATION);
+               // required.add(TYPE_DECLARATION);
+               // }
+               for (int i = 0; i < variables.length; i++) {
+                       String type = variables[i].getType();
+                       if (getResolver(type) == null) {
+                               throw new TemplateException(
+                                               JavaTemplateMessages
+                                                               .getFormattedString(
+                                                                               "CodeTemplateContextType.validate.unknownvariable", type)); //$NON-NLS-1$
+                       }
+                       required.remove(type);
+               }
+               if (!required.isEmpty()) {
+                       String missing = (String) required.get(0);
+                       throw new TemplateException(
+                                       JavaTemplateMessages
+                                                       .getFormattedString(
+                                                                       "CodeTemplateContextType.validate.missingvariable", missing)); //$NON-NLS-1$
+               }
+               super.validateVariables(variables);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.corext.template.ContextType#createContext()
+        */
+       public TemplateContext createContext() {
+               return null;
+       }
+
+       public static void registerContextTypes(ContextTypeRegistry registry) {
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.CATCHBLOCK_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.METHODBODY_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.CONSTRUCTORBODY_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.GETTERBODY_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.SETTERBODY_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.NEWTYPE_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.NEWHTML_CONTEXTTYPE));
+
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.TYPECOMMENT_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.FIELDCOMMENT_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.METHODCOMMENT_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.CONSTRUCTORCOMMENT_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.OVERRIDECOMMENT_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.GETTERCOMMENT_CONTEXTTYPE));
+               registry.addContextType(new CodeTemplateContextType(
+                               CodeTemplateContextType.SETTERCOMMENT_CONTEXTTYPE));
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.ContextType#validate(java.lang.String)
+        */
+       public void validate(String pattern) throws TemplateException {
+               super.validate(pattern);
+               if (fIsComment) {
+                       if (!isValidComment(pattern)) {
+                               throw new TemplateException(
+                                               JavaTemplateMessages
+                                                               .getString("CodeTemplateContextType.validate.invalidcomment")); //$NON-NLS-1$
+                       }
+               }
+       }
+
+       private boolean isValidComment(String template) {
+               IScanner scanner = ToolFactory.createScanner(true, false, false, true);// false);
+               scanner.setSource(template.toCharArray());
+               try {
+                       int next = scanner.getNextToken();
+                       while (next == ITerminalSymbols.TokenNameCOMMENT_LINE
+                                       || next == ITerminalSymbols.TokenNameCOMMENT_PHPDOC
+                                       || next == ITerminalSymbols.TokenNameCOMMENT_BLOCK) {
+                               next = scanner.getNextToken();
+                       }
+                       return next == ITerminalSymbols.TokenNameEOF;
+               } catch (InvalidInputException e) {
+               }
+               return false;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplates.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CodeTemplates.java
new file mode 100644 (file)
index 0000000..668967a
--- /dev/null
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.text.templates.Template;
+
+/**
+ * <code>CodeTemplates</code> gives access to the available code templates.
+ * 
+ * @since 3.0
+ * @deprecated use
+ *             {@link net.sourceforge.phpdt.internal.ui.JavaPlugin#getCodeTemplateStore()}
+ *             instead
+ */
+public class CodeTemplates extends
+               net.sourceforge.phpdt.internal.corext.template.php.TemplateSet {
+
+       private static final String DEFAULT_FILE = "default-codetemplates.xml"; //$NON-NLS-1$
+
+       private static final String TEMPLATE_FILE = "codetemplates.xml"; //$NON-NLS-1$
+
+       private static final ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(JavaTemplateMessages.class.getName());
+
+       /** Singleton. */
+       private static CodeTemplates fgTemplates;
+
+       public static Template getCodeTemplate(String name) {
+               return getInstance().getFirstTemplate(name);
+       }
+
+       /**
+        * Returns an instance of templates.
+        */
+       public static CodeTemplates getInstance() {
+               if (fgTemplates == null)
+                       fgTemplates = new CodeTemplates();
+
+               return fgTemplates;
+       }
+
+       private CodeTemplates() {
+               super(
+                               "codetemplate", WebUI.getDefault().getCodeTemplateContextRegistry()); //$NON-NLS-1$
+               create();
+       }
+
+       private void create() {
+
+               try {
+                       addFromStream(getDefaultsAsStream(), false, true, fgResourceBundle);
+                       File templateFile = getTemplateFile();
+                       if (templateFile.exists()) {
+                               addFromFile(templateFile, false, fgResourceBundle);
+                       }
+                       saveToFile(templateFile);
+
+               } catch (CoreException e) {
+                       PHPeclipsePlugin.log(e);
+                       clear();
+               }
+
+       }
+
+       /**
+        * Resets the template set.
+        */
+       public void reset() throws CoreException {
+               clear();
+               addFromFile(getTemplateFile(), false, fgResourceBundle);
+       }
+
+       /**
+        * Resets the template set with the default templates.
+        */
+       public void restoreDefaults() throws CoreException {
+               clear();
+               addFromStream(getDefaultsAsStream(), false, true, fgResourceBundle);
+       }
+
+       /**
+        * Saves the template set.
+        */
+       public void save() throws CoreException {
+               saveToFile(getTemplateFile());
+       }
+
+       private static InputStream getDefaultsAsStream() {
+               return CodeTemplates.class.getResourceAsStream(DEFAULT_FILE);
+       }
+
+       private static File getTemplateFile() {
+               IPath path = PHPeclipsePlugin.getDefault().getStateLocation();
+               path = path.append(TEMPLATE_FILE);
+
+               return path.toFile();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitCompletion.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitCompletion.java
new file mode 100644 (file)
index 0000000..7684b9d
--- /dev/null
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import net.sourceforge.phpdt.core.CompletionRequestorAdapter;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+
+/**
+ * A completion requestor to collect informations on local variables. This class
+ * is used for guessing variable names like arrays, collections, etc.
+ */
+class CompilationUnitCompletion extends CompletionRequestorAdapter {
+
+       static class LocalVariable {
+               String name;
+
+               String typePackageName;
+
+               String typeName;
+
+               LocalVariable(String name, String typePackageName, String typeName) {
+                       this.name = name;
+                       this.typePackageName = typePackageName;
+                       this.typeName = typeName;
+               }
+       }
+
+       private ICompilationUnit fUnit;
+
+       private List fLocalVariables = new ArrayList();
+
+       private Map fTypes = new HashMap();
+
+       private boolean fError;
+
+       /**
+        * Creates a compilation unit completion.
+        * 
+        * @param unit
+        *            the compilation unit, may be <code>null</code>.
+        */
+       public CompilationUnitCompletion(ICompilationUnit unit) {
+               reset(unit);
+       }
+
+       /**
+        * Resets the completion requestor.
+        * 
+        * @param unit
+        *            the compilation unit, may be <code>null</code>.
+        */
+       public void reset(ICompilationUnit unit) {
+               fUnit = unit;
+
+               fLocalVariables.clear();
+               fTypes.clear();
+
+               fError = false;
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptError(IProblem)
+        */
+       public void acceptError(IProblem error) {
+               fError = true;
+       }
+
+       /*
+        * @see ICodeCompletionRequestor#acceptLocalVariable
+        */
+       public void acceptLocalVariable(char[] name, char[] typePackageName,
+                       char[] typeName, int modifiers, int completionStart,
+                       int completionEnd, int relevance) {
+               fLocalVariables.add(new LocalVariable(new String(name), new String(
+                               typePackageName), new String(typeName)));
+       }
+
+       // ---
+
+       /**
+        * Tests if the code completion process produced errors.
+        */
+       public boolean hasErrors() {
+               return fError;
+       }
+
+       boolean existsLocalName(String name) {
+               for (Iterator iterator = fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable = (LocalVariable) iterator.next();
+
+                       if (localVariable.name.equals(name))
+                               return true;
+               }
+
+               return false;
+       }
+
+       String[] getLocalVariableNames() {
+               String[] res = new String[fLocalVariables.size()];
+               int i = 0;
+               for (Iterator iterator = fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable = (LocalVariable) iterator.next();
+                       res[i++] = localVariable.name;
+               }
+               return res;
+       }
+
+       LocalVariable[] findLocalArrays() {
+               Vector vector = new Vector();
+
+               for (Iterator iterator = fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable = (LocalVariable) iterator.next();
+
+                       if (isArray(localVariable.typeName))
+                               vector.add(localVariable);
+               }
+
+               return (LocalVariable[]) vector
+                               .toArray(new LocalVariable[vector.size()]);
+       }
+
+       // LocalVariable[] findLocalCollections() throws JavaModelException {
+       // Vector vector= new Vector();
+       //
+       // for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();)
+       // {
+       // LocalVariable localVariable= (LocalVariable) iterator.next();
+       //
+       // String typeName= qualify(localVariable.typeName);
+       //                      
+       // if (typeName == null)
+       // continue;
+       //                                              
+       // if (isSubclassOf(typeName, "java.util.Collection")) //$NON-NLS-1$
+       // vector.add(localVariable);
+       // }
+       //
+       // return (LocalVariable[]) vector.toArray(new
+       // LocalVariable[vector.size()]);
+       // }
+
+       String simplifyTypeName(String qualifiedName) {
+               return (String) fTypes.get(qualifiedName);
+       }
+
+       private static boolean isArray(String type) {
+               return type.endsWith("[]"); //$NON-NLS-1$
+       }
+
+       // returns fully qualified name if successful
+       // private String qualify(String typeName) throws JavaModelException {
+       // if (fUnit == null)
+       // return null;
+       //
+       // IType[] types= fUnit.getTypes();
+       //
+       // if (types.length == 0)
+       // return null;
+       //              
+       // String[][] resolvedTypeNames= types[0].resolveType(typeName);
+       //
+       // if (resolvedTypeNames == null)
+       // return null;
+       //                      
+       // return resolvedTypeNames[0][0] + '.' + resolvedTypeNames[0][1];
+       // }
+
+       // type names must be fully qualified
+       // private boolean isSubclassOf(String typeName0, String typeName1) throws
+       // JavaModelException {
+       // if (typeName0.equals(typeName1))
+       // return true;
+       //
+       // if (fUnit == null)
+       // return false;
+       //
+       // IJavaProject project= fUnit.getJavaProject();
+       //
+       // IType type0= project.findType(typeName0);
+       // if (type0 == null)
+       // return false;
+       //
+       // IType type1= project.findType(typeName1);
+       // if (type1 == null)
+       // return false;
+       //
+       // ITypeHierarchy hierarchy= type0.newSupertypeHierarchy(null);
+       // IType[] superTypes= hierarchy.getAllSupertypes(type0);
+       //              
+       // for (int i= 0; i < superTypes.length; i++)
+       // if (superTypes[i].equals(type1))
+       // return true;
+       //              
+       // return false;
+       // }
+
+       /*
+        * @see net.sourceforge.phpdt.core.ICompletionRequestor#acceptClass(char[],
+        *      char[], char[], int, int, int, int)
+        */
+       public void acceptClass(char[] packageName, char[] className,
+                       char[] completionName, int modifiers, int completionStart,
+                       int completionEnd, int relevance) {
+               final String qualifiedName = createQualifiedTypeName(packageName,
+                               className);
+               fTypes.put(qualifiedName, String.valueOf(completionName));
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.core.ICompletionRequestor#acceptInterface(char[],
+        *      char[], char[], int, int, int, int)
+        */
+       public void acceptInterface(char[] packageName, char[] interfaceName,
+                       char[] completionName, int modifiers, int completionStart,
+                       int completionEnd, int relevance) {
+               final String qualifiedName = createQualifiedTypeName(packageName,
+                               interfaceName);
+               fTypes.put(qualifiedName, String.valueOf(completionName));
+       }
+
+       private static String createQualifiedTypeName(char[] packageName,
+                       char[] className) {
+               StringBuffer buffer = new StringBuffer();
+
+               if (packageName.length != 0) {
+                       buffer.append(packageName);
+                       buffer.append('.');
+               }
+               buffer.append(className);
+
+               return buffer.toString();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitContext.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitContext.java
new file mode 100644 (file)
index 0000000..a7defad
--- /dev/null
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.text.template.contentassist.MultiVariableGuess;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.templates.DocumentTemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+
+// import
+// net.sourceforge.phpdt.internal.ui.text.template.contentassist.MultiVariableGuess;
+
+/**
+ * A compilation unit context.
+ */
+public abstract class CompilationUnitContext extends DocumentTemplateContext {
+
+       /** The compilation unit, may be <code>null</code>. */
+       private final ICompilationUnit fCompilationUnit;
+
+       /** A flag to force evaluation in head-less mode. */
+       protected boolean fForceEvaluation;
+
+       /** A global state for proposals that change if a master proposal changes. */
+       protected MultiVariableGuess fMultiVariableGuess;
+
+       /**
+        * Creates a compilation unit context.
+        * 
+        * @param type
+        *            the context type
+        * @param document
+        *            the document
+        * @param completionOffset
+        *            the completion position within the document
+        * @param completionLength
+        *            the completion length within the document
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       protected CompilationUnitContext(TemplateContextType type,
+                       IDocument document, int completionOffset, int completionLength,
+                       ICompilationUnit compilationUnit) {
+               super(type, document, completionOffset, completionLength);
+               fCompilationUnit = compilationUnit;
+       }
+
+       /**
+        * Returns the compilation unit if one is associated with this context,
+        * <code>null</code> otherwise.
+        */
+       public final ICompilationUnit getCompilationUnit() {
+               return fCompilationUnit;
+       }
+
+       /**
+        * Returns the enclosing element of a particular element type,
+        * <code>null</code> if no enclosing element of that type exists.
+        */
+       public IJavaElement findEnclosingElement(int elementType) {
+               if (fCompilationUnit == null)
+                       return null;
+
+               try {
+                       IJavaElement element = fCompilationUnit.getElementAt(getStart());
+                       if (element == null) {
+                               element = fCompilationUnit;
+                       }
+
+                       return element.getAncestor(elementType);
+
+               } catch (JavaModelException e) {
+                       return null;
+               }
+       }
+
+       /**
+        * Forces evaluation.
+        */
+       public void setForceEvaluation(boolean evaluate) {
+               fForceEvaluation = evaluate;
+       }
+
+       /**
+        * Returns the multivariable guess - state
+        * 
+        * @return
+        */
+       public MultiVariableGuess getMultiVariableGuess() {
+               return fMultiVariableGuess;
+       }
+
+       /**
+        * @param multiVariableGuess
+        *            The multiVariableGuess to set.
+        */
+       public void setMultiVariableGuess(MultiVariableGuess multiVariableGuess) {
+               fMultiVariableGuess = multiVariableGuess;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitContextType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitContextType.java
new file mode 100644 (file)
index 0000000..085d382
--- /dev/null
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.Signature;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+
+/**
+ * Compilation unit context type.
+ */
+public abstract class CompilationUnitContextType extends TemplateContextType {
+
+       protected static class ReturnType extends TemplateVariableResolver {
+               public ReturnType() {
+                       super(
+                                       "return_type", JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.return.type")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+
+               protected String resolve(TemplateContext context) {
+                       IJavaElement element = ((CompilationUnitContext) context)
+                                       .findEnclosingElement(IJavaElement.METHOD);
+                       if (element == null)
+                               return null;
+
+                       try {
+                               return Signature.toString(((IMethod) element).getReturnType());
+                       } catch (JavaModelException e) {
+                               return null;
+                       }
+               }
+       }
+
+       protected static class File extends TemplateVariableResolver {
+               public File() {
+                       super(
+                                       "file", JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.file")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+
+               protected String resolve(TemplateContext context) {
+                       ICompilationUnit unit = ((CompilationUnitContext) context)
+                                       .getCompilationUnit();
+
+                       return (unit == null) ? null : unit.getElementName();
+               }
+
+               /*
+                * @see org.eclipse.jface.text.templates.TemplateVariableResolver#isUnambiguous(org.eclipse.jface.text.templates.TemplateContext)
+                */
+               protected boolean isUnambiguous(TemplateContext context) {
+                       return resolve(context) != null;
+               }
+       }
+
+       protected static class PrimaryTypeName extends TemplateVariableResolver {
+               public PrimaryTypeName() {
+                       super(
+                                       "primary_type_name", JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.primary.type.name")); //$NON-NLS-1$ //$NON-NLS-2$
+
+               }
+
+               protected String resolve(TemplateContext context) {
+                       ICompilationUnit unit = ((CompilationUnitContext) context)
+                                       .getCompilationUnit();
+                       if (unit == null)
+                               return null;
+                       String elementName = unit.getElementName();
+                       return elementName.substring(0, elementName.lastIndexOf('.'));
+               }
+
+               /*
+                * @see org.eclipse.jface.text.templates.TemplateVariableResolver#isUnambiguous(org.eclipse.jface.text.templates.TemplateContext)
+                */
+               protected boolean isUnambiguous(TemplateContext context) {
+                       return resolve(context) != null;
+               }
+       }
+
+       protected static class EnclosingJavaElement extends
+                       TemplateVariableResolver {
+               protected final int fElementType;
+
+               public EnclosingJavaElement(String name, String description,
+                               int elementType) {
+                       super(name, description);
+                       fElementType = elementType;
+               }
+
+               protected String resolve(TemplateContext context) {
+                       IJavaElement element = ((CompilationUnitContext) context)
+                                       .findEnclosingElement(fElementType);
+                       return (element == null) ? null : element.getElementName();
+               }
+
+               /*
+                * @see org.eclipse.jface.text.templates.TemplateVariableResolver#isUnambiguous(org.eclipse.jface.text.templates.TemplateContext)
+                */
+               protected boolean isUnambiguous(TemplateContext context) {
+                       return resolve(context) != null;
+               }
+       }
+
+       protected static class Method extends EnclosingJavaElement {
+               public Method() {
+                       super(
+                                       "enclosing_method", JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.method"), IJavaElement.METHOD); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }
+
+       protected static class Type extends EnclosingJavaElement {
+               public Type() {
+                       super(
+                                       "enclosing_type", JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.type"), IJavaElement.TYPE); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }
+
+       /*
+        * protected static class SuperClass extends EnclosingJavaElement { public
+        * Type() { super("super_class",
+        * TemplateMessages.getString("JavaContextType.variable.description.type"),
+        * IJavaElement.TYPE); } }
+        */
+       protected static class Package extends EnclosingJavaElement {
+               public Package() {
+                       super(
+                                       "enclosing_package", JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.package"), IJavaElement.PACKAGE_FRAGMENT); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }
+
+       protected static class Project extends EnclosingJavaElement {
+               public Project() {
+                       super(
+                                       "enclosing_project", JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.project"), IJavaElement.JAVA_PROJECT); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }
+
+       /*
+        * protected static class Project2 extends TemplateVariableResolver { public
+        * Project2() { super("project",
+        * TemplateMessages.getString("JavaContextType.variable.description.project")); }
+        * public String evaluate(TemplateContext context) { ICompilationUnit unit=
+        * ((JavaContext) context).getUnit(); return (unit == null) ? null :
+        * unit.getJavaProject().getElementName(); } }
+        */
+       protected static class Arguments extends TemplateVariableResolver {
+               public Arguments() {
+                       super(
+                                       "enclosing_method_arguments", JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.method.arguments")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+
+               protected String resolve(TemplateContext context) {
+                       IJavaElement element = ((CompilationUnitContext) context)
+                                       .findEnclosingElement(IJavaElement.METHOD);
+                       if (element == null)
+                               return null;
+
+                       IMethod method = (IMethod) element;
+
+                       try {
+                               String[] arguments = method.getParameterNames();
+                               StringBuffer buffer = new StringBuffer();
+
+                               for (int i = 0; i < arguments.length; i++) {
+                                       if (i > 0)
+                                               buffer.append(", "); //$NON-NLS-1$
+                                       buffer.append(arguments[i]);
+                               }
+
+                               return buffer.toString();
+
+                       } catch (JavaModelException e) {
+                               return null;
+                       }
+               }
+       }
+
+       /*
+        * protected static class Line extends TemplateVariableResolver { public
+        * Line() { super("line",
+        * TemplateMessages.getString("CompilationUnitContextType.variable.description.line")); }
+        * public String evaluate(TemplateContext context) { return
+        * ((JavaTemplateContext) context).guessLineNumber(); } }
+        */
+
+       /*
+        * @see ContextType#ContextType(String)
+        */
+       public CompilationUnitContextType(String name) {
+               super(name);
+       }
+
+       public abstract CompilationUnitContext createContext(IDocument document,
+                       int completionPosition, int length, ICompilationUnit compilationUnit);
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.corext.template.ContextType#validateVariables(net.sourceforge.phpdt.internal.corext.template.TemplateVariable[])
+        */
+       protected void validateVariables(TemplateVariable[] variables)
+                       throws TemplateException {
+               // check for multiple cursor variables
+               for (int i = 0; i < variables.length; i++) {
+                       TemplateVariable var = variables[i];
+                       if (var.getType().equals(GlobalTemplateVariables.Cursor.NAME)) {
+                               if (var.getOffsets().length > 1) {
+                                       throw new TemplateException(
+                                                       JavaTemplateMessages
+                                                                       .getString("ContextType.error.multiple.cursor.variables")); //$NON-NLS-1$
+                               }
+                       }
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/HTMLContextType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/HTMLContextType.java
new file mode 100644 (file)
index 0000000..b187c3d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+// import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateVariable;
+
+/**
+ * A context type for javadoc.
+ */
+public class HTMLContextType extends CompilationUnitContextType {
+
+       /**
+        * Creates a java context type.
+        */
+       public HTMLContextType() {
+               super("html"); //$NON-NLS-1$
+
+               // global
+               addResolver(new GlobalTemplateVariables.Cursor());
+               addResolver(new GlobalTemplateVariables.WordSelection());
+               addResolver(new GlobalTemplateVariables.LineSelection());
+               addResolver(new GlobalTemplateVariables.Dollar());
+               addResolver(new GlobalTemplateVariables.Date());
+               addResolver(new GlobalTemplateVariables.Year());
+               addResolver(new GlobalTemplateVariables.Time());
+               addResolver(new GlobalTemplateVariables.User());
+
+               addResolver(new File());
+       }
+
+       /*
+        * @see ContextType#createContext()
+        */
+       public CompilationUnitContext createContext(IDocument document, int offset,
+                       int length, ICompilationUnit compilationUnit) {
+               return new HTMLUnitContext(this, document, offset, length,
+                               compilationUnit);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContextType#createContext(org.eclipse.jface.text.IDocument,
+        *      int, int, net.sourceforge.phpdt.core.ICompilationUnit)
+        */
+       // public CompilationUnitContext createContext(IDocument document, int
+       // offset, int length, ICompilationUnit compilationUnit) {
+       // return new JavaDocContext(this, document, offset, length,
+       // compilationUnit);
+       // }
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.corext.template.ContextType#validateVariables(net.sourceforge.phpdt.internal.corext.template.TemplateVariable[])
+        */
+       protected void validateVariables(TemplateVariable[] variables)
+                       throws TemplateException {
+               // check for multiple cursor variables
+               for (int i = 0; i < variables.length; i++) {
+                       TemplateVariable var = variables[i];
+                       if (var.getType().equals(GlobalTemplateVariables.Cursor.NAME)) {
+                               if (var.getOffsets().length > 1) {
+                                       throw new TemplateException(
+                                                       JavaTemplateMessages
+                                                                       .getString("ContextType.error.multiple.cursor.variables")); //$NON-NLS-1$
+                               }
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/HTMLUnitContext.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/HTMLUnitContext.java
new file mode 100644 (file)
index 0000000..bbd35b7
--- /dev/null
@@ -0,0 +1,175 @@
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateTranslator;
+
+/**
+ * A context for javadoc.
+ */
+public class HTMLUnitContext extends CompilationUnitContext {
+
+       // tags
+       // private static final char HTML_TAG_BEGIN= '<';
+       // private static final char HTML_TAG_END= '>';
+       // private static final char JAVADOC_TAG_BEGIN= '@';
+       /**
+        * special characters '&' for the start of HTML entities '<' for the start
+        * of HTML tags '#' for the start of colour attributes '{' for the start of
+        * smarty partitions inside HTML code
+        */
+       private static final String specialChars = "&<#{";
+
+       /**
+        * Creates a javadoc template context.
+        * 
+        * @param type
+        *            the context type.
+        * @param document
+        *            the document.
+        * @param completionOffset
+        *            the completion offset within the document.
+        * @param completionLength
+        *            the completion length within the document.
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>).
+        */
+       public HTMLUnitContext(TemplateContextType type, IDocument document,
+                       int completionOffset, int completionLength,
+                       ICompilationUnit compilationUnit) {
+               super(type, document, completionOffset, completionLength,
+                               compilationUnit);
+       }
+
+       /*
+        * @see TemplateContext#canEvaluate(Template templates)
+        */
+       public boolean canEvaluate(Template template) {
+               String key = getKey();
+
+               if (fForceEvaluation)
+                       return true;
+
+               return template.matches(key, getContextType().getId())
+                               && (key.length() != 0)
+                               && template.getName().toLowerCase().startsWith(
+                                               key.toLowerCase());
+       }
+
+       /*
+        * @see DocumentTemplateContext#getCompletionPosition();
+        */
+       public int getStart() {
+               IDocument document = getDocument();
+               try {
+                       int start = getCompletionOffset();
+                       char ch = ' ';
+                       while (start != 0) {
+                               ch = document.getChar(start - 1);
+                               if (specialChars.indexOf(ch) != (-1)) {
+                                       return --start;
+                               }
+                               if (Character.isUnicodeIdentifierPart(ch)) {
+                                       start--;
+                               } else {
+                                       break;
+                               }
+                       }
+                       if ((start != 0)
+                                       && Character.isUnicodeIdentifierStart(document
+                                                       .getChar(start - 1))) {
+                               start--;
+                               if ((start != 0)
+                                               && specialChars.indexOf(document.getChar(start - 1)) != (-1)) {
+                                       start--;
+                               }
+                       }
+
+                       // while (((start != 0)
+                       // && Character.isUnicodeIdentifierPart(document.getChar(start -
+                       // 1)))
+                       // || ((start != 0)
+                       // && specialChars.indexOf(document.getChar(start - 1)) != (-1))) {
+                       // start--;
+                       // }
+                       //
+                       // if (((start != 0)
+                       // && Character.isUnicodeIdentifierStart(document.getChar(start -
+                       // 1)))
+                       // || ((start != 0)
+                       // && specialChars.indexOf(document.getChar(start - 1)) != (-1))) {
+                       // start--;
+                       // }
+
+                       return start;
+
+               } catch (BadLocationException e) {
+                       return getCompletionOffset();
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext#getEnd()
+        */
+       public int getEnd() {
+
+               if (getCompletionLength() == 0)
+                       return super.getEnd();
+
+               try {
+                       IDocument document = getDocument();
+
+                       int start = getCompletionOffset();
+                       int end = getCompletionOffset() + getCompletionLength();
+
+                       while (start != end
+                                       && Character.isWhitespace(document.getChar(end - 1)))
+                               end--;
+
+                       return end;
+
+               } catch (BadLocationException e) {
+                       return super.getEnd();
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext#getKey()
+        */
+       public String getKey() {
+
+               if (getCompletionLength() == 0)
+                       return super.getKey();
+
+               try {
+                       IDocument document = getDocument();
+
+                       int start = getStart();
+                       int end = getCompletionOffset();
+                       return start <= end ? document.get(start, end - start) : ""; //$NON-NLS-1$
+
+               } catch (BadLocationException e) {
+                       return super.getKey();
+               }
+       }
+
+       /*
+        * @see TemplateContext#evaluate(Template)
+        */
+       public TemplateBuffer evaluate(Template template)
+                       throws BadLocationException, TemplateException {
+               TemplateTranslator translator = new TemplateTranslator();
+               TemplateBuffer buffer = translator.translate(template);
+
+               getContextType().resolve(buffer, this);
+
+               return buffer;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContext.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContext.java
new file mode 100644 (file)
index 0000000..0102646
--- /dev/null
@@ -0,0 +1,664 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.internal.corext.Assert;
+import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitCompletion.LocalVariable;
+import net.sourceforge.phpdt.internal.corext.util.Strings;
+import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage;
+import net.sourceforge.phpdt.internal.ui.text.template.contentassist.MultiVariable;
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateTranslator;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A context for java source.
+ */
+public class JavaContext extends CompilationUnitContext {
+
+       /** The platform default line delimiter. */
+       private static final String PLATFORM_LINE_DELIMITER = System
+                       .getProperty("line.separator"); //$NON-NLS-1$
+
+       /** A code completion requestor for guessing local variable names. */
+       private CompilationUnitCompletion fCompletion;
+
+       /**
+        * Creates a java template context.
+        * 
+        * @param type
+        *            the context type.
+        * @param document
+        *            the document.
+        * @param completionOffset
+        *            the completion offset within the document.
+        * @param completionLength
+        *            the completion length.
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>).
+        */
+       public JavaContext(TemplateContextType type, IDocument document,
+                       int completionOffset, int completionLength,
+                       ICompilationUnit compilationUnit) {
+               super(type, document, completionOffset, completionLength,
+                               compilationUnit);
+       }
+
+       /**
+        * Returns the indentation level at the position of code completion.
+        */
+       private int getIndentation() {
+               int start = getStart();
+               IDocument document = getDocument();
+               try {
+                       IRegion region = document.getLineInformationOfOffset(start);
+                       String lineContent = document.get(region.getOffset(), region
+                                       .getLength());
+                       return Strings.computeIndent(lineContent,
+                                       CodeFormatterPreferencePage.getTabSize());
+                       // return Strings.computeIndent(lineContent,
+                       // CodeFormatterUtil.getTabWidth());
+               } catch (BadLocationException e) {
+                       return 0;
+               }
+       }
+
+       /*
+        * @see TemplateContext#evaluate(Template template)
+        */
+       public TemplateBuffer evaluate(Template template)
+                       throws BadLocationException, TemplateException {
+
+               if (!canEvaluate(template))
+                       throw new TemplateException(JavaTemplateMessages
+                                       .getString("Context.error.cannot.evaluate")); //$NON-NLS-1$
+
+               TemplateTranslator translator = new TemplateTranslator() {
+                       /*
+                        * @see org.eclipse.jface.text.templates.TemplateTranslator#createVariable(java.lang.String,
+                        *      java.lang.String, int[])
+                        */
+                       protected TemplateVariable createVariable(String type, String name,
+                                       int[] offsets) {
+                               return new MultiVariable(type, name, offsets);
+                       }
+               };
+               TemplateBuffer buffer = translator.translate(template);
+
+               getContextType().resolve(buffer, this);
+               String lineDelimiter = null;
+               try {
+                       lineDelimiter = getDocument().getLineDelimiter(0);
+               } catch (BadLocationException e) {
+               }
+
+               if (lineDelimiter == null)
+                       lineDelimiter = PLATFORM_LINE_DELIMITER;
+               IPreferenceStore prefs = WebUI.getDefault()
+                               .getPreferenceStore();
+               // axelcl start
+               // boolean useCodeFormatter =
+               // prefs.getBoolean(PreferenceConstants.TEMPLATES_USE_CODEFORMATTER);
+               boolean useCodeFormatter = false;
+               // axelcl end
+
+               JavaFormatter formatter = new JavaFormatter(lineDelimiter,
+                               getIndentation(), useCodeFormatter);
+               formatter.format(buffer, this);
+               // debug start
+               // String res = buffer.getString();
+               // res = res.replaceAll("\n","/n");
+               // res = res.replaceAll("\t","/t");
+               // System.out.println(res);
+               // debug end
+               return buffer;
+       }
+
+       /*
+        * @see TemplateContext#canEvaluate(Template templates)
+        */
+       public boolean canEvaluate(Template template) {
+               String key = getKey();
+
+               if (fForceEvaluation)
+                       return true;
+
+               return template.matches(key, getContextType().getId())
+                               && key.length() != 0
+                               && template.getName().toLowerCase().startsWith(
+                                               key.toLowerCase());
+       }
+
+       public boolean canEvaluate(String identifier) {
+               String prefix = getKey();
+               return identifier.toLowerCase().startsWith(prefix.toLowerCase());
+       }
+
+       /*
+        * @see DocumentTemplateContext#getCompletionPosition();
+        */
+       public int getStart() {
+
+               try {
+                       IDocument document = getDocument();
+
+                       if (getCompletionLength() == 0) {
+
+                               int start = getCompletionOffset();
+                               while ((start != 0)
+                                               && Character.isUnicodeIdentifierPart(document
+                                                               .getChar(start - 1)))
+                                       start--;
+
+                               if ((start != 0)
+                                               && (Character.isUnicodeIdentifierStart(document
+                                                               .getChar(start - 1)) || (document
+                                                               .getChar(start - 1) == '$')))
+                                       start--;
+
+                               return start;
+
+                       } else {
+
+                               int start = getCompletionOffset();
+                               int end = getCompletionOffset() + getCompletionLength();
+
+                               while (start != 0
+                                               && Character.isUnicodeIdentifierPart(document
+                                                               .getChar(start - 1)))
+                                       start--;
+                               if ((start != 0)
+                                               && (Character.isUnicodeIdentifierStart(document
+                                                               .getChar(start - 1)) || (document
+                                                               .getChar(start - 1) == '$')))
+                                       start--;
+                               while (start != end
+                                               && Character.isWhitespace(document.getChar(start)))
+                                       start++;
+
+                               if (start == end)
+                                       start = getCompletionOffset();
+
+                               return start;
+                       }
+
+               } catch (BadLocationException e) {
+                       return super.getStart();
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext#getEnd()
+        */
+       public int getEnd() {
+
+               if (getCompletionLength() == 0)
+                       return super.getEnd();
+
+               try {
+                       IDocument document = getDocument();
+
+                       int start = getCompletionOffset();
+                       int end = getCompletionOffset() + getCompletionLength();
+
+                       while (start != end
+                                       && Character.isWhitespace(document.getChar(end - 1)))
+                               end--;
+
+                       return end;
+
+               } catch (BadLocationException e) {
+                       return super.getEnd();
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext#getKey()
+        */
+       public String getKey() {
+
+               // if (getCompletionLength() == 0) {
+               // return super.getKey();
+               // }
+
+               try {
+                       IDocument document = getDocument();
+
+                       int start = getStart();
+                       int end = getCompletionOffset();
+                       return start <= end ? document.get(start, end - start) : ""; //$NON-NLS-1$
+
+               } catch (BadLocationException e) {
+                       return super.getKey();
+               }
+       }
+
+       /**
+        * Returns the character before start position of completion.
+        */
+       public char getCharacterBeforeStart() {
+               int start = getStart();
+
+               try {
+                       return start == 0 ? ' ' : getDocument().getChar(start - 1);
+
+               } catch (BadLocationException e) {
+                       return ' ';
+               }
+       }
+
+       private static void handleException(Shell shell, Exception e) {
+               String title = JavaTemplateMessages
+                               .getString("JavaContext.error.title"); //$NON-NLS-1$
+               if (e instanceof CoreException)
+                       ExceptionHandler.handle((CoreException) e, shell, title, null);
+               else if (e instanceof InvocationTargetException)
+                       ExceptionHandler.handle((InvocationTargetException) e, shell,
+                                       title, null);
+               else {
+                       PHPeclipsePlugin.log(e);
+                       MessageDialog.openError(shell, title, e.getMessage());
+               }
+       }
+
+       // private CompilationUnitCompletion getCompletion() {
+       // ICompilationUnit compilationUnit= getCompilationUnit();
+       // if (fCompletion == null) {
+       // fCompletion= new CompilationUnitCompletion(compilationUnit);
+       //                      
+       // if (compilationUnit != null) {
+       // try {
+       // compilationUnit.codeComplete(getStart(), fCompletion);
+       // } catch (JavaModelException e) {
+       // // ignore
+       // }
+       // }
+       // }
+       //              
+       // return fCompletion;
+       // }
+
+       /**
+        * Returns the name of a guessed local array, <code>null</code> if no
+        * local array exists.
+        */
+       // public String guessArray() {
+       // return firstOrNull(guessArrays());
+       // }
+       /**
+        * Returns the name of a guessed local array, <code>null</code> if no
+        * local array exists.
+        */
+       // public String[] guessArrays() {
+       // CompilationUnitCompletion completion= getCompletion();
+       // LocalVariable[] localArrays= completion.findLocalArrays();
+       //                              
+       // String[] ret= new String[localArrays.length];
+       // for (int i= 0; i < ret.length; i++) {
+       // ret[ret.length - i - 1]= localArrays[i].name;
+       // }
+       // return ret;
+       // }
+       /**
+        * Returns the name of the type of a local array, <code>null</code> if no
+        * local array exists.
+        */
+       // public String guessArrayType() {
+       // return firstOrNull(guessArrayTypes());
+       // }
+       private String firstOrNull(String[] strings) {
+               if (strings.length > 0)
+                       return strings[0];
+               else
+                       return null;
+       }
+
+       /**
+        * Returns the name of the type of a local array, <code>null</code> if no
+        * local array exists.
+        */
+       // public String[][] guessGroupedArrayTypes() {
+       // CompilationUnitCompletion completion= getCompletion();
+       // LocalVariable[] localArrays= completion.findLocalArrays();
+       //              
+       // String[][] ret= new String[localArrays.length][];
+       //              
+       // for (int i= 0; i < localArrays.length; i++) {
+       // String type= getArrayTypeFromLocalArray(completion,
+       // localArrays[localArrays.length - i - 1]);
+       // ret[i]= new String[] {type};
+       // }
+       //              
+       // return ret;
+       // }
+       /**
+        * Returns the name of the type of a local array, <code>null</code> if no
+        * local array exists.
+        */
+       // public String[] guessArrayTypes() {
+       // CompilationUnitCompletion completion= getCompletion();
+       // LocalVariable[] localArrays= completion.findLocalArrays();
+       //              
+       // List ret= new ArrayList();
+       //              
+       // for (int i= 0; i < localArrays.length; i++) {
+       // String type= getArrayTypeFromLocalArray(completion,
+       // localArrays[localArrays.length - i - 1]);
+       // if (!ret.contains(type))
+       // ret.add(type);
+       // }
+       //              
+       // return (String[]) ret.toArray(new String[ret.size()]);
+       // }
+       private String getArrayTypeFromLocalArray(
+                       CompilationUnitCompletion completion, LocalVariable array) {
+               String arrayTypeName = array.typeName;
+               String typeName = getScalarType(arrayTypeName);
+               int dimension = getArrayDimension(arrayTypeName) - 1;
+               Assert.isTrue(dimension >= 0);
+
+               String qualifiedName = createQualifiedTypeName(array.typePackageName,
+                               typeName);
+               String innerTypeName = completion.simplifyTypeName(qualifiedName);
+
+               return innerTypeName == null ? createArray(typeName, dimension)
+                               : createArray(innerTypeName, dimension);
+       }
+
+       private static String createArray(String type, int dimension) {
+               StringBuffer buffer = new StringBuffer(type);
+               for (int i = 0; i < dimension; i++)
+                       buffer.append("[]"); //$NON-NLS-1$
+               return buffer.toString();
+       }
+
+       private static String getScalarType(String type) {
+               return type.substring(0, type.indexOf('['));
+       }
+
+       private static int getArrayDimension(String type) {
+
+               int dimension = 0;
+               int index = type.indexOf('[');
+
+               while (index != -1) {
+                       dimension++;
+                       index = type.indexOf('[', index + 1);
+               }
+
+               return dimension;
+       }
+
+       private static String createQualifiedTypeName(String packageName,
+                       String className) {
+               StringBuffer buffer = new StringBuffer();
+
+               if (packageName.length() != 0) {
+                       buffer.append(packageName);
+                       buffer.append('.');
+               }
+               buffer.append(className);
+
+               return buffer.toString();
+       }
+
+       /**
+        * Returns a proposal for a variable name of a local array element,
+        * <code>null</code> if no local array exists.
+        */
+       // public String guessArrayElement() {
+       // return firstOrNull(guessArrayElements());
+       // }
+       /**
+        * Returns a proposal for a variable name of a local array element,
+        * <code>null</code> if no local array exists.
+        */
+       // public String[] guessArrayElements() {
+       // ICompilationUnit cu= getCompilationUnit();
+       // if (cu == null) {
+       // return new String[0];
+       // }
+       //              
+       // CompilationUnitCompletion completion= getCompletion();
+       // LocalVariable[] localArrays= completion.findLocalArrays();
+       //              
+       // List ret= new ArrayList();
+       //              
+       // for (int i= 0; i < localArrays.length; i++) {
+       // int idx= localArrays.length - i - 1;
+       //                      
+       // LocalVariable var= localArrays[idx];
+       //                      
+       // IJavaProject project= cu.getJavaProject();
+       // String typeName= var.typeName;
+       // String baseTypeName= typeName.substring(0, typeName.lastIndexOf('['));
+       //
+       // String indexName= getIndex();
+       // String[] excludedNames= completion.getLocalVariableNames();
+       // if (indexName != null) {
+       // ArrayList excludedNamesList= new ArrayList(Arrays.asList(excludedNames));
+       // excludedNamesList.add(indexName);
+       // excludedNames= (String[])excludedNamesList.toArray(new
+       // String[excludedNamesList.size()]);
+       // }
+       // String[] proposals= NamingConventions.suggestLocalVariableNames(project,
+       // var.typePackageName, baseTypeName, 0, excludedNames);
+       // for (int j= 0; j < proposals.length; j++) {
+       // if (!ret.contains(proposals[j]))
+       // ret.add(proposals[j]);
+       // }
+       // }
+       //              
+       // return (String[]) ret.toArray(new String[ret.size()]);
+       // }
+       /**
+        * Returns a proposal for a variable name of a local array element,
+        * <code>null</code> if no local array exists.
+        */
+       // public String[][] guessGroupedArrayElements() {
+       // ICompilationUnit cu= getCompilationUnit();
+       // if (cu == null) {
+       // return new String[0][];
+       // }
+       //              
+       // CompilationUnitCompletion completion= getCompletion();
+       // LocalVariable[] localArrays= completion.findLocalArrays();
+       //              
+       // String[][] ret= new String[localArrays.length][];
+       //              
+       // for (int i= 0; i < localArrays.length; i++) {
+       // int idx= localArrays.length - i - 1;
+       //                      
+       // LocalVariable var= localArrays[idx];
+       //                      
+       // IJavaProject project= cu.getJavaProject();
+       // String typeName= var.typeName;
+       // int dim= -1; // we expect at least one array
+       // int lastIndex= typeName.length();
+       // int bracket= typeName.lastIndexOf('[');
+       // while (bracket != -1) {
+       // lastIndex= bracket;
+       // dim++;
+       // bracket= typeName.lastIndexOf('[', bracket - 1);
+       // }
+       // typeName= typeName.substring(0, lastIndex);
+       //                      
+       // String indexName= getIndex();
+       // String[] excludedNames= completion.getLocalVariableNames();
+       // if (indexName != null) {
+       // ArrayList excludedNamesList= new ArrayList(Arrays.asList(excludedNames));
+       // excludedNamesList.add(indexName);
+       // excludedNames= (String[])excludedNamesList.toArray(new
+       // String[excludedNamesList.size()]);
+       // }
+       // String[] proposals= NamingConventions.suggestLocalVariableNames(project,
+       // var.typePackageName, typeName, dim, excludedNames);
+       //                      
+       // ret[i]= proposals;
+       // }
+       //              
+       // return ret;
+       // }
+       /**
+        * Returns an array index name. 'i', 'j', 'k' are tried until no name
+        * collision with an existing local variable occurs. If all names collide,
+        * <code>null</code> is returned.
+        */
+       // public String getIndex() {
+       // CompilationUnitCompletion completion= getCompletion();
+       // String[] proposals= {"i", "j", "k"}; //$NON-NLS-1$ //$NON-NLS-2$
+       // //$NON-NLS-3$
+       //              
+       // for (int i= 0; i != proposals.length; i++) {
+       // String proposal = proposals[i];
+       //
+       // if (!completion.existsLocalName(proposal))
+       // return proposal;
+       // }
+       //
+       // return null;
+       // }
+       /**
+        * Returns the name of a local collection, <code>null</code> if no local
+        * collection exists.
+        */
+       // public String guessCollection() {
+       // return firstOrNull(guessCollections());
+       // }
+       /**
+        * Returns the names of local collections.
+        */
+       // public String[] guessCollections() {
+       // CompilationUnitCompletion completion= getCompletion();
+       // try {
+       // LocalVariable[] localCollections= completion.findLocalCollections();
+       // String[] ret= new String[localCollections.length];
+       // for (int i= 0; i < ret.length; i++) {
+       // ret[ret.length - i - 1]= localCollections[i].name;
+       // }
+       //                      
+       // return ret;
+       //
+       // } catch (JavaModelException e) {
+       // JavaPlugin.log(e);
+       // }
+       //
+       // return new String[0];
+       // }
+       /**
+        * Returns an iterator name ('iter'). If 'iter' already exists as local
+        * variable, <code>null</code> is returned.
+        */
+       // public String getIterator() {
+       // CompilationUnitCompletion completion= getCompletion();
+       // String[] proposals= {"iter"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+       //              
+       // for (int i= 0; i != proposals.length; i++) {
+       // String proposal = proposals[i];
+       //
+       // if (!completion.existsLocalName(proposal))
+       // return proposal;
+       // }
+       //
+       // return null;
+       // }
+       // public void addIteratorImport() {
+       // ICompilationUnit cu= getCompilationUnit();
+       // if (cu == null) {
+       // return;
+       // }
+       //      
+       // try {
+       // Position position= new Position(getCompletionOffset(),
+       // getCompletionLength());
+       // IDocument document= getDocument();
+       // final String category= "__template_position_importer" +
+       // System.currentTimeMillis(); //$NON-NLS-1$
+       // IPositionUpdater updater= new DefaultPositionUpdater(category);
+       // document.addPositionCategory(category);
+       // document.addPositionUpdater(updater);
+       // document.addPosition(position);
+       //
+       // CodeGenerationSettings settings=
+       // JavaPreferencesSettings.getCodeGenerationSettings();
+       // ImportsStructure structure= new ImportsStructure(cu,
+       // settings.importOrder, settings.importThreshold, true);
+       // structure.addImport("java.util.Iterator"); //$NON-NLS-1$
+       // structure.create(false, null);
+       //
+       // document.removePosition(position);
+       // document.removePositionUpdater(updater);
+       // document.removePositionCategory(category);
+       //                      
+       // setCompletionOffset(position.getOffset());
+       // setCompletionLength(position.getLength());
+       //                      
+       // } catch (CoreException e) {
+       // handleException(null, e);
+       // } catch (BadLocationException e) {
+       // handleException(null, e);
+       // } catch (BadPositionCategoryException e) {
+       // handleException(null, e);
+       // }
+       // }
+       /**
+        * Evaluates a 'java' template in thecontext of a compilation unit
+        */
+       public static String evaluateTemplate(Template template,
+                       ICompilationUnit compilationUnit, int position)
+                       throws CoreException, BadLocationException, TemplateException {
+
+               TemplateContextType contextType = WebUI.getDefault()
+                               .getTemplateContextRegistry().getContextType("java"); //$NON-NLS-1$
+               if (contextType == null)
+                       throw new CoreException(
+                                       new Status(
+                                                       IStatus.ERROR,
+                                                       PHPeclipsePlugin.PLUGIN_ID,
+                                                       IStatus.ERROR,
+                                                       JavaTemplateMessages
+                                                                       .getString("JavaContext.error.message"), null)); //$NON-NLS-1$
+
+               IDocument document = new Document();
+               if (compilationUnit != null && compilationUnit.exists())
+                       document.set(compilationUnit.getSource());
+
+               JavaContext context = new JavaContext(contextType, document, position,
+                               0, compilationUnit);
+               context.setForceEvaluation(true);
+
+               TemplateBuffer buffer = context.evaluate(template);
+               if (buffer == null)
+                       return null;
+               return buffer.getString();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContextType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContextType.java
new file mode 100644 (file)
index 0000000..f121bdf
--- /dev/null
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 2000, orporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sebastian Davids: sdavids@gmx.de - see bug 25376
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+
+/**
+ * A context type for java code.
+ */
+public class JavaContextType extends CompilationUnitContextType {
+
+       public static final String NAME = "php"; //$NON-NLS-1$
+
+       // protected static class Array extends TemplateVariableResolver {
+       // public Array() {
+       // super("array",
+       // TemplateMessages.getString("JavaContextType.variable.description.array"));
+       // //$NON-NLS-1$ //$NON-NLS-2$
+       // }
+       // protected String[] resolveAll(TemplateContext context) {
+       // return ((JavaContext) context).guessArrays();
+       // }
+       // /*
+       // * @see
+       // org.eclipse.jface.text.templates.TemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateVariable,
+       // org.eclipse.jface.text.templates.TemplateContext)
+       // */
+       // public void resolve(TemplateVariable variable, TemplateContext context) {
+       // if (variable instanceof MultiVariable) {
+       // JavaContext jc= (JavaContext) context;
+       // MultiVariable mv= (MultiVariable) variable;
+       // String[] bindings= resolveAll(context);
+       // if (bindings.length > 0) {
+       // mv.setValues(bindings);
+       // MultiVariableGuess guess= jc.getMultiVariableGuess();
+       // if (guess == null) {
+       // guess= new MultiVariableGuess(mv);
+       // jc.setMultiVariableGuess(guess);
+       // }
+       // }
+       // if (bindings.length > 1)
+       // variable.setUnambiguous(false);
+       // else
+       // variable.setUnambiguous(isUnambiguous(context));
+       // } else
+       // super.resolve(variable, context);
+       // }
+       // }
+       //
+       // protected static class ArrayType extends TemplateVariableResolver {
+       // public ArrayType() {
+       // super("array_type",
+       // TemplateMessages.getString("JavaContextType.variable.description.array.type"));
+       // //$NON-NLS-1$ //$NON-NLS-2$
+       // }
+       // protected String[] resolveAll(TemplateContext context) {
+       //              
+       // String[] arrayTypes= ((JavaContext) context).guessArrayTypes();
+       // if (arrayTypes != null)
+       // return arrayTypes;
+       // else
+       // return super.resolveAll(context);
+       // }
+       //          
+       // /*
+       // * @see
+       // org.eclipse.jface.text.templates.TemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateVariable,
+       // org.eclipse.jface.text.templates.TemplateContext)
+       // */
+       // public void resolve(TemplateVariable variable, TemplateContext context) {
+       // if (variable instanceof MultiVariable) {
+       // MultiVariable mv= (MultiVariable) variable;
+       // String[] arrays= ((JavaContext) context).guessArrays();
+       // String[][] types= ((JavaContext) context).guessGroupedArrayTypes();
+       //                              
+       // for (int i= 0; i < arrays.length; i++) {
+       // mv.setValues(arrays[i], types[i]);
+       // }
+       //
+       // if (arrays.length > 1 || types.length == 1 && types[0].length > 1)
+       // variable.setUnambiguous(false);
+       // else
+       // variable.setUnambiguous(isUnambiguous(context));
+       //                              
+       // } else
+       // super.resolve(variable, context);
+       // }
+       // }
+       //
+       // protected static class ArrayElement extends TemplateVariableResolver {
+       // public ArrayElement() {
+       // super("array_element",
+       // TemplateMessages.getString("JavaContextType.variable.description.array.element"));
+       // //$NON-NLS-1$ //$NON-NLS-2$
+       // }
+       // protected String[] resolveAll(TemplateContext context) {
+       // return ((JavaContext) context).guessArrayElements();
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.jface.text.templates.TemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateVariable,
+       // org.eclipse.jface.text.templates.TemplateContext)
+       // */
+       // public void resolve(TemplateVariable variable, TemplateContext context) {
+       // if (variable instanceof MultiVariable) {
+       // MultiVariable mv= (MultiVariable) variable;
+       // String[] arrays= ((JavaContext) context).guessArrays();
+       // String[][] elems= ((JavaContext) context).guessGroupedArrayElements();
+       //                              
+       // for (int i= 0; i < arrays.length; i++) {
+       // mv.setValues(arrays[i], elems[i]);
+       // }
+       //
+       // if (arrays.length > 1 || elems.length == 1 && elems[0].length > 1)
+       // variable.setUnambiguous(false);
+       // else
+       // variable.setUnambiguous(isUnambiguous(context));
+       //                              
+       // } else
+       // super.resolve(variable, context);
+       // }
+       // }
+       //
+       // protected static class Index extends TemplateVariableResolver {
+       // public Index() {
+       // super("index",
+       // TemplateMessages.getString("JavaContextType.variable.description.index"));
+       // //$NON-NLS-1$ //$NON-NLS-2$
+       // }
+       // protected String resolve(TemplateContext context) {
+       // return ((JavaContext) context).getIndex();
+       // }
+       // }
+       //
+       // protected static class Collection extends TemplateVariableResolver {
+       // public Collection() {
+       // super("collection",
+       // TemplateMessages.getString("JavaContextType.variable.description.collection"));
+       // //$NON-NLS-1$ //$NON-NLS-2$
+       // }
+       //          
+       // protected String[] resolveAll(TemplateContext context) {
+       // String[] collections= ((JavaContext) context).guessCollections();
+       // if (collections.length > 0)
+       // return collections;
+       // else
+       // return super.resolveAll(context);
+       // }
+       // }
+       //
+       // protected static class Iterator extends TemplateVariableResolver {
+       //
+       // public Iterator() {
+       // super("iterator",
+       // TemplateMessages.getString("JavaContextType.variable.description.iterator"));
+       // //$NON-NLS-1$ //$NON-NLS-2$
+       // }
+       // protected String resolve(TemplateContext context) {
+       // JavaContext javaContext= (JavaContext) context;
+       //
+       // if (!context.isReadOnly())
+       // javaContext.addIteratorImport();
+       //              
+       // return javaContext.getIterator();
+       // }
+       // }
+       //      
+       protected static class Todo extends TemplateVariableResolver {
+
+               public Todo() {
+                       super(
+                                       "todo", JavaTemplateMessages.getString("JavaContextType.variable.description.todo")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+
+               protected String resolve(TemplateContext context) {
+                       JavaContext javaContext = (JavaContext) context;
+                       ICompilationUnit compilationUnit = javaContext.getCompilationUnit();
+                       if (compilationUnit == null)
+                               return "XXX"; //$NON-NLS-1$
+
+                       IJavaProject javaProject = compilationUnit.getJavaProject();
+                       String todoTaskTag = StubUtility.getTodoTaskTag(javaProject);
+                       if (todoTaskTag == null)
+                               return "XXX"; //$NON-NLS-1$
+
+                       return todoTaskTag;
+               }
+       }
+
+       /*
+        * protected static class Arguments extends SimpleVariableResolver { public
+        * Arguments() { super("arguments",
+        * TemplateMessages.getString("JavaContextType.variable.description.arguments"),
+        * ""); } }
+        */
+
+       /**
+        * Creates a java context type.
+        */
+       public JavaContextType() {
+               super(NAME);
+
+               // global
+               addResolver(new GlobalTemplateVariables.Cursor());
+               addResolver(new GlobalTemplateVariables.WordSelection());
+               addResolver(new GlobalTemplateVariables.LineSelection());
+               addResolver(new GlobalTemplateVariables.Dollar());
+               addResolver(new GlobalTemplateVariables.Date());
+               addResolver(new GlobalTemplateVariables.Year());
+               addResolver(new GlobalTemplateVariables.Time());
+               addResolver(new GlobalTemplateVariables.User());
+
+               // compilation unit
+               addResolver(new File());
+               addResolver(new PrimaryTypeName());
+               addResolver(new ReturnType());
+               addResolver(new Method());
+               addResolver(new Type());
+               addResolver(new Package());
+               addResolver(new Project());
+               addResolver(new Arguments());
+
+               // java
+               // addResolver(new Array());
+               // addResolver(new ArrayType());
+               // addResolver(new ArrayElement());
+               // addResolver(new Index());
+               // addResolver(new Iterator());
+               // addResolver(new Collection());
+               addResolver(new Todo());
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContextType#createContext(org.eclipse.jface.text.IDocument,
+        *      int, int, net.sourceforge.phpdt.core.ICompilationUnit)
+        */
+       public CompilationUnitContext createContext(IDocument document, int offset,
+                       int length, ICompilationUnit compilationUnit) {
+               return new JavaContext(this, document, offset, length, compilationUnit);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaDocContext.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaDocContext.java
new file mode 100644 (file)
index 0000000..9377103
--- /dev/null
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateTranslator;
+
+/**
+ * A context for javadoc.
+ */
+public class JavaDocContext extends CompilationUnitContext {
+
+       // tags
+       private static final char HTML_TAG_BEGIN = '<';
+
+       private static final char HTML_TAG_END = '>';
+
+       private static final char JAVADOC_TAG_BEGIN = '@';
+
+       /**
+        * Creates a javadoc template context.
+        * 
+        * @param type
+        *            the context type.
+        * @param document
+        *            the document.
+        * @param completionOffset
+        *            the completion offset within the document.
+        * @param completionLength
+        *            the completion length within the document.
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>).
+        */
+       public JavaDocContext(TemplateContextType type, IDocument document,
+                       int completionOffset, int completionLength,
+                       ICompilationUnit compilationUnit) {
+               super(type, document, completionOffset, completionLength,
+                               compilationUnit);
+       }
+
+       /*
+        * @see TemplateContext#canEvaluate(Template templates)
+        */
+       public boolean canEvaluate(Template template) {
+               String key = getKey();
+
+               if (fForceEvaluation)
+                       return true;
+
+               return template.matches(key, getContextType().getId())
+                               && (key.length() != 0)
+                               && template.getName().toLowerCase().startsWith(
+                                               key.toLowerCase());
+       }
+
+       /*
+        * @see DocumentTemplateContext#getStart()
+        */
+       public int getStart() {
+               try {
+                       IDocument document = getDocument();
+
+                       if (getCompletionLength() == 0) {
+                               int start = getCompletionOffset();
+
+                               if ((start != 0)
+                                               && (document.getChar(start - 1) == HTML_TAG_END))
+                                       start--;
+
+                               while ((start != 0)
+                                               && Character.isUnicodeIdentifierPart(document
+                                                               .getChar(start - 1)))
+                                       start--;
+
+                               if ((start != 0)
+                                               && Character.isUnicodeIdentifierStart(document
+                                                               .getChar(start - 1)))
+                                       start--;
+
+                               // include html and javadoc tags
+                               if ((start != 0)
+                                               && ((document.getChar(start - 1) == HTML_TAG_BEGIN) || (document
+                                                               .getChar(start - 1) == JAVADOC_TAG_BEGIN))) {
+                                       start--;
+                               }
+
+                               return start;
+
+                       } else {
+
+                               int start = getCompletionOffset();
+                               int end = getCompletionOffset() + getCompletionLength();
+
+                               while (start != 0
+                                               && Character.isUnicodeIdentifierPart(document
+                                                               .getChar(start - 1)))
+                                       start--;
+
+                               while (start != end
+                                               && Character.isWhitespace(document.getChar(start)))
+                                       start++;
+
+                               if (start == end)
+                                       start = getCompletionOffset();
+
+                               return start;
+                       }
+
+               } catch (BadLocationException e) {
+                       return getCompletionOffset();
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext#getEnd()
+        */
+       public int getEnd() {
+
+               if (getCompletionLength() == 0)
+                       return super.getEnd();
+
+               try {
+                       IDocument document = getDocument();
+
+                       int start = getCompletionOffset();
+                       int end = getCompletionOffset() + getCompletionLength();
+
+                       while (start != end
+                                       && Character.isWhitespace(document.getChar(end - 1)))
+                               end--;
+
+                       return end;
+
+               } catch (BadLocationException e) {
+                       return super.getEnd();
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext#getKey()
+        */
+       public String getKey() {
+
+               if (getCompletionLength() == 0)
+                       return super.getKey();
+
+               try {
+                       IDocument document = getDocument();
+
+                       int start = getStart();
+                       int end = getCompletionOffset();
+                       return start <= end ? document.get(start, end - start) : ""; //$NON-NLS-1$
+
+               } catch (BadLocationException e) {
+                       return super.getKey();
+               }
+       }
+
+       /*
+        * @see TemplateContext#evaluate(Template)
+        */
+       public TemplateBuffer evaluate(Template template)
+                       throws BadLocationException, TemplateException {
+               TemplateTranslator translator = new TemplateTranslator();
+               TemplateBuffer buffer = translator.translate(template);
+
+               getContextType().resolve(buffer, this);
+
+               return buffer;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaDocContextType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaDocContextType.java
new file mode 100644 (file)
index 0000000..e41fcc8
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+
+/**
+ * A context type for javadoc.
+ */
+public class JavaDocContextType extends CompilationUnitContextType {
+
+       public static final String NAME = "phpdoc"; //$NON-NLS-1$
+
+       /**
+        * Creates a java context type.
+        */
+       public JavaDocContextType() {
+               super(NAME);
+
+               // global
+               addResolver(new GlobalTemplateVariables.Cursor());
+               addResolver(new GlobalTemplateVariables.LineSelection());
+               addResolver(new GlobalTemplateVariables.WordSelection());
+               addResolver(new GlobalTemplateVariables.Dollar());
+               addResolver(new GlobalTemplateVariables.Date());
+               addResolver(new GlobalTemplateVariables.Year());
+               addResolver(new GlobalTemplateVariables.Time());
+               addResolver(new GlobalTemplateVariables.User());
+
+               // compilation unit
+               addResolver(new File());
+               addResolver(new PrimaryTypeName());
+               addResolver(new Method());
+               addResolver(new ReturnType());
+               addResolver(new Arguments());
+               addResolver(new Type());
+               addResolver(new Package());
+               addResolver(new Project());
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContextType#createContext(org.eclipse.jface.text.IDocument,
+        *      int, int, net.sourceforge.phpdt.core.ICompilationUnit)
+        */
+       public CompilationUnitContext createContext(IDocument document, int offset,
+                       int length, ICompilationUnit compilationUnit) {
+               return new JavaDocContext(this, document, offset, length,
+                               compilationUnit);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaFormatter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaFormatter.java
new file mode 100644 (file)
index 0000000..1c815b7
--- /dev/null
@@ -0,0 +1,393 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.corext.util.CodeFormatterUtil;
+import net.sourceforge.phpdt.internal.corext.util.Strings;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner;
+import net.sourceforge.phpdt.internal.ui.text.JavaIndenter;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.templates.DocumentTemplateContext;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.RangeMarker;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * A template editor using the Java formatter to format a template buffer.
+ */
+public class JavaFormatter {
+
+       private static final String MARKER = "/*${" + GlobalTemplateVariables.Cursor.NAME + "}*/"; //$NON-NLS-1$ //$NON-NLS-2$
+
+       /** The line delimiter to use if code formatter is not used. */
+       private final String fLineDelimiter;
+
+       /** The initial indent level */
+       private final int fInitialIndentLevel;
+
+       /** The java partitioner */
+       private boolean fUseCodeFormatter;
+
+       /**
+        * Creates a JavaFormatter with the target line delimiter.
+        * 
+        * @param lineDelimiter
+        *            the line delimiter to use
+        * @param initialIndentLevel
+        *            the initial indentation level
+        * @param useCodeFormatter
+        *            <code>true</code> if the core code formatter should be used
+        */
+       public JavaFormatter(String lineDelimiter, int initialIndentLevel,
+                       boolean useCodeFormatter) {
+               fLineDelimiter = lineDelimiter;
+               fUseCodeFormatter = useCodeFormatter;
+               fInitialIndentLevel = initialIndentLevel;
+       }
+
+       /**
+        * Formats the template buffer.
+        * 
+        * @param buffer
+        * @param context
+        * @throws BadLocationException
+        */
+       public void format(TemplateBuffer buffer, TemplateContext context)
+                       throws BadLocationException {
+               try {
+                       if (fUseCodeFormatter)
+                               // try to format and fall back to indenting
+                               try {
+                                       format(buffer, (JavaContext) context);
+                               } catch (BadLocationException e) {
+                                       indent(buffer);
+                               } catch (MalformedTreeException e) {
+                                       indent(buffer);
+                               }
+                       else
+                               indent(buffer);
+
+                       // don't trim the buffer if the replacement area is empty
+                       // case: surrounding empty lines with block
+                       if (context instanceof DocumentTemplateContext) {
+                               DocumentTemplateContext dtc = (DocumentTemplateContext) context;
+                               if (dtc.getStart() == dtc.getCompletionOffset())
+                                       if (dtc.getDocument().get(dtc.getStart(),
+                                                       dtc.getEnd() - dtc.getEnd()).trim().length() == 0)
+                                               return;
+                       }
+
+                       trimBegin(buffer);
+               } catch (MalformedTreeException e) {
+                       throw new BadLocationException();
+               }
+       }
+
+       private static int getCaretOffset(TemplateVariable[] variables) {
+               for (int i = 0; i != variables.length; i++) {
+                       TemplateVariable variable = variables[i];
+
+                       if (variable.getType().equals(GlobalTemplateVariables.Cursor.NAME))
+                               return variable.getOffsets()[0];
+               }
+
+               return -1;
+       }
+
+       private boolean isInsideCommentOrString(String string, int offset) {
+
+               IDocument document = new Document(string);
+               WebUI.getDefault().getJavaTextTools()
+                               .setupJavaDocumentPartitioner(document);
+
+               try {
+                       ITypedRegion partition = document.getPartition(offset);
+                       String partitionType = partition.getType();
+
+                       return partitionType != null
+                                       && (partitionType
+                                                       .equals(IPHPPartitions.PHP_MULTILINE_COMMENT)
+                                                       || partitionType
+                                                                       .equals(IPHPPartitions.PHP_SINGLELINE_COMMENT)
+                                                       || partitionType
+                                                                       .equals(IPHPPartitions.PHP_STRING_DQ)
+                                                       || partitionType
+                                                                       .equals(IPHPPartitions.PHP_STRING_SQ)
+                                                       || partitionType
+                                                                       .equals(IPHPPartitions.PHP_STRING_HEREDOC) || partitionType
+                                                       .equals(IPHPPartitions.PHP_PHPDOC_COMMENT));
+
+               } catch (BadLocationException e) {
+                       return false;
+               }
+       }
+
+       private void format(TemplateBuffer templateBuffer, JavaContext context)
+                       throws BadLocationException {
+               // XXX 4360, 15247
+               // workaround for code formatter limitations
+               // handle a special case where cursor position is surrounded by
+               // whitespaces
+
+               String string = templateBuffer.getString();
+               TemplateVariable[] variables = templateBuffer.getVariables();
+
+               int caretOffset = getCaretOffset(variables);
+               if ((caretOffset > 0)
+                               && Character.isWhitespace(string.charAt(caretOffset - 1))
+                               && (caretOffset < string.length())
+                               && Character.isWhitespace(string.charAt(caretOffset))
+                               && !isInsideCommentOrString(string, caretOffset)) {
+                       List positions = variablesToPositions(variables);
+
+                       TextEdit insert = new InsertEdit(caretOffset, MARKER);
+                       string = edit(string, positions, insert);
+                       positionsToVariables(positions, variables);
+                       templateBuffer.setContent(string, variables);
+
+                       plainFormat(templateBuffer, context);
+
+                       string = templateBuffer.getString();
+                       variables = templateBuffer.getVariables();
+                       caretOffset = getCaretOffset(variables);
+
+                       positions = variablesToPositions(variables);
+                       TextEdit delete = new DeleteEdit(caretOffset, MARKER.length());
+                       string = edit(string, positions, delete);
+                       positionsToVariables(positions, variables);
+                       templateBuffer.setContent(string, variables);
+
+               } else {
+                       plainFormat(templateBuffer, context);
+               }
+       }
+
+       private void plainFormat(TemplateBuffer templateBuffer, JavaContext context)
+                       throws BadLocationException {
+       }
+
+       // private void plainFormat(TemplateBuffer templateBuffer, JavaContext
+       // context) throws BadLocationException {
+       //
+       // IDocument doc= new Document(templateBuffer.getString());
+       //
+       // TemplateVariable[] variables= templateBuffer.getVariables();
+       //
+       // List offsets= variablesToPositions(variables);
+       //
+       // Map options;
+       // if (context.getCompilationUnit() != null)
+       // options= context.getCompilationUnit().getJavaProject().getOptions(true);
+       // else
+       // options= JavaCore.getOptions();
+       //
+       // TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_UNKNOWN,
+       // doc.get(), fInitialIndentLevel, fLineDelimiter, options);
+       // if (edit == null)
+       // throw new BadLocationException(); // fall back to indenting
+       //
+       // MultiTextEdit root;
+       // if (edit instanceof MultiTextEdit)
+       // root= (MultiTextEdit) edit;
+       // else {
+       // root= new MultiTextEdit(0, doc.getLength());
+       // root.addChild(edit);
+       // }
+       // for (Iterator it= offsets.iterator(); it.hasNext();) {
+       // TextEdit position= (TextEdit) it.next();
+       // try {
+       // root.addChild(position);
+       // } catch (MalformedTreeException e) {
+       // // position conflicts with formatter edit
+       // // ignore this position
+       // }
+       // }
+       //
+       // root.apply(doc, TextEdit.UPDATE_REGIONS);
+       //
+       // positionsToVariables(offsets, variables);
+       //
+       // templateBuffer.setContent(doc.get(), variables);
+       // }
+
+       private void indent(TemplateBuffer templateBuffer)
+                       throws BadLocationException, MalformedTreeException {
+
+               TemplateVariable[] variables = templateBuffer.getVariables();
+               List positions = variablesToPositions(variables);
+
+               IDocument document = new Document(templateBuffer.getString());
+               MultiTextEdit root = new MultiTextEdit(0, document.getLength());
+               root.addChildren((TextEdit[]) positions.toArray(new TextEdit[positions
+                               .size()]));
+
+               JavaHeuristicScanner scanner = new JavaHeuristicScanner(document);
+               JavaIndenter indenter = new JavaIndenter(document, scanner);
+
+               // first line
+               int offset = document.getLineOffset(0);
+               TextEdit edit = new InsertEdit(offset, CodeFormatterUtil
+                               .createIndentString(fInitialIndentLevel));
+               root.addChild(edit);
+               root.apply(document, TextEdit.UPDATE_REGIONS);
+               root.removeChild(edit);
+
+               formatDelimiter(document, root, 0);
+
+               // following lines
+               int lineCount = document.getNumberOfLines();
+
+               for (int line = 1; line < lineCount; line++) {
+                       IRegion region = document.getLineInformation(line);
+                       offset = region.getOffset();
+                       StringBuffer indent = indenter.computeIndentation(offset);
+                       if (indent == null)
+                               continue;
+                       // axelcl delete start
+                       // int nonWS =
+                       // scanner.findNonWhitespaceForwardInAnyPartition(offset, offset +
+                       // region.getLength());
+                       // if (nonWS == JavaHeuristicScanner.NOT_FOUND)
+                       // continue;
+                       // edit = new ReplaceEdit(offset, nonWS - offset,
+                       // indent.toString());
+                       // axelcl delete end
+                       // axelcl insert start
+                       int nonWS = offset;
+                       edit = new ReplaceEdit(offset, nonWS - offset, CodeFormatterUtil
+                                       .createIndentString(fInitialIndentLevel));
+                       // axelcl insert end
+                       root.addChild(edit);
+                       root.apply(document, TextEdit.UPDATE_REGIONS);
+                       root.removeChild(edit);
+
+                       formatDelimiter(document, root, line);
+               }
+
+               positionsToVariables(positions, variables);
+               templateBuffer.setContent(document.get(), variables);
+       }
+
+       /**
+        * Changes the delimiter to the configured line delimiter.
+        * 
+        * @param document
+        *            the temporary document being edited
+        * @param root
+        *            the root edit containing all positions that will be updated
+        *            along the way
+        * @param line
+        *            the line to format
+        * @throws BadLocationException
+        *             if applying the changes fails
+        */
+       private void formatDelimiter(IDocument document, MultiTextEdit root,
+                       int line) throws BadLocationException {
+               IRegion region = document.getLineInformation(line);
+               String lineDelimiter = document.getLineDelimiter(line);
+               if (lineDelimiter != null) {
+                       TextEdit edit = new ReplaceEdit(region.getOffset()
+                                       + region.getLength(), lineDelimiter.length(),
+                                       fLineDelimiter);
+                       root.addChild(edit);
+                       root.apply(document, TextEdit.UPDATE_REGIONS);
+                       root.removeChild(edit);
+               }
+       }
+
+       private static void trimBegin(TemplateBuffer templateBuffer)
+                       throws BadLocationException {
+               String string = templateBuffer.getString();
+               TemplateVariable[] variables = templateBuffer.getVariables();
+
+               List positions = variablesToPositions(variables);
+
+               int i = 0;
+               while ((i != string.length())
+                               && Character.isWhitespace(string.charAt(i)))
+                       i++;
+
+               string = edit(string, positions, new DeleteEdit(0, i));
+               positionsToVariables(positions, variables);
+
+               templateBuffer.setContent(string, variables);
+       }
+
+       private static String edit(String string, List positions, TextEdit edit)
+                       throws BadLocationException {
+               MultiTextEdit root = new MultiTextEdit(0, string.length());
+               root.addChildren((TextEdit[]) positions.toArray(new TextEdit[positions
+                               .size()]));
+               root.addChild(edit);
+               IDocument document = new Document(string);
+               root.apply(document);
+
+               return document.get();
+       }
+
+       private static List variablesToPositions(TemplateVariable[] variables) {
+               List positions = new ArrayList(5);
+               for (int i = 0; i != variables.length; i++) {
+                       int[] offsets = variables[i].getOffsets();
+
+                       // trim positions off whitespace
+                       String value = variables[i].getDefaultValue();
+                       int wsStart = 0;
+                       while (wsStart < value.length()
+                                       && Character.isWhitespace(value.charAt(wsStart))
+                                       && !Strings.isLineDelimiterChar(value.charAt(wsStart)))
+                               wsStart++;
+
+                       variables[i].getValues()[0] = value.substring(wsStart);
+
+                       for (int j = 0; j != offsets.length; j++) {
+                               offsets[j] += wsStart;
+                               positions.add(new RangeMarker(offsets[j], 0));
+                       }
+               }
+               return positions;
+       }
+
+       private static void positionsToVariables(List positions,
+                       TemplateVariable[] variables) {
+               Iterator iterator = positions.iterator();
+
+               for (int i = 0; i != variables.length; i++) {
+                       TemplateVariable variable = variables[i];
+
+                       int[] offsets = new int[variable.getOffsets().length];
+                       for (int j = 0; j != offsets.length; j++)
+                               offsets[j] = ((TextEdit) iterator.next()).getOffset();
+
+                       variable.setOffsets(offsets);
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaTemplateMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaTemplateMessages.java
new file mode 100644 (file)
index 0000000..7756536
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+class JavaTemplateMessages {
+
+       private static final String RESOURCE_BUNDLE = JavaTemplateMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private JavaTemplateMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaTemplateMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/JavaTemplateMessages.properties
new file mode 100644 (file)
index 0000000..bf31395
--- /dev/null
@@ -0,0 +1,139 @@
+###############################################################################
+# Copyright (c) 2000, 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+ContextType.error.multiple.cursor.variables=Template has multiple cursor variables.
+
+Templates.for_array=iterate over array
+Templates.for_temp=iterate over array with temporary variable
+Templates.for_collection=iterate over collection
+Templates.while_enumeration=iterate with enumeration
+Templates.while_iterator=iterate with iterator
+Templates.do=do while statement
+Templates.switch=switch case statement
+Templates.if=if statement
+Templates.ifelse=if else statement
+Templates.elseif=else if block
+Templates.else=else block
+Templates.try=try catch block
+Templates.catch=catch block
+Templates.main=main method
+Templates.public_method=public method
+Templates.protected_method=protected method
+Templates.private_method=private method
+Templates.private_static_method=private static method
+Templates.instanceof=dynamic type test and cast
+Templates.cast=dynamic cast
+Templates.toarray=convert collection to array
+Templates.test=test method
+Templates.systrace=print current method to standard out
+Templates.sysout=print to standard out
+Templates.syserr=print to standard error
+Templates.code_tag=<code></code>
+Templates.code_tag_null=<code>null</code>
+Templates.pre_tag=<pre></pre>
+Templates.b_tag=<b></b>
+Templates.i_tag=<i></i>
+Templates.author=author name
+Templates.new=create new object
+Templates.lazy=lazy creation
+Templates.while_condition=while loop with condition
+
+# Java Only stuff
+CompilationUnitContextType.variable.description.file=Filename of compilation unit
+CompilationUnitContextType.variable.description.primary.type.name=Filename without extension
+CompilationUnitContextType.variable.description.enclosing.method=Enclosing method name
+CompilationUnitContextType.variable.description.enclosing.type=Enclosing type name
+CompilationUnitContextType.variable.description.enclosing.package=Enclosing package name
+CompilationUnitContextType.variable.description.enclosing.project=Enclosing project name
+CompilationUnitContextType.variable.description.enclosing.method.arguments=Argument names of enclosing method
+CompilationUnitContextType.variable.description.return.type=Enclosing method return type
+
+JavaContextType.variable.description.array=A proposal for an array
+JavaContextType.variable.description.array.type=A proposal for the element type of an array
+JavaContextType.variable.description.array.element=A proposal for the element name of an array
+JavaContextType.variable.description.index=A proposal for an index (int)
+JavaContextType.variable.description.collection=A proposal for a collection (java.util.Collection)
+JavaContextType.variable.description.iterator=A proposal for an iterator (java.util.Iterator)
+JavaContextType.variable.description.todo=Todo task tag
+
+JavaContext.error.title=Template Error
+JavaContext.error.message=Template file incomplete or has errors.  You can load the default templates from the template preferences page (Java>Templates).
+
+CodeTemplateContextType.variable.description.todo=Todo task tag
+CodeTemplateContextType.variable.description.packdeclaration=Package declaration of the new type
+CodeTemplateContextType.variable.description.typedeclaration=Generated type declaration
+CodeTemplateContextType.variable.description.getterfieldname=The name of field to set or get
+CodeTemplateContextType.variable.description.getterfieldtype=The type of the field to set or get
+CodeTemplateContextType.variable.description.fieldname=The name of field
+CodeTemplateContextType.variable.description.fieldtype=The type of the field
+CodeTemplateContextType.variable.description.barefieldname=The name of field to set or get without pre- or suffix
+CodeTemplateContextType.variable.description.param=The parameter passed into the setter method
+CodeTemplateContextType.variable.description.typecomment=Content of code template 'typecomment'
+CodeTemplateContextType.variable.description.exceptiontype=The type of the caught exception
+CodeTemplateContextType.variable.description.exceptionvar=The variable name of the caught exception
+CodeTemplateContextType.variable.description.enclosingtype=The type enclosing this method
+CodeTemplateContextType.variable.description.typename=Name of the current type
+CodeTemplateContextType.variable.description.enclosingmethod=The enclosing method
+CodeTemplateContextType.variable.description.bodystatement=Return statement or super call
+CodeTemplateContextType.variable.description.returntype=Return type of the enclosing method
+CodeTemplateContextType.variable.description.tags=Generated Javadoc tags (@param, @return...)
+CodeTemplateContextType.variable.description.seetag=See tag pointing to the overridden method (@see T#m())
+
+CodeTemplateContextType.variable.description.filename=Name of the enclosing compilation unit
+CodeTemplateContextType.variable.description.packagename=Name of the enclosing package
+CodeTemplateContextType.variable.description.projectname=Name of the enclosing project
+
+CodeTemplateContextType.validate.unknownvariable=Variable ''{0}'' is unknown.
+CodeTemplateContextType.validate.missingvariable=Variable ''{0}'' is required.
+CodeTemplateContextType.validate.invalidcomment=Pattern is not a valid Java comment.
+
+
+
+CodeTemplates.error.title=Error accessing code templates.
+
+# strings in default templates
+CodeTemplates.constructorcomment=Comment for created constructors
+CodeTemplates.typecomment=Comment for created types
+CodeTemplates.fieldcomment=Comment for fields
+CodeTemplates.nonoverridingcomment=Comment for non-overriding methods
+CodeTemplates.overridecomment=Comment for overriding methods
+CodeTemplates.gettercomment=Comment for getter method
+# ! Do not translate ${bare_field_name} !
+CodeTemplates.gettercomment.returntagcontent=Returns the ${bare_field_name}.
+CodeTemplates.settercomment=Comment for setter method
+# ! Do not translate ${bare_field_name} !
+CodeTemplates.settercomment.paramtagcontent=The ${bare_field_name} to set.
+
+CodeTemplates.newfile=Newly created files
+CodeTemplates.catchblock=Code in new catch blocks
+CodeTemplates.methodstub=Code in created method stubs
+CodeTemplates.constructorstub=Code in created constructor stubs
+CodeTemplates.getterstub=Code in created getters
+CodeTemplates.setterstub=Code in created setters
+
+# ! Do not translate @todo !
+CodeTemplates.typecomment.content1=To change the template for this generated type comment go to
+CodeTemplates.typecomment.content2=Window - Preferences - Java - Code Style - Code Templates
+
+# ! Do not translate ${field} !
+CodeTemplates.fieldcomment.content=Comment for <code>${field}</code>
+
+CodeTemplates.overridecomment.nonjd=(non-Javadoc)
+
+# ! Do not translate ${date} !
+CodeTemplates.newfile.content1=Created on ${date}
+CodeTemplates.newfile.content2=To change the template for this generated file go to
+CodeTemplates.newfile.content3=Window - Preferences - Java - Code Style - Code Templates
+
+CodeTemplates.catchblock.tododesc=Auto-generated catch block
+CodeTemplates.methodstub.tododesc=Auto-generated method stub
+CodeTemplates.constructorstub.tododesc=Auto-generated constructor stub
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/TemplateSet.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/TemplateSet.java
new file mode 100644 (file)
index 0000000..a0d83fa
--- /dev/null
@@ -0,0 +1,422 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.templates.ContextTypeRegistry;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * <code>TemplateSet</code> manages a collection of templates and makes them
+ * persistent.
+ * 
+ * @deprecated use TemplateStore instead
+ * @since 3.0
+ */
+public class TemplateSet {
+
+       private static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$
+
+       private static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$
+
+       private static final String CONTEXT_ATTRIBUTE = "context"; //$NON-NLS-1$
+
+       private List fTemplates = new ArrayList();
+
+       private String fTemplateTag;
+
+       private static final int TEMPLATE_PARSE_EXCEPTION = 10002;
+
+       private static final int TEMPLATE_IO_EXCEPTION = 10005;
+
+       private ContextTypeRegistry fRegistry;
+
+       public TemplateSet(String templateTag, ContextTypeRegistry registry) {
+               fTemplateTag = templateTag;
+               fRegistry = registry;
+       }
+
+       /**
+        * Convenience method for reading templates from a file.
+        * 
+        * @param file
+        * @param allowDuplicates
+        * @param bundle
+        * @see #addFromStream(InputStream, boolean, boolean, ResourceBundle)
+        * @throws CoreException
+        */
+       public void addFromFile(File file, boolean allowDuplicates,
+                       ResourceBundle bundle) throws CoreException {
+               InputStream stream = null;
+
+               try {
+                       stream = new FileInputStream(file);
+                       addFromStream(stream, allowDuplicates, false, bundle);
+
+               } catch (IOException e) {
+                       throwReadException(e);
+
+               } finally {
+                       try {
+                               if (stream != null)
+                                       stream.close();
+                       } catch (IOException e) {
+                       }
+               }
+       }
+
+       public String getTemplateTag() {
+               return fTemplateTag;
+       }
+
+       /**
+        * Reads templates from a XML stream and adds them to the templates
+        * 
+        * @param stream
+        * @param allowDuplicates
+        * @param bundle
+        * @param doTranslations
+        * @see #addFromStream(InputStream, boolean, boolean, ResourceBundle)
+        * @throws CoreException
+        */
+       public void addFromStream(InputStream stream, boolean allowDuplicates,
+                       boolean doTranslations, ResourceBundle bundle) throws CoreException {
+               try {
+                       DocumentBuilderFactory factory = DocumentBuilderFactory
+                                       .newInstance();
+                       DocumentBuilder parser = factory.newDocumentBuilder();
+                       Document document = parser.parse(new InputSource(stream));
+
+                       NodeList elements = document.getElementsByTagName(getTemplateTag());
+
+                       int count = elements.getLength();
+                       for (int i = 0; i != count; i++) {
+                               Node node = elements.item(i);
+                               NamedNodeMap attributes = node.getAttributes();
+
+                               if (attributes == null)
+                                       continue;
+
+                               String name = getAttributeValue(attributes, NAME_ATTRIBUTE);
+                               String description = getAttributeValue(attributes,
+                                               DESCRIPTION_ATTRIBUTE);
+                               if (name == null || description == null)
+                                       continue;
+
+                               if (doTranslations) {
+                                       description = translateString(description, bundle);
+                               }
+                               String context = getAttributeValue(attributes,
+                                               CONTEXT_ATTRIBUTE);
+
+                               if (name == null || description == null || context == null)
+                                       throw new SAXException(JavaTemplateMessages
+                                                       .getString("TemplateSet.error.missing.attribute")); //$NON-NLS-1$
+
+                               StringBuffer buffer = new StringBuffer();
+                               NodeList children = node.getChildNodes();
+                               for (int j = 0; j != children.getLength(); j++) {
+                                       String value = children.item(j).getNodeValue();
+                                       if (value != null)
+                                               buffer.append(value);
+                               }
+                               String pattern = buffer.toString().trim();
+                               if (doTranslations) {
+                                       pattern = translateString(pattern, bundle);
+                               }
+
+                               Template template = new Template(name, description, context,
+                                               pattern);
+
+                               String message = validateTemplate(template);
+                               if (message == null) {
+                                       if (!allowDuplicates) {
+                                               Template[] templates = getTemplates(name);
+                                               for (int k = 0; k < templates.length; k++) {
+                                                       remove(templates[k]);
+                                               }
+                                       }
+                                       add(template);
+                               } else {
+                                       throwReadException(null);
+                               }
+                       }
+               } catch (ParserConfigurationException e) {
+                       throwReadException(e);
+               } catch (IOException e) {
+                       throwReadException(e);
+               } catch (SAXException e) {
+                       throwReadException(e);
+               }
+       }
+
+       private String translateString(String str, ResourceBundle bundle) {
+               int idx = str.indexOf('%');
+               if (idx == -1) {
+                       return str;
+               }
+               StringBuffer buf = new StringBuffer();
+               int k = 0;
+               while (idx != -1) {
+                       buf.append(str.substring(k, idx));
+                       for (k = idx + 1; k < str.length()
+                                       && !Character.isWhitespace(str.charAt(k)); k++) {
+                               // loop
+                       }
+                       String key = str.substring(idx + 1, k);
+                       buf.append(getBundleString(key, bundle));
+                       idx = str.indexOf('%', k);
+               }
+               buf.append(str.substring(k));
+               return buf.toString();
+       }
+
+       private String getBundleString(String key, ResourceBundle bundle) {
+               if (bundle != null) {
+                       try {
+                               return bundle.getString(key);
+                       } catch (MissingResourceException e) {
+                               return '!' + key + '!';
+                       }
+               } else
+                       return JavaTemplateMessages.getString(key); // default messages
+       }
+
+       protected String validateTemplate(Template template) {
+               TemplateContextType type = fRegistry.getContextType(template
+                               .getContextTypeId());
+               if (type == null) {
+                       return "Unknown context type: " + template.getContextTypeId(); //$NON-NLS-1$
+               }
+               try {
+                       type.validate(template.getPattern());
+                       return null;
+               } catch (TemplateException e) {
+                       return e.getMessage();
+               }
+       }
+
+       private String getAttributeValue(NamedNodeMap attributes, String name) {
+               Node node = attributes.getNamedItem(name);
+
+               return node == null ? null : node.getNodeValue();
+       }
+
+       /**
+        * Convenience method for saving to a file.
+        * 
+        * @see #saveToStream(OutputStream)
+        */
+       public void saveToFile(File file) throws CoreException {
+               OutputStream stream = null;
+
+               try {
+                       stream = new FileOutputStream(file);
+                       saveToStream(stream);
+
+               } catch (IOException e) {
+                       throwWriteException(e);
+
+               } finally {
+                       try {
+                               if (stream != null)
+                                       stream.close();
+                       } catch (IOException e) {
+                       }
+               }
+       }
+
+       /**
+        * Saves the template set as XML.
+        */
+       public void saveToStream(OutputStream stream) throws CoreException {
+               try {
+                       DocumentBuilderFactory factory = DocumentBuilderFactory
+                                       .newInstance();
+                       DocumentBuilder builder = factory.newDocumentBuilder();
+                       Document document = builder.newDocument();
+
+                       Node root = document.createElement("templates"); //$NON-NLS-1$
+                       document.appendChild(root);
+
+                       for (int i = 0; i != fTemplates.size(); i++) {
+                               Template template = (Template) fTemplates.get(i);
+
+                               Node node = document.createElement(getTemplateTag());
+                               root.appendChild(node);
+
+                               NamedNodeMap attributes = node.getAttributes();
+
+                               Attr name = document.createAttribute(NAME_ATTRIBUTE);
+                               name.setValue(template.getName());
+                               attributes.setNamedItem(name);
+
+                               Attr description = document
+                                               .createAttribute(DESCRIPTION_ATTRIBUTE);
+                               description.setValue(template.getDescription());
+                               attributes.setNamedItem(description);
+
+                               Attr context = document.createAttribute(CONTEXT_ATTRIBUTE);
+                               context.setValue(template.getContextTypeId());
+                               attributes.setNamedItem(context);
+
+                               Text pattern = document.createTextNode(template.getPattern());
+                               node.appendChild(pattern);
+                       }
+
+                       Transformer transformer = TransformerFactory.newInstance()
+                                       .newTransformer();
+                       transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+                       transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+                       DOMSource source = new DOMSource(document);
+                       StreamResult result = new StreamResult(stream);
+
+                       transformer.transform(source, result);
+
+               } catch (ParserConfigurationException e) {
+                       throwWriteException(e);
+               } catch (TransformerException e) {
+                       throwWriteException(e);
+               }
+       }
+
+       private static void throwReadException(Throwable t) throws CoreException {
+               int code;
+               if (t instanceof SAXException)
+                       code = TEMPLATE_PARSE_EXCEPTION;
+               else
+                       code = TEMPLATE_IO_EXCEPTION;
+               // IStatus status= JavaUIStatus.createError(code,
+               // TemplateMessages.getString("TemplateSet.error.read"), t);
+               // //$NON-NLS-1$
+               // throw new JavaUIException(status);
+               throw new CoreException(
+                               new Status(
+                                               IStatus.ERROR,
+                                               "org.eclipse.jface.text", code, JavaTemplateMessages.getString("TemplateSet.error.read"), t)); //$NON-NLS-1$ //$NON-NLS-2$
+       }
+
+       private static void throwWriteException(Throwable t) throws CoreException {
+               // IStatus status=
+               // JavaUIStatus.createError(IJavaStatusConstants.TEMPLATE_IO_EXCEPTION,
+               // TemplateMessages.getString("TemplateSet.error.write"), t);
+               // //$NON-NLS-1$
+               // throw new JavaUIException(status);
+               throw new CoreException(
+                               new Status(
+                                               IStatus.ERROR,
+                                               "org.eclipse.jface.text", TEMPLATE_IO_EXCEPTION, JavaTemplateMessages.getString("TemplateSet.error.write"), t)); //$NON-NLS-1$ //$NON-NLS-2$
+       }
+
+       /**
+        * Adds a template to the set.
+        */
+       public void add(Template template) {
+               if (exists(template))
+                       return; // ignore duplicate
+
+               fTemplates.add(template);
+       }
+
+       private boolean exists(Template template) {
+               for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) {
+                       Template anotherTemplate = (Template) iterator.next();
+
+                       if (template.equals(anotherTemplate))
+                               return true;
+               }
+
+               return false;
+       }
+
+       /**
+        * Removes a template to the set.
+        */
+       public void remove(Template template) {
+               fTemplates.remove(template);
+       }
+
+       /**
+        * Empties the set.
+        */
+       public void clear() {
+               fTemplates.clear();
+       }
+
+       /**
+        * Returns all templates.
+        */
+       public Template[] getTemplates() {
+               return (Template[]) fTemplates.toArray(new Template[fTemplates.size()]);
+       }
+
+       /**
+        * Returns all templates with a given name.
+        */
+       public Template[] getTemplates(String name) {
+               ArrayList res = new ArrayList();
+               for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) {
+                       Template curr = (Template) iterator.next();
+                       if (curr.getName().equals(name)) {
+                               res.add(curr);
+                       }
+               }
+               return (Template[]) res.toArray(new Template[res.size()]);
+       }
+
+       /**
+        * Returns the first templates with the given name.
+        */
+       public Template getFirstTemplate(String name) {
+               for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) {
+                       Template curr = (Template) iterator.next();
+                       if (curr.getName().equals(name)) {
+                               return curr;
+                       }
+               }
+               return null;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/Templates.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/corext/template/php/Templates.java
new file mode 100644 (file)
index 0000000..b520985
--- /dev/null
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * <code>Templates</code> gives access to the available templates.
+ * 
+ * @deprecated As of 3.0, replaced by
+ *             {@link org.eclipse.jface.text.templates.persistence.TemplateStore}
+ */
+public class Templates extends
+               net.sourceforge.phpdt.internal.corext.template.php.TemplateSet {
+
+       private static final String DEFAULT_FILE = "default-templates.xml"; //$NON-NLS-1$
+
+       private static final String TEMPLATE_FILE = "templates.xml"; //$NON-NLS-1$
+
+       private static final ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(JavaTemplateMessages.class.getName());
+
+       /** Singleton. */
+       private static Templates fgTemplates;
+
+       /**
+        * Returns an instance of templates.
+        * 
+        * @deprecated As of 3.0, replaced by
+        *             {@link net.sourceforge.phpdt.internal.ui.JavaPlugin#getTemplateStore()}
+        */
+       public static Templates getInstance() {
+               if (fgTemplates == null)
+                       fgTemplates = new Templates();
+
+               return fgTemplates;
+       }
+
+       public Templates() {
+               super(
+                               "template", WebUI.getDefault().getTemplateContextRegistry()); //$NON-NLS-1$
+               create();
+       }
+
+       private void create() {
+
+               try {
+                       File templateFile = getTemplateFile();
+                       if (templateFile.exists()) {
+                               addFromFile(templateFile, true, fgResourceBundle);
+                       }
+
+               } catch (CoreException e) {
+                       PHPeclipsePlugin.log(e);
+                       clear();
+               }
+
+       }
+
+       /**
+        * Resets the template set.
+        */
+       public void reset() throws CoreException {
+               clear();
+               addFromFile(getTemplateFile(), true, fgResourceBundle);
+       }
+
+       /**
+        * Resets the template set with the default templates.
+        */
+       public void restoreDefaults() throws CoreException {
+               clear();
+               addFromStream(getDefaultsAsStream(), true, true, fgResourceBundle);
+       }
+
+       /**
+        * Saves the template set.
+        */
+       public void save() throws CoreException {
+               saveToFile(getTemplateFile());
+       }
+
+       private static InputStream getDefaultsAsStream() {
+               return Templates.class.getResourceAsStream(DEFAULT_FILE);
+       }
+
+       private static File getTemplateFile() {
+               IPath path = PHPeclipsePlugin.getDefault().getStateLocation();
+               path = path.append(TEMPLATE_FILE);
+
+               return path.toFile();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/IJavaHelpContextIds.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/IJavaHelpContextIds.java
new file mode 100644 (file)
index 0000000..7b6eaa6
--- /dev/null
@@ -0,0 +1,763 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+/**
+ * Help context ids for the Java UI.
+ * <p>
+ * This interface contains constants only; it is not intended to be implemented
+ * or extended.
+ * </p>
+ * 
+ */
+public interface IJavaHelpContextIds {
+       public static final String PREFIX = WebUI.PLUGIN_ID + '.';
+
+       // Actions
+       public static final String GETTERSETTER_ACTION = PREFIX
+                       + "getter_setter_action_context"; //$NON-NLS-1$
+
+       public static final String ADD_METHODSTUB_ACTION = PREFIX
+                       + "add_methodstub_action_context"; //$NON-NLS-1$
+
+       public static final String ADD_UNIMPLEMENTED_METHODS_ACTION = PREFIX
+                       + "add_unimplemented_methods_action_context"; //$NON-NLS-1$
+
+       public static final String ADD_UNIMPLEMENTED_CONSTRUCTORS_ACTION = PREFIX
+                       + "add_unimplemented_constructors_action_context"; //$NON-NLS-1$        
+
+       public static final String SHOW_IN_PACKAGEVIEW_ACTION = PREFIX
+                       + "show_in_packageview_action_context"; //$NON-NLS-1$
+
+       public static final String SHOW_IN_HIERARCHYVIEW_ACTION = PREFIX
+                       + "show_in_hierarchyview_action_context"; //$NON-NLS-1$
+
+       public static final String FOCUS_ON_SELECTION_ACTION = PREFIX
+                       + "focus_on_selection_action"; //$NON-NLS-1$
+
+       public static final String FOCUS_ON_TYPE_ACTION = PREFIX
+                       + "focus_on_type_action"; //$NON-NLS-1$
+
+       public static final String TYPEHIERARCHY_HISTORY_ACTION = PREFIX
+                       + "typehierarchy_history_action"; //$NON-NLS-1$
+
+       public static final String FILTER_PUBLIC_ACTION = PREFIX
+                       + "filter_public_action"; //$NON-NLS-1$
+
+       public static final String FILTER_FIELDS_ACTION = PREFIX
+                       + "filter_fields_action"; //$NON-NLS-1$
+
+       public static final String FILTER_STATIC_ACTION = PREFIX
+                       + "filter_static_action"; //$NON-NLS-1$
+
+       public static final String SHOW_INHERITED_ACTION = PREFIX
+                       + "show_inherited_action"; //$NON-NLS-1$
+
+       public static final String SHOW_SUPERTYPES = PREFIX
+                       + "show_supertypes_action"; //$NON-NLS-1$
+
+       public static final String SHOW_SUBTYPES = PREFIX + "show_subtypes_action"; //$NON-NLS-1$
+
+       public static final String SHOW_HIERARCHY = PREFIX
+                       + "show_hierarchy_action"; //$NON-NLS-1$
+
+       public static final String ENABLE_METHODFILTER_ACTION = PREFIX
+                       + "enable_methodfilter_action"; //$NON-NLS-1$
+
+       public static final String ADD_IMPORT_ON_SELECTION_ACTION = PREFIX
+                       + "add_imports_on_selection_action_context"; //$NON-NLS-1$
+
+       public static final String ORGANIZE_IMPORTS_ACTION = PREFIX
+                       + "organize_imports_action_context"; //$NON-NLS-1$
+
+       public static final String ADD_TO_CLASSPATH_ACTION = PREFIX
+                       + "addjtoclasspath_action_context"; //$NON-NLS-1$
+
+       public static final String REMOVE_FROM_CLASSPATH_ACTION = PREFIX
+                       + "removefromclasspath_action_context"; //$NON-NLS-1$
+
+       public static final String TOGGLE_PRESENTATION_ACTION = PREFIX
+                       + "toggle_presentation_action_context"; //$NON-NLS-1$
+
+       public static final String TOGGLE_TEXTHOVER_ACTION = PREFIX
+                       + "toggle_texthover_action_context"; //$NON-NLS-1$
+
+       public static final String OPEN_CLASS_WIZARD_ACTION = PREFIX
+                       + "open_class_wizard_action"; //$NON-NLS-1$
+
+       public static final String OPEN_INTERFACE_WIZARD_ACTION = PREFIX
+                       + "open_interface_wizard_action"; //$NON-NLS-1$
+
+       public static final String SORT_MEMBERS_ACTION = PREFIX
+                       + "sort_members_action"; //$NON-NLS-1$  
+
+       public static final String OPEN_PACKAGE_WIZARD_ACTION = PREFIX
+                       + "open_package_wizard_action"; //$NON-NLS-1$
+
+       public static final String OPEN_PROJECT_WIZARD_ACTION = PREFIX
+                       + "open_project_wizard_action"; //$NON-NLS-1$
+
+       public static final String OPEN_SNIPPET_WIZARD_ACTION = PREFIX
+                       + "open_snippet_wizard_action"; //$NON-NLS-1$
+
+       public static final String EDIT_WORKING_SET_ACTION = PREFIX
+                       + "edit_working_set_action"; //$NON-NLS-1$
+
+       public static final String CLEAR_WORKING_SET_ACTION = PREFIX
+                       + "clear_working_set_action"; //$NON-NLS-1$
+
+       public static final String GOTO_MARKER_ACTION = PREFIX
+                       + "goto_marker_action"; //$NON-NLS-1$
+
+       public static final String GOTO_PACKAGE_ACTION = PREFIX
+                       + "goto_package_action"; //$NON-NLS-1$
+
+       public static final String GOTO_TYPE_ACTION = PREFIX + "goto_type_action"; //$NON-NLS-1$
+
+       public static final String GOTO_MATCHING_BRACKET_ACTION = PREFIX
+                       + "goto_matching_bracket_action"; //$NON-NLS-1$
+
+       public static final String GOTO_NEXT_MEMBER_ACTION = PREFIX
+                       + "goto_next_member_action"; //$NON-NLS-1$
+
+       public static final String GOTO_PREVIOUS_MEMBER_ACTION = PREFIX
+                       + "goto_previous_member_action"; //$NON-NLS-1$
+
+       public static final String HISTORY_ACTION = PREFIX + "history_action"; //$NON-NLS-1$
+
+       public static final String HISTORY_LIST_ACTION = PREFIX
+                       + "history_list_action"; //$NON-NLS-1$
+
+       public static final String LEXICAL_SORTING_OUTLINE_ACTION = PREFIX
+                       + "lexical_sorting_outline_action"; //$NON-NLS-1$
+
+       public static final String LEXICAL_SORTING_BROWSING_ACTION = PREFIX
+                       + "lexical_sorting_browsing_action"; //$NON-NLS-1$
+
+       public static final String OPEN_JAVA_PERSPECTIVE_ACTION = PREFIX
+                       + "open_java_perspective_action"; //$NON-NLS-1$
+
+       public static final String ADD_DELEGATE_METHODS_ACTION = PREFIX
+                       + "add_delegate_methods_action"; //$NON-NLS-1$
+
+       public static final String OPEN_JAVA_BROWSING_PERSPECTIVE_ACTION = PREFIX
+                       + "open_java_browsing_perspective_action"; //$NON-NLS-1$
+
+       public static final String OPEN_PROJECT_ACTION = PREFIX
+                       + "open_project_action"; //$NON-NLS-1$
+
+       public static final String OPEN_TYPE_ACTION = PREFIX + "open_type_action"; //$NON-NLS-1$
+
+       public static final String OPEN_TYPE_IN_HIERARCHY_ACTION = PREFIX
+                       + "open_type_in_hierarchy_action"; //$NON-NLS-1$
+
+       public static final String ADD_JAVADOC_STUB_ACTION = PREFIX
+                       + "add_javadoc_stub_action"; //$NON-NLS-1$
+
+       public static final String ADD_TASK_ACTION = PREFIX + "add_task_action"; //$NON-NLS-1$
+
+       public static final String EXTERNALIZE_STRINGS_ACTION = PREFIX
+                       + "externalize_strings_action"; //$NON-NLS-1$   
+
+       public static final String EXTRACT_METHOD_ACTION = PREFIX
+                       + "extract_method_action"; //$NON-NLS-1$        
+
+       public static final String EXTRACT_TEMP_ACTION = PREFIX
+                       + "extract_temp_action"; //$NON-NLS-1$  
+
+       public static final String PROMOTE_TEMP_TO_FIELD_ACTION = PREFIX
+                       + "promote_temp_to_field_action"; //$NON-NLS-1$ 
+
+       public static final String CONVERT_ANONYMOUS_TO_NESTED_ACTION = PREFIX
+                       + "convert_anonymous_to_nested_action"; //$NON-NLS-1$   
+
+       public static final String EXTRACT_CONSTANT_ACTION = PREFIX
+                       + "extract_constant_action"; //$NON-NLS-1$      
+
+       public static final String EXTRACT_INTERFACE_ACTION = PREFIX
+                       + "extract_interface_action"; //$NON-NLS-1$     
+
+       public static final String MOVE_INNER_TO_TOP_ACTION = PREFIX
+                       + "move_inner_to_top_level_action"; //$NON-NLS-1$
+
+       public static final String USE_SUPERTYPE_ACTION = PREFIX
+                       + "use_supertype_action"; //$NON-NLS-1$
+
+       public static final String FIND_DECLARATIONS_IN_WORKSPACE_ACTION = PREFIX
+                       + "find_declarations_in_workspace_action"; //$NON-NLS-1$        
+
+       public static final String FIND_DECLARATIONS_IN_HIERARCHY_ACTION = PREFIX
+                       + "find_declarations_in_hierarchy_action"; //$NON-NLS-1$        
+
+       public static final String FIND_DECLARATIONS_IN_WORKING_SET_ACTION = PREFIX
+                       + "find_declarations_in_working_set_action"; //$NON-NLS-1$      
+
+       public static final String FIND_IMPLEMENTORS_IN_WORKSPACE_ACTION = PREFIX
+                       + "find_implementors_in_workspace_action"; //$NON-NLS-1$                        
+
+       public static final String FIND_IMPLEMENTORS_IN_WORKING_SET_ACTION = PREFIX
+                       + "find_implementors_in_working_set_action"; //$NON-NLS-1$                      
+
+       public static final String FIND_REFERENCES_IN_WORKSPACE_ACTION = PREFIX
+                       + "find_references_in_workspace_action"; //$NON-NLS-1$                  
+
+       public static final String FIND_REFERENCES_IN_HIERARCHY_ACTION = PREFIX
+                       + "find_references_in_hierarchy_action"; //$NON-NLS-1$                  
+
+       public static final String FIND_REFERENCES_IN_WORKING_SET_ACTION = PREFIX
+                       + "find_references_in_working_set_action"; //$NON-NLS-1$                        
+
+       public static final String FIND_READ_REFERENCES_IN_WORKSPACE_ACTION = PREFIX
+                       + "find_read_references_in_workspace_action"; //$NON-NLS-1$                     
+
+       public static final String FIND_READ_REFERENCES_IN_HIERARCHY_ACTION = PREFIX
+                       + "find_read_references_in_hierarchy_action"; //$NON-NLS-1$
+
+       public static final String FIND_READ_REFERENCES_IN_WORKING_SET_ACTION = PREFIX
+                       + "find_read_references_in_working_set_action"; //$NON-NLS-1$
+
+       public static final String FIND_WRITE_REFERENCES_IN_HIERARCHY_ACTION = PREFIX
+                       + "find_write_references_in_hierarchy_action"; //$NON-NLS-1$
+
+       public static final String FIND_WRITE_REFERENCES_IN_WORKING_SET_ACTION = PREFIX
+                       + "find_write_references_in_working_set_action"; //$NON-NLS-1$
+
+       public static final String FIND_WRITE_REFERENCES_IN_WORKSPACE_ACTION = PREFIX
+                       + "find_write_references_in_workspace_action"; //$NON-NLS-1$
+
+       public static final String FIND_OCCURRENCES_IN_FILE_ACTION = PREFIX
+                       + "find_occurrences_in_file_action"; //$NON-NLS-1$
+
+       public static final String WORKING_SET_FIND_ACTION = PREFIX
+                       + "working_set_find_action"; //$NON-NLS-1$
+
+       public static final String FIND_STRINGS_TO_EXTERNALIZE_ACTION = PREFIX
+                       + "find_strings_to_externalize_action"; //$NON-NLS-1$
+
+       public static final String INLINE_ACTION = PREFIX + "inline_action"; //$NON-NLS-1$
+
+       public static final String MODIFY_PARAMETERS_ACTION = PREFIX
+                       + "modify_parameters_action"; //$NON-NLS-1$
+
+       public static final String MOVE_ACTION = PREFIX + "move_action"; //$NON-NLS-1$
+
+       public static final String OPEN_ACTION = PREFIX + "open_action"; //$NON-NLS-1$
+
+       public static final String OPEN_EXTERNAL_JAVADOC_ACTION = PREFIX
+                       + "open_external_javadoc_action"; //$NON-NLS-1$
+
+       public static final String OPEN_SUPER_IMPLEMENTATION_ACTION = PREFIX
+                       + "open_super_implementation_action"; //$NON-NLS-1$
+
+       public static final String PULL_UP_ACTION = PREFIX + "pull_up_action"; //$NON-NLS-1$
+
+       public static final String PUSH_DOWN_ACTION = PREFIX + "push_down_action"; //$NON-NLS-1$
+
+       public static final String REFRESH_ACTION = PREFIX + "refresh_action"; //$NON-NLS-1$
+
+       public static final String RENAME_ACTION = PREFIX + "rename_action"; //$NON-NLS-1$
+
+       public static final String SELF_ENCAPSULATE_ACTION = PREFIX
+                       + "self_encapsulate_action"; //$NON-NLS-1$
+
+       public static final String SHOW_IN_NAVIGATOR_VIEW_ACTION = PREFIX
+                       + "show_in_navigator_action"; //$NON-NLS-1$
+
+       public static final String SURROUND_WITH_TRY_CATCH_ACTION = PREFIX
+                       + "surround_with_try_catch_action"; //$NON-NLS-1$       
+
+       public static final String OPEN_RESOURCE_ACTION = PREFIX
+                       + "open_resource_action"; //$NON-NLS-1$ 
+
+       public static final String SELECT_WORKING_SET_ACTION = PREFIX
+                       + "select_working_set_action"; //$NON-NLS-1$    
+
+       public static final String STRUCTURED_SELECTION_HISTORY_ACTION = PREFIX
+                       + "structured_selection_history_action"; //$NON-NLS-1$  
+
+       public static final String STRUCTURED_SELECT_ENCLOSING_ACTION = PREFIX
+                       + "structured_select_enclosing_action"; //$NON-NLS-1$   
+
+       public static final String STRUCTURED_SELECT_NEXT_ACTION = PREFIX
+                       + "structured_select_next_action"; //$NON-NLS-1$        
+
+       public static final String STRUCTURED_SELECT_PREVIOUS_ACTION = PREFIX
+                       + "structured_select_previous_action"; //$NON-NLS-1$    
+
+       public static final String TOGGLE_ORIENTATION_ACTION = PREFIX
+                       + "toggle_orientations_action"; //$NON-NLS-1$           
+
+       public static final String CUT_ACTION = PREFIX + "cut_action"; //$NON-NLS-1$    
+
+       public static final String COPY_ACTION = PREFIX + "copy_action"; //$NON-NLS-1$  
+
+       public static final String PASTE_ACTION = PREFIX + "paste_action"; //$NON-NLS-1$        
+
+       public static final String DELETE_ACTION = PREFIX + "delete_action"; //$NON-NLS-1$      
+
+       public static final String SELECT_ALL_ACTION = PREFIX + "select_all_action"; //$NON-NLS-1$
+
+       public static final String OPEN_TYPE_HIERARCHY_ACTION = PREFIX
+                       + "open_type_hierarchy_action"; //$NON-NLS-1$   
+
+       public static final String COLLAPSE_ALL_ACTION = PREFIX
+                       + "open_type_hierarchy_action"; //$NON-NLS-1$
+
+       public static final String GOTO_RESOURCE_ACTION = PREFIX
+                       + "goto_resource_action"; //$NON-NLS-1$
+
+       public static final String LINK_EDITOR_ACTION = PREFIX
+                       + "link_editor_action"; //$NON-NLS-1$
+
+       public static final String GO_INTO_TOP_LEVEL_TYPE_ACTION = PREFIX
+                       + "go_into_top_level_type_action"; //$NON-NLS-1$
+
+       public static final String COMPARE_WITH_HISTORY_ACTION = PREFIX
+                       + "compare_with_history_action"; //$NON-NLS-1$
+
+       public static final String REPLACE_WITH_PREVIOUS_FROM_HISTORY_ACTION = PREFIX
+                       + "replace_with_previous_from_history_action"; //$NON-NLS-1$
+
+       public static final String REPLACE_WITH_HISTORY_ACTION = PREFIX
+                       + "replace_with_history_action"; //$NON-NLS-1$
+
+       public static final String ADD_FROM_HISTORY_ACTION = PREFIX
+                       + "add_from_history_action"; //$NON-NLS-1$
+
+       public static final String LAYOUT_FLAT_ACTION = PREFIX
+                       + "layout_flat_action"; //$NON-NLS-1$
+
+       public static final String LAYOUT_HIERARCHICAL_ACTION = PREFIX
+                       + "layout_hierarchical_action"; //$NON-NLS-1$   
+
+       public static final String NEXT_CHANGE_ACTION = PREFIX
+                       + "next_change_action"; //$NON-NLS-1$   
+
+       public static final String PREVIOUS_CHANGE_ACTION = PREFIX
+                       + "previous_change_action"; //$NON-NLS-1$       
+
+       public static final String NEXT_PROBLEM_ACTION = PREFIX
+                       + "next_problem_action"; //$NON-NLS-1$  
+
+       public static final String PREVIOUS_PROBLEM_ACTION = PREFIX
+                       + "previous_problem_action"; //$NON-NLS-1$      
+
+       public static final String JAVA_SELECT_MARKER_RULER_ACTION = PREFIX
+                       + "java_select_marker_ruler_action"; //$NON-NLS-1$      
+
+       public static final String GOTO_NEXT_ERROR_ACTION = PREFIX
+                       + "goto_next_error_action"; //$NON-NLS-1$       
+
+       public static final String GOTO_PREVIOUS_ERROR_ACTION = PREFIX
+                       + "goto_previous_error_action"; //$NON-NLS-1$   
+
+       public static final String SHOW_QUALIFIED_NAMES_ACTION = PREFIX
+                       + "show_qualified_names_action"; //$NON-NLS-1$  
+
+       public static final String SORT_BY_DEFINING_TYPE_ACTION = PREFIX
+                       + "sort_by_defining_type_action"; //$NON-NLS-1$ 
+
+       public static final String FORMAT_ACTION = PREFIX + "format_action"; //$NON-NLS-1$      
+
+       public static final String COMMENT_ACTION = PREFIX + "comment_action"; //$NON-NLS-1$    
+
+       public static final String UNCOMMENT_ACTION = PREFIX + "uncomment_action"; //$NON-NLS-1$        
+
+       public static final String QUICK_FIX_ACTION = PREFIX + "quick_fix_action"; //$NON-NLS-1$        
+
+       public static final String CONTENT_ASSIST_ACTION = PREFIX
+                       + "content_assist_action"; //$NON-NLS-1$        
+
+       public static final String PARAMETER_HINTS_ACTION = PREFIX
+                       + "parameter_hints_action"; //$NON-NLS-1$       
+
+       public static final String SHOW_JAVADOC_ACTION = PREFIX
+                       + "show_javadoc_action"; //$NON-NLS-1$  
+
+       public static final String SHOW_OUTLINE_ACTION = PREFIX
+                       + "show_outline_action"; //$NON-NLS-1$  
+
+       public static final String OPEN_STRUCTURE_ACTION = PREFIX
+                       + "open_structure_action"; //$NON-NLS-1$        
+
+       // Dialogs
+       public static final String MAINTYPE_SELECTION_DIALOG = PREFIX
+                       + "maintype_selection_dialog_context"; //$NON-NLS-1$
+
+       public static final String OPEN_TYPE_DIALOG = PREFIX
+                       + "open_type_dialog_context"; //$NON-NLS-1$
+
+       public static final String SOURCE_ATTACHMENT_DIALOG = PREFIX
+                       + "source_attachment_dialog_context"; //$NON-NLS-1$
+
+       public static final String LIBRARIES_WORKBOOK_PAGE_ADVANCED_DIALOG = PREFIX
+                       + "advanced_dialog_context"; //$NON-NLS-1$
+
+       public static final String CONFIRM_SAVE_MODIFIED_RESOURCES_DIALOG = PREFIX
+                       + "confirm_save_modified_resources_dialog_context"; //$NON-NLS-1$
+
+       public static final String NEW_VARIABLE_ENTRY_DIALOG = PREFIX
+                       + "new_variable_dialog_context"; //$NON-NLS-1$
+
+       public static final String NONNLS_DIALOG = PREFIX + "nonnls_dialog_context"; //$NON-NLS-1$
+
+       public static final String MULTI_MAIN_TYPE_SELECTION_DIALOG = PREFIX
+                       + "multi_main_type_selection_dialog_context"; //$NON-NLS-1$
+
+       public static final String MULTI_TYPE_SELECTION_DIALOG = PREFIX
+                       + "multi_type_selection_dialog_context"; //$NON-NLS-1$
+
+       public static final String SUPER_INTERFACE_SELECTION_DIALOG = PREFIX
+                       + "super_interface_selection_dialog_context"; //$NON-NLS-1$
+
+       public static final String OVERRIDE_TREE_SELECTION_DIALOG = PREFIX
+                       + "override_tree_selection_dialog_context"; //$NON-NLS-1$
+
+       public static final String MOVE_DESTINATION_DIALOG = PREFIX
+                       + "move_destination_dialog_context"; //$NON-NLS-1$
+
+       public static final String CHOOSE_VARIABLE_DIALOG = PREFIX
+                       + "choose_variable_dialog_context"; //$NON-NLS-1$       
+
+       public static final String EDIT_TEMPLATE_DIALOG = PREFIX
+                       + "edit_template_dialog_context"; //$NON-NLS-1$ 
+
+       public static final String HISTORY_LIST_DIALOG = PREFIX
+                       + "history_list_dialog_context"; //$NON-NLS-1$  
+
+       public static final String IMPORT_ORGANIZE_INPUT_DIALOG = PREFIX
+                       + "import_organize_input_dialog_context"; //$NON-NLS-1$
+
+       public static final String TODO_TASK_INPUT_DIALOG = PREFIX
+                       + "todo_task_input_dialog_context"; //$NON-NLS-1$
+
+       public static final String JAVADOC_PROPERTY_DIALOG = PREFIX
+                       + "javadoc_property_dialog_context"; //$NON-NLS-1$      
+
+       public static final String NEW_CONTAINER_DIALOG = PREFIX
+                       + "new_container_dialog_context"; //$NON-NLS-1$ 
+
+       public static final String EXCLUSION_PATTERN_DIALOG = PREFIX
+                       + "exclusion_pattern_dialog_context"; //$NON-NLS-1$
+
+       public static final String OUTPUT_LOCATION_DIALOG = PREFIX
+                       + "output_location_dialog_context"; //$NON-NLS-1$
+
+       public static final String VARIABLE_CREATION_DIALOG = PREFIX
+                       + "variable_creation_dialog_context"; //$NON-NLS-1$     
+
+       public static final String JAVA_SEARCH_PAGE = PREFIX
+                       + "java_search_page_context"; //$NON-NLS-1$
+
+       public static final String NLS_SEARCH_PAGE = PREFIX
+                       + "nls_search_page_context"; //$NON-NLS-1$
+
+       public static final String JAVA_EDITOR = PREFIX + "java_editor_context"; //$NON-NLS-1$
+
+       public static final String GOTO_RESOURCE_DIALOG = PREFIX
+                       + "goto_resource_dialog"; //$NON-NLS-1$
+
+       public static final String COMPARE_DIALOG = PREFIX
+                       + "compare_dialog_context"; //$NON-NLS-1$
+
+       public static final String ADD_ELEMENT_FROM_HISTORY_DIALOG = PREFIX
+                       + "add_element_from_history_dialog_context"; //$NON-NLS-1$
+
+       public static final String COMPARE_ELEMENT_WITH_HISTORY_DIALOG = PREFIX
+                       + "compare_element_with_history_dialog_context"; //$NON-NLS-1$
+
+       public static final String REPLACE_ELEMENT_WITH_HISTORY_DIALOG = PREFIX
+                       + "replace_element_with_history_dialog_context"; //$NON-NLS-1$
+
+       // view parts
+       public static final String TYPE_HIERARCHY_VIEW = PREFIX
+                       + "type_hierarchy_view_context"; //$NON-NLS-1$
+
+       public static final String PACKAGES_VIEW = PREFIX + "package_view_context"; //$NON-NLS-1$
+
+       public static final String PROJECTS_VIEW = PREFIX + "projects_view_context"; //$NON-NLS-1$
+
+       public static final String PACKAGES_BROWSING_VIEW = PREFIX
+                       + "packages_browsing_view_context"; //$NON-NLS-1$
+
+       public static final String TYPES_VIEW = PREFIX + "types_view_context"; //$NON-NLS-1$
+
+       public static final String MEMBERS_VIEW = PREFIX + "members_view_context"; //$NON-NLS-1$
+
+       // Preference/Property pages
+       public static final String APPEARANCE_PREFERENCE_PAGE = PREFIX
+                       + "appearance_preference_page_context"; //$NON-NLS-1$
+
+       public static final String SORT_ORDER_PREFERENCE_PAGE = PREFIX
+                       + "sort_order_preference_page_context"; //$NON-NLS-1$
+
+       public static final String BUILD_PATH_PROPERTY_PAGE = PREFIX
+                       + "build_path_property_page_context"; //$NON-NLS-1$
+
+       public static final String CP_VARIABLES_PREFERENCE_PAGE = PREFIX
+                       + "cp_variables_preference_page_context"; //$NON-NLS-1$
+
+       public static final String CODEFORMATTER_PREFERENCE_PAGE = PREFIX
+                       + "codeformatter_preference_page_context"; //$NON-NLS-1$
+
+       public static final String SOURCE_ATTACHMENT_PROPERTY_PAGE = PREFIX
+                       + "source_attachment_property_page_context"; //$NON-NLS-1$
+
+       public static final String COMPILER_PROPERTY_PAGE = PREFIX
+                       + "compiler_property_page_context"; //$NON-NLS-1$
+
+       public static final String TODOTASK_PROPERTY_PAGE = PREFIX
+                       + "tasktags_property_page_context"; //$NON-NLS-1$
+
+       public static final String CODE_MANIPULATION_PREFERENCE_PAGE = PREFIX
+                       + "code_manipulation_preference_context"; //$NON-NLS-1$
+
+       public static final String ORGANIZE_IMPORTS_PREFERENCE_PAGE = PREFIX
+                       + "organizeimports_preference_page_context"; //$NON-NLS-1$
+
+       public static final String JAVA_BASE_PREFERENCE_PAGE = PREFIX
+                       + "java_base_preference_page_context"; //$NON-NLS-1$
+
+       public static final String REFACTORING_PREFERENCE_PAGE = PREFIX
+                       + "refactoring_preference_page_context"; //$NON-NLS-1$
+
+       public static final String JAVA_EDITOR_PREFERENCE_PAGE = PREFIX
+                       + "java_editor_preference_page_context"; //$NON-NLS-1$
+
+       public static final String COMPILER_PREFERENCE_PAGE = PREFIX
+                       + "compiler_preference_page_context"; //$NON-NLS-1$
+
+       public static final String TODOTASK_PREFERENCE_PAGE = PREFIX
+                       + "tasktags_preference_page_context"; //$NON-NLS-1$
+
+       public static final String TEMPLATE_PREFERENCE_PAGE = PREFIX
+                       + "template_preference_page_context"; //$NON-NLS-1$
+
+       public static final String JAVADOC_PREFERENCE_PAGE = PREFIX
+                       + "javadoc_preference_page_context"; //$NON-NLS-1$
+
+       public static final String NEW_JAVA_PROJECT_PREFERENCE_PAGE = PREFIX
+                       + "new_java_project_preference_page_context"; //$NON-NLS-1$
+
+       public static final String JAVADOC_CONFIGURATION_PROPERTY_PAGE = PREFIX
+                       + "new_java_project_preference_page_context"; //$NON-NLS-1$
+
+       public static final String JAVA_ELEMENT_INFO_PAGE = PREFIX
+                       + "java_element_info_page_context"; //$NON-NLS-1$
+
+       // Wizard pages
+       public static final String NEW_JAVAPROJECT_WIZARD_PAGE = PREFIX
+                       + "new_javaproject_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String NEW_SNIPPET_WIZARD_PAGE = PREFIX
+                       + "new_snippet_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String NEW_PACKAGE_WIZARD_PAGE = PREFIX
+                       + "new_package_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String NEW_CLASS_WIZARD_PAGE = PREFIX
+                       + "new_class_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String NEW_INTERFACE_WIZARD_PAGE = PREFIX
+                       + "new_interface_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String NEW_PACKAGEROOT_WIZARD_PAGE = PREFIX
+                       + "new_packageroot_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String JARPACKAGER_WIZARD_PAGE = PREFIX
+                       + "jar_packager_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String JARMANIFEST_WIZARD_PAGE = PREFIX
+                       + "jar_manifest_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String JAROPTIONS_WIZARD_PAGE = PREFIX
+                       + "jar_options_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String JAVA_WORKING_SET_PAGE = PREFIX
+                       + "java_working_set_page_context"; //$NON-NLS-1$
+
+       public static final String CLASSPATH_CONTAINER_DEFAULT_PAGE = PREFIX
+                       + "classpath_container_default_page_context"; //$NON-NLS-1$
+
+       public static final String JAVADOC_STANDARD_PAGE = PREFIX
+                       + "javadoc_standard_page_context"; //$NON-NLS-1$
+
+       public static final String JAVADOC_SPECIFICS_PAGE = PREFIX
+                       + "javadoc_specifics_page_context"; //$NON-NLS-1$
+
+       public static final String JAVADOC_TREE_PAGE = PREFIX
+                       + "javadoc_tree_page_context"; //$NON-NLS-1$
+
+       // same help for all refactoring preview pages
+       public static final String REFACTORING_PREVIEW_WIZARD_PAGE = PREFIX
+                       + "refactoring_preview_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String MOVE_CU_ERROR_WIZARD_PAGE = PREFIX
+                       + "move_cu_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_PARAMS_WIZARD_PAGE = PREFIX
+                       + "rename_params_wizard_page"; //$NON-NLS-1$
+
+       public static final String RENAME_PARAMS_ERROR_WIZARD_PAGE = PREFIX
+                       + "rename_params_error_wizard_page"; //$NON-NLS-1$
+
+       public static final String EXTERNALIZE_WIZARD_KEYVALUE_PAGE = PREFIX
+                       + "externalize_wizard_keyvalue_page_context"; //$NON-NLS-1$
+
+       public static final String EXTERNALIZE_WIZARD_PROPERTIES_FILE_PAGE = PREFIX
+                       + "externalize_wizard_properties_file_page_context"; //$NON-NLS-1$
+
+       public static final String EXTERNALIZE_ERROR_WIZARD_PAGE = PREFIX
+                       + "externalize_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String EXTRACT_INTERFACE_WIZARD_PAGE = PREFIX
+                       + "extract_interface_temp_page_context"; //$NON-NLS-1$
+
+       public static final String EXTRACT_INTERFACE_ERROR_WIZARD_PAGE = PREFIX
+                       + "extract_interface_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String EXTRACT_METHOD_WIZARD_PAGE = PREFIX
+                       + "extract_method_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String EXTRACT_METHOD_ERROR_WIZARD_PAGE = PREFIX
+                       + "extract_method_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String EXTRACT_TEMP_WIZARD_PAGE = PREFIX
+                       + "extract_temp_page_context"; //$NON-NLS-1$
+
+       public static final String EXTRACT_TEMP_ERROR_WIZARD_PAGE = PREFIX
+                       + "extract_temp_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String EXTRACT_CONSTANT_WIZARD_PAGE = PREFIX
+                       + "extract_constant_page_context"; //$NON-NLS-1$
+
+       public static final String EXTRACT_CONSTANT_ERROR_WIZARD_PAGE = PREFIX
+                       + "extract_constant_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String PROMOTE_TEMP_TO_FIELD_WIZARD_PAGE = PREFIX
+                       + "promote_temp_to_field_page_context"; //$NON-NLS-1$
+
+       public static final String PROMOTE_TEMP_TO_FIELD_ERROR_WIZARD_PAGE = PREFIX
+                       + "promote_temp_to_field_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String CONVERT_ANONYMOUS_TO_NESTED_WIZARD_PAGE = PREFIX
+                       + "convert_anonymous_to_nested_page_context"; //$NON-NLS-1$
+
+       public static final String CONVERT_ANONYMOUS_TO_NESTED_ERROR_WIZARD_PAGE = PREFIX
+                       + "convert_anonymous_to_nested_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String MODIFY_PARAMETERS_WIZARD_PAGE = PREFIX
+                       + "modify_parameters_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String MODIFY_PARAMETERS_ERROR_WIZARD_PAGE = PREFIX
+                       + "modify_parameters_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String MOVE_MEMBERS_WIZARD_PAGE = PREFIX
+                       + "move_members_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String MOVE_MEMBERS_ERROR_WIZARD_PAGE = PREFIX
+                       + "move_members_error_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String MOVE_INNER_TO_TOP_WIZARD_PAGE = PREFIX
+                       + "move_inner_to_top_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String MOVE_INNER_TO_TOP_ERROR_WIZARD_PAGE = PREFIX
+                       + "move_inner_to_top_error_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String PULL_UP_WIZARD_PAGE = PREFIX
+                       + "pull_up_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String PULL_UP_ERROR_WIZARD_PAGE = PREFIX
+                       + "pull_up_error_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String PUSH_DOWN_WIZARD_PAGE = PREFIX
+                       + "push_down_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String PUSH_DOWN_ERROR_WIZARD_PAGE = PREFIX
+                       + "push_down_error_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_PACKAGE_WIZARD_PAGE = PREFIX
+                       + "rename_package_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_PACKAGE_ERROR_WIZARD_PAGE = PREFIX
+                       + "rename_package_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_TEMP_WIZARD_PAGE = PREFIX
+                       + "rename_local_variable_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_TEMP_ERROR_WIZARD_PAGE = PREFIX
+                       + "rename_local_variable_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_CU_WIZARD_PAGE = PREFIX
+                       + "rename_cu_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_CU_ERROR_WIZARD_PAGE = PREFIX
+                       + "rename_cu_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_METHOD_WIZARD_PAGE = PREFIX
+                       + "rename_method_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_METHOD_ERROR_WIZARD_PAGE = PREFIX
+                       + "rename_method_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_TYPE_WIZARD_PAGE = PREFIX
+                       + "rename_type_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_TYPE_ERROR_WIZARD_PAGE = PREFIX
+                       + "rename_type_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_FIELD_WIZARD_PAGE = PREFIX
+                       + "rename_field_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String RENAME_FIELD_ERROR_WIZARD_PAGE = PREFIX
+                       + "rename_field_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String SEF_WIZARD_PAGE = PREFIX
+                       + "self_encapsulate_field_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String SEF_ERROR_WIZARD_PAGE = PREFIX
+                       + "self_encapsulate_field_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String USE_SUPERTYPE_WIZARD_PAGE = PREFIX
+                       + "use_supertype_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String USE_SUPERTYPE_ERROR_WIZARD_PAGE = PREFIX
+                       + "use_supertype_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String INLINE_METHOD_WIZARD_PAGE = PREFIX
+                       + "inline_method_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String INLINE_METHOD_ERROR_WIZARD_PAGE = PREFIX
+                       + "inline_method_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String INLINE_CONSTANT_WIZARD_PAGE = PREFIX
+                       + "inline_constant_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String INLINE_CONSTANT_ERROR_WIZARD_PAGE = PREFIX
+                       + "inline_constant_error_wizard_page_context"; //$NON-NLS-1$
+
+       public static final String INLINE_TEMP_ERROR_WIZARD_PAGE = PREFIX
+                       + "inline_temp_error_wizard_page_context"; //$NON-NLS-1$
+
+       // reused ui-blocks
+       public static final String BUILD_PATH_BLOCK = PREFIX
+                       + "build_paths_context"; //$NON-NLS-1$
+
+       public static final String SOURCE_ATTACHMENT_BLOCK = PREFIX
+                       + "source_attachment_context"; //$NON-NLS-1$
+
+       // Custom Filters
+       public static final String CUSTOM_FILTERS_DIALOG = PREFIX
+                       + "open_custom_filters_dialog_context"; //$NON-NLS-1$
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/IJavaStatusConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/IJavaStatusConstants.java
new file mode 100644 (file)
index 0000000..a5c7fbd
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui;
+
+/**
+ * Defines status codes relevant to the Java UI plug-in. When a Core exception
+ * is thrown, it contain a status object describing the cause of the exception.
+ * The status objects originating from the Java UI plug-in use the codes defined
+ * in this interface.
+ */
+public interface IJavaStatusConstants {
+
+       // Java UI status constants start at 10000 to make sure that we don't
+       // collide with resource and java model constants.
+
+       public static final int INTERNAL_ERROR = 10001;
+
+       /**
+        * Status constant indicating that an exception occurred on storing or
+        * loading templates.
+        */
+       public static final int TEMPLATE_IO_EXCEPTION = 10002;
+
+       /**
+        * Status constant indicating that an validateEdit call has changed the
+        * content of a file on disk.
+        */
+       public static final int VALIDATE_EDIT_CHANGED_CONTENT = 10003;
+
+       /**
+        * Status constant indicating that a <tt>ChangeAbortException</tt> has
+        * been caught.
+        */
+       public static final int CHANGE_ABORTED = 10004;
+
+       /**
+        * Status constant indicating that an exception occurred while parsing
+        * template file.
+        */
+       public static final int TEMPLATE_PARSE_EXCEPTION = 10005;
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/JavaElementAdapterFactory.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/JavaElementAdapterFactory.java
new file mode 100644 (file)
index 0000000..b1ae566
--- /dev/null
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.ui.IContributorResourceAdapter;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.views.properties.FilePropertySource;
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.ui.views.properties.ResourcePropertySource;
+
+/**
+ * Implements basic UI support for Java elements. Implements handle to
+ * persistent support for Java elements.
+ */
+public class JavaElementAdapterFactory implements IAdapterFactory,
+               IContributorResourceAdapter {
+
+       private static Class[] PROPERTIES = new Class[] {
+                       IPropertySource.class,
+                       IResource.class,
+                       // IWorkbenchAdapter.class,
+                       // IResourceLocator.class,
+                       IPersistableElement.class, IProject.class,
+                       IContributorResourceAdapter.class,
+       // ITaskListResourceAdapter.class,
+       // IContainmentAdapter.class
+       };
+
+       // private Object fSearchPageScoreComputer;
+       // private static IResourceLocator fgResourceLocator= new ResourceLocator();
+       // private static JavaWorkbenchAdapter fgJavaWorkbenchAdapter= new
+       // JavaWorkbenchAdapter();
+       // private static ITaskListResourceAdapter fgTaskListAdapter= new
+       // JavaTaskListAdapter();
+       // private static JavaElementContainmentAdapter
+       // fgJavaElementContainmentAdapter= new JavaElementContainmentAdapter();
+
+       public Class[] getAdapterList() {
+               // updateLazyLoadedAdapters();
+               return PROPERTIES;
+       }
+
+       public Object getAdapter(Object element, Class key) {
+               // updateLazyLoadedAdapters();
+               IJavaElement java = (IJavaElement) element;
+
+               if (IPropertySource.class.equals(key)) {
+                       return getProperties(java);
+               }
+               if (IResource.class.equals(key)) {
+                       return getResource(java);
+               }
+               if (IProject.class.equals(key)) {
+                       return getProject(java);
+                       // } if (fSearchPageScoreComputer != null &&
+                       // ISearchPageScoreComputer.class.equals(key)) {
+                       // return fSearchPageScoreComputer;
+                       // } if (IWorkbenchAdapter.class.equals(key)) {
+                       // return fgJavaWorkbenchAdapter;
+                       // } if (IResourceLocator.class.equals(key)) {
+                       // return fgResourceLocator;
+                       // } if (IPersistableElement.class.equals(key)) {
+                       // return new PersistableJavaElementFactory(java);
+               }
+               if (IContributorResourceAdapter.class.equals(key)) {
+                       return this;
+                       // } if (ITaskListResourceAdapter.class.equals(key)) {
+                       // return fgTaskListAdapter;
+                       // } if (IContainmentAdapter.class.equals(key)) {
+                       // return fgJavaElementContainmentAdapter;
+               }
+               return null;
+       }
+
+       private IResource getResource(IJavaElement element) {
+               // can't use IJavaElement.getResource directly as we are interrested in
+               // the
+               // corresponding resource
+               switch (element.getElementType()) {
+               case IJavaElement.TYPE:
+                       // top level types behave like the CU
+                       IJavaElement parent = element.getParent();
+                       if (parent instanceof ICompilationUnit) {
+                               return JavaModelUtil.toOriginal((ICompilationUnit) parent)
+                                               .getResource();
+                       }
+                       return null;
+               case IJavaElement.COMPILATION_UNIT:
+                       return JavaModelUtil.toOriginal((ICompilationUnit) element)
+                                       .getResource();
+               case IJavaElement.CLASS_FILE:
+               case IJavaElement.PACKAGE_FRAGMENT:
+                       // test if in a archive
+                       IPackageFragmentRoot root = (IPackageFragmentRoot) element
+                                       .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+                       if (!root.isArchive()) {
+                               return element.getResource();
+                       }
+                       return null;
+               case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+               case IJavaElement.JAVA_PROJECT:
+               case IJavaElement.JAVA_MODEL:
+                       return element.getResource();
+               default:
+                       return null;
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.IContributorResourceAdapter#getAdaptedResource(org.eclipse.core.runtime.IAdaptable)
+        */
+       public IResource getAdaptedResource(IAdaptable adaptable) {
+               return getResource((IJavaElement) adaptable);
+       }
+
+       private IResource getProject(IJavaElement element) {
+               return element.getJavaProject().getProject();
+       }
+
+       private IPropertySource getProperties(IJavaElement element) {
+               IResource resource = getResource(element);
+               if (resource == null)
+                       return new JavaElementProperties(element);
+               if (resource.getType() == IResource.FILE)
+                       return new FilePropertySource((IFile) resource);
+               return new ResourcePropertySource(resource);
+       }
+
+       // private void updateLazyLoadedAdapters() {
+       // if (fSearchPageScoreComputer == null &&
+       // SearchUtil.isSearchPlugInActivated())
+       // createSearchPageScoreComputer();
+       // }
+
+       // private void createSearchPageScoreComputer() {
+       // fSearchPageScoreComputer= new JavaSearchPageScoreComputer();
+       // PROPERTIES= new Class[] {
+       // IPropertySource.class,
+       // IResource.class,
+       // ISearchPageScoreComputer.class,
+       // IWorkbenchAdapter.class,
+       // IResourceLocator.class,
+       // IPersistableElement.class,
+       // IProject.class,
+       // IContributorResourceAdapter.class,
+       // ITaskListResourceAdapter.class,
+       // IContainmentAdapter.class
+       // };
+       // }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/JavaElementProperties.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/JavaElementProperties.java
new file mode 100644 (file)
index 0000000..e6e3d0c
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+
+import org.eclipse.jface.viewers.IBasicPropertyConstants;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.ui.views.properties.PropertyDescriptor;
+
+public class JavaElementProperties implements IPropertySource {
+
+       private IJavaElement fSource;
+
+       // Property Descriptors
+       static private IPropertyDescriptor[] fgPropertyDescriptors = new IPropertyDescriptor[1];
+       {
+               PropertyDescriptor descriptor;
+
+               // resource name
+               descriptor = new PropertyDescriptor(IBasicPropertyConstants.P_TEXT,
+                               PHPUIMessages.getString("JavaElementProperties.name")); //$NON-NLS-1$
+               descriptor.setAlwaysIncompatible(true);
+               fgPropertyDescriptors[0] = descriptor;
+       }
+
+       public JavaElementProperties(IJavaElement source) {
+               fSource = source;
+       }
+
+       public IPropertyDescriptor[] getPropertyDescriptors() {
+               return fgPropertyDescriptors;
+       }
+
+       public Object getPropertyValue(Object name) {
+               if (name.equals(IBasicPropertyConstants.P_TEXT)) {
+                       return fSource.getElementName();
+               }
+               return null;
+       }
+
+       public void setPropertyValue(Object name, Object value) {
+       }
+
+       public Object getEditableValue() {
+               return this;
+       }
+
+       public boolean isPropertySet(Object property) {
+               return false;
+       }
+
+       public void resetPropertyValue(Object property) {
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIException.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIException.java
new file mode 100644 (file)
index 0000000..4db626b
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * An exception to wrap a status. This is necessary to use the core's
+ * IRunnableWithProgress support
+ */
+
+public class PHPUIException extends CoreException {
+
+       public PHPUIException(IStatus status) {
+               super(status);
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIMessages.java
new file mode 100644 (file)
index 0000000..76a0bd8
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class PHPUIMessages {
+
+       private static final String RESOURCE_BUNDLE = PHPUIMessages.class.getName();//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private PHPUIMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       public static String getFormattedString(String key, String arg) {
+               return getFormattedString(key, new String[] { arg });
+       }
+
+       public static String getFormattedString(String key, String[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUIMessages.properties
new file mode 100644 (file)
index 0000000..e1e7d3f
--- /dev/null
@@ -0,0 +1,576 @@
+#########
+## jdt.internal.ui
+#########
+
+JavaPlugin.internal_error=Internal Error
+JavaElementProperties.name=Name
+
+#########
+## actions
+#########
+AddWatchpointAction.errorTitle=Error Adding Watchpoint
+
+AddGetterSetterAction.label=&Create Getter and Setter
+AddGetterSetterAction.description=Create getter and setter methods for the field
+AddGetterSetterAction.tooltip=Create Getter and Setter Methods for the Field
+
+AddGetterSetterAction.error.title=Generate Getter and Setter
+AddGetterSetterAction.error.actionfailed=Generate Getter and Setter Failed.
+AddGetterSetterAction.error.fieldNotExisting=The field ''{0}'' has been removed in the editor.
+
+AddGetterSetterAction.QueryDialog.title=Generate Getter and Setter
+AddGetterSetterAction.SkipSetterForFinalDialog.message=Field ''{0}'' is final.\nOK to only create getter?
+AddGetterSetterAction.SkipExistingDialog.message=Method ''{0}'' already exists.\nSkip creation?
+AddGetterSetterAction.SkipExistingDialog.skip.label=&Skip
+AddGetterSetterAction.SkipExistingDialog.replace.label=&Replace
+AddGetterSetterAction.SkipExistingDialog.skipAll.label=Skip &All
+
+AddMethodStubAction.label=Create Method
+AddMethodStubAction.detailed.implement=&Implement in ''{0}''
+AddMethodStubAction.detailed.override=&Override in ''{0}''
+AddMethodStubAction.description=Add method stub to type
+AddMethodStubAction.tooltip=Add Method Stub to Type
+
+AddMethodStubAction.error.title=Add Method Stub Failed
+AddMethodStubAction.error.type_removed_in_editor=Input type has been removed in editor
+
+AddMethodStubAction.QueryDialog.title=Create Method Stub
+AddMethodStubAction.OverridesFinalDialog.message=This will override the final method ''{0}'' from ''{1}''\nOK to continue?
+AddMethodStubAction.OverridesPrivateDialog.message=This will override the private method ''{0}'' from ''{1}''\nOK to continue?
+AddMethodStubAction.ReplaceExistingDialog.message=This will replace the existing method ''{0}''.\nOK to continue?
+
+AddJavaDocStubAction.label=Add &PHPDoc Comment
+AddJavaDocStubAction.description=Add a PHPDoc comment stub to the member element
+AddJavaDocStubAction.tooltip=Add a PHPDoc comment stub to the member element
+
+AddJavaDocStubsAction.error.dialogTitle=Add PHPDoc Comment
+AddJavaDocStubsAction.error.noWorkingCopy=Could not find working copy.
+AddJavaDocStubsAction.error.memberNotExisting=Member has been removed in editor.
+AddJavaDocStubsAction.error.actionFailed=Error while adding PHPDoc comment
+
+AddUnimplementedMethodsAction.label=&Override Methods...
+AddUnimplementedMethodsAction.description=Override Methods from super types.
+AddUnimplementedMethodsAction.tooltip=Override Methods
+
+AddUnimplementedMethodsAction.error.title=Override Methods
+AddUnimplementedMethodsAction.error.nothing_found=No methods to override found for this type.
+AddUnimplementedMethodsAction.error.type_removed_in_editor=Input type has been removed in editor.
+
+AddUnimplementedConstructorsAction.label=Add &Constructors from Superclass
+AddUnimplementedConstructorsAction.description=Evaluate and add constructors from superclass
+AddUnimplementedConstructorsAction.tooltip=Add Constructors from Superclass
+
+AddUnimplementedConstructorsAction.error.title=Add Constructors from Superclass
+AddUnimplementedConstructorsAction.error.nothing_found=No unimplemented constructors found.
+AddUnimplementedConstructorsAction.error.type_removed_in_editor=Input type has been removed in editor.
+
+OpenHierarchyPerspectiveItem.menulabel=Open Type &Hierarchy
+
+OpenImportDeclarationAction.errorMessage=Cannot open resource
+OpenImportDeclarationAction.errorTitle=Error On Open
+OpenImportDeclarationAction.label=&Open
+OpenImportDeclarationAction.description=Open the selected element in the editor\t
+OpenImportDeclarationAction.tooltip=Open the Selected Element in the Editor
+
+OpenJavaElementAction.description=Open the selected element
+OpenJavaElementAction.tooltip=Open the Selected Element
+OpenJavaElementAction.errorMessage=Cannot open element:
+OpenJavaElementAction.errorTitle=Problems while Opening Element
+OpenJavaElementAction.label=&Open
+
+OpenTypeAction.description=Open a type in the editor
+OpenTypeAction.tooltip=Open a Type
+OpenTypeAction.dialogMessage=&Choose a type (? = any character, * = any string):
+OpenTypeAction.dialogTitle=Open Type
+OpenTypeAction.errorMessage=An exception occurred while opening the type.
+OpenTypeAction.errorTitle=Open Type
+OpenTypeAction.label=Open Type...@Ctrl+Shift+T
+
+OpenSuperImplementationAction.label=Open S&uper Implementation
+OpenSuperImplementationAction.description=Open the Implementation in the Super Type
+OpenSuperImplementationAction.tooltip=Open the Implementation in the Super Type
+OpenSuperImplementationAction.error.title=Open Super Implementation
+OpenSuperImplementationAction.error.message=Opening failed. Check log for details.
+
+ShowInPackageViewAction.label=Show in &Package Explorer
+ShowInPackageViewAction.description=Show the selected element in Package Explorer
+ShowInPackageViewAction.tooltip=Show in Package Explorer
+ShowInPackageViewAction.error.title=Show In Package Explorer
+ShowInPackageViewAction.error.message=Internal error. Please see log for details.
+
+ShowTypeHierarchyAction.label=&Show in Type Hierarchy
+ShowTypeHierarchyAction.tooltip=Show in Type Hierarchy
+ShowTypeHierarchyAction.description=Show the type hierarchy of the selected type
+
+ShowTypeHierarchyAction.selectiondialog.title=Show In Type Hierarchy
+ShowTypeHierarchyAction.selectiondialog.message=&Select the type to be shown in the Type Hierarchy view:
+
+ShowTypeHierarchyAction.error.title=Problems Opening Type Hierarchy
+
+
+#######
+## dialogs
+#######
+
+ElementTreeSelectionDialog.nothing_available=No entries available.
+
+CheckedTreeSelectionDialog.nothing_available=No entries available.
+CheckedTreeSelectionDialog.select_all=Select &All
+CheckedTreeSelectionDialog.deselect_all=&Deselect All
+
+MultiElementListSelectionDialog.pageInfoMessage=Page {0} of {1}
+
+MultiTypeSelectionDialog.dialogMessage=Could not uniquely map the type name to a type.
+MultiTypeSelectionDialog.dialogTitle=Select Type
+MultiTypeSelectionDialog.errorMessage=Could not uniquely map the type name to a type.
+MultiTypeSelectionDialog.errorTitle=Select Type
+MultiTypeSelectionDialog.error2Message=Unexpected exception. See log for details.
+MultiTypeSelectionDialog.error2Title=Exception
+
+TypeSelectionDialog.errorMessage=Could not uniquely map the type name to a type.
+TypeSelectionDialog.errorTitle=Select Type
+TypeSelectionDialog.lowerLabel=&Qualifier:
+TypeSelectionDialog.upperLabel=&Matching types:
+TypeSelectionDialog.notypes.title=Type Selection
+TypeSelectionDialog.notypes.message=No types available.
+TypeSelectionDialog.error2Message=Unexpected exception. See log for details.
+TypeSelectionDialog.error2Title=Exception
+TypeSelectionDialog.error3Message=Unexpected exception. See log for details.
+TypeSelectionDialog.error3Title=Exception
+
+ExceptionDialog.seeErrorLogMessage= See error log for more details.
+
+MainTypeSelectionDialog.errorTitle=Error
+MultiMainTypeSelectionDialog.errorTitle=Error
+
+######
+## dnd
+######
+LocalSelectionTransfer.errorMessage=Received wrong transfer data.
+
+###########
+## preferences
+###########
+BuildPathsPropertyPage.error.message=An error occurred while setting the build path
+BuildPathsPropertyPage.error.title=Error Setting Build Path
+BuildPathsPropertyPage.no_java_project.message=Not a Java project.
+BuildPathsPropertyPage.closed_project.message=Java information is not available for a closed project.
+
+ClasspathVariablesPreferencePage.description=A classpath variable can be added to a project's class path. It can be used to define the location of a JAR file that isn't part of the workspace. The reserved class path variables JRE_LIB, JRE_SRC, JRE_SRCROOT are set internally depending on the JRE setting.
+
+ImportOrganizePreferencePage.description=Preferences used by the Organize Imports action:
+
+ImportOrganizePreferencePage.order.label=Define the &sorting order of import statements. A package name prefix (e.g. org.eclipse) is a valid entry.
+
+ImportOrganizePreferencePage.order.add.button=&New..
+ImportOrganizePreferencePage.order.edit.button=&Edit...
+ImportOrganizePreferencePage.order.up.button=&Up
+ImportOrganizePreferencePage.order.down.button=Do&wn
+ImportOrganizePreferencePage.order.remove.button=&Remove
+ImportOrganizePreferencePage.order.load.button=&Load...
+ImportOrganizePreferencePage.order.save.button=Sa&ve...
+ImportOrganizePreferencePage.ignoreLowerCase.label=Do not create imports for &types starting with a lowercase letter
+
+ImportOrganizePreferencePage.threshold.label=Number of &qualified imports before .* is used (e.g. org.eclipse.*):
+ImportOrganizePreferencePage.error.invalidthreshold=Invalid import number.
+
+ImportOrganizePreferencePage.loadDialog.title=Load Import Order from File
+ImportOrganizePreferencePage.loadDialog.error.title=Load Import Order
+ImportOrganizePreferencePage.loadDialog.error.message=Loading failed. Not a valid import order file.
+
+ImportOrganizePreferencePage.saveDialog.title=Save Import Order to File
+ImportOrganizePreferencePage.saveDialog.error.title=Save Import Order
+ImportOrganizePreferencePage.saveDialog.error.message=Writing import order file failed.
+
+
+ImportOrganizeInputDialog.title=Import Order Entry
+ImportOrganizeInputDialog.message=&Package name or package name prefix:
+ImportOrganizeInputDialog.browse.button=&Browse...
+ImportOrganizeInputDialog.ChoosePackageDialog.title=Package Selection
+ImportOrganizeInputDialog.ChoosePackageDialog.description=Choose package name or package prefix:
+ImportOrganizeInputDialog.ChoosePackageDialog.empty=No packages available.
+ImportOrganizeInputDialog.error.enterName=Enter a package name.
+ImportOrganizeInputDialog.error.invalidName=Not a valid package name. {0}
+ImportOrganizeInputDialog.error.entryExists=Package name already exists in list.
+
+JavaBasePreferencePage.description=General settings for Java development:
+
+JavaBasePreferencePage.linkPackageView= L&ink Package Explorer selection to active editor
+JavaBasePreferencePage.dblClick=A&ction on double-clicking in Package Explorer on container is  'Go Into'
+JavaBasePreferencePage.cuChildren=S&how members in Package Explorer
+
+JavaBasePreferencePage.updateJavaViews=Update Java views:
+JavaBasePreferencePage.onSave=On &save only
+JavaBasePreferencePage.whileEditing=While &editing
+JavaBasePreferencePage.notice.outliner=Note: This preference is not applied to already opened views (Outline view is always updated while editing)
+
+JavaBasePreferencePage.typeHierarchySettings=Type Hierarchy settings
+JavaBasePreferencePage.linkTypeHierarchy=Lin&k Type Hierarchy view selection to active editor
+JavaBasePreferencePage.openTypeHierarchy=When opening a Type Hierarchy:
+JavaBasePreferencePage.inPerspective=Open a new Type Hierarchy &Perspective
+JavaBasePreferencePage.inView=Show the &Type Hierarchy View in the current perspective
+JavaBasePreferencePage.doubleclick.action=Action on double click in the Package Explorer:
+JavaBasePreferencePage.doubleclick.gointo=&Go into the selected element
+JavaBasePreferencePage.doubleclick.expand=E&xpand the selected element
+
+JavaBasePreferencePage.linkSettings.text=Link settings:
+JavaBasePreferencePage.linkJavaBrowsingViewsCheckbox.text=&Link Java Browsing views selection to active editor
+
+
+NewJavaProjectPreferencePage.description=Specify the classpath entries used as default by the New Java Project creation wizard:
+
+NewJavaProjectPreferencePage.sourcefolder.label=As source and output location use:
+NewJavaProjectPreferencePage.sourcefolder.project=&Project
+NewJavaProjectPreferencePage.sourcefolder.folder=&Folders
+NewJavaProjectPreferencePage.folders.src=&Source folder name:
+NewJavaProjectPreferencePage.folders.bin=&Output location name:
+
+NewJavaProjectPreferencePage.jrelibrary.label=As &JRE library use:
+NewJavaProjectPreferencePage.jre_variable.description=JRE_LIB variable
+NewJavaProjectPreferencePage.jre_container.description=JRE container
+
+NewJavaProjectPreferencePage.folders.error.namesempty=Enter folder names.
+NewJavaProjectPreferencePage.folders.error.invalidsrcname=Invalid source folder name: {0}
+NewJavaProjectPreferencePage.folders.error.invalidbinname=Invalid output folder name: {0}
+
+NewJavaProjectPreferencePage.error.decode=Error while decoding JRE entry
+
+PHPEditorPreferencePage.updatesOnNextChangeIinEditor.label=Note: Updates on next change in the editor
+PHPEditorPreferencePage.annotationsTab.title= Annotation&s
+PHPEditorPreferencePage.showQuickFixables=&Indicate problems solvable with Quick Fix in vertical ruler
+PHPEditorPreferencePage.description=PHP Editor settings:
+PHPEditorPreferencePage.font=Text Font:
+PHPEditorPreferencePage.multiLineComment=Multi-line comment
+PHPEditorPreferencePage.singleLineComment=Single-line comment
+PHPEditorPreferencePage.tags=PHP tags
+PHPEditorPreferencePage.keywords=Keywords
+PHPEditorPreferencePage.functionNames=Predefined function names
+PHPEditorPreferencePage.variables=Variables
+PHPEditorPreferencePage.constants=Constants
+PHPEditorPreferencePage.types=Types
+PHPEditorPreferencePage.strings=Strings
+PHPEditorPreferencePage.others=Others
+PHPEditorPreferencePage.phpDocKeywords=PHPDoc keywords
+PHPEditorPreferencePage.phpDocHtmlTags=PHPDoc HTML tags
+PHPEditorPreferencePage.phpDocLinks=PHPDoc links
+PHPEditorPreferencePage.phpDocOthers=PHPDoc others
+PHPEditorPreferencePage.backgroundColor=Background color
+PHPEditorPreferencePage.systemDefault=S&ystem Default
+PHPEditorPreferencePage.custom=C&ustom:
+PHPEditorPreferencePage.foreground=Fo&reground:
+PHPEditorPreferencePage.color=C&olor:
+PHPEditorPreferencePage.bold=&Bold
+PHPEditorPreferencePage.preview=Preview:
+PHPEditorPreferencePage.textFont=Text &font:
+PHPEditorPreferencePage.displayedTabWidth=Displayed &tab width:
+PHPEditorPreferencePage.insertSpaceForTabs=Ins&ert space for tabs (see Code Formatter preference page)
+PHPEditorPreferencePage.showOverviewRuler=Show overview &ruler
+PHPEditorPreferencePage.highlightMatchingBrackets=Highlight &matching brackets
+PHPEditorPreferencePage.matchingBracketsHighlightColor=Matching &brackets highlight color:
+PHPEditorPreferencePage.highlightCurrentLine=Hi&ghlight current line
+PHPEditorPreferencePage.currentLineHighlightColor=Current &line highlight color:
+PHPEditorPreferencePage.showPrintMargin=Sho&w print margin
+PHPEditorPreferencePage.printMarginColor=Print m&argin color:
+PHPEditorPreferencePage.printMarginColumn=Print margin col&umn:
+PHPEditorPreferencePage.findScopeColor=F&ind Scope Color:
+PHPEditorPreferencePage.linkedPositionColor=Lin&ked Position Color:
+PHPEditorPreferencePage.insertSingleProposalsAutomatically=Insert single &proposals automatically
+PHPEditorPreferencePage.showOnlyProposalsVisibleInTheInvocationContext=Show only proposals &visible in the invocation context
+PHPEditorPreferencePage.presentProposalsInAlphabeticalOrder=Present proposals in a&lphabetical order
+PHPEditorPreferencePage.enableAutoActivation=&Enable auto activation
+PHPEditorPreferencePage.automaticallyAddImportInsteadOfQualifiedName=Automatically add &import instead of qualified name
+PHPEditorPreferencePage.insertCompletion=&Insert completion
+PHPEditorPreferencePage.fillArgumentNamesOnMethodCompletion=&Fill argument names on method completion
+PHPEditorPreferencePage.guessArgumentNamesOnMethodCompletion=&Guess filled argument names
+PHPEditorPreferencePage.autoActivationDelay=Auto activation dela&y:
+PHPEditorPreferencePage.autoActivationTriggersForPHP=Auto activation &triggers for PHP:
+PHPEditorPreferencePage.autoActivationTriggersForPHPDoc=Auto activation triggers for &PHPDoc:
+PHPEditorPreferencePage.autoActivationTriggersForHTML=Auto activation triggers for &HTML:
+PHPEditorPreferencePage.backgroundForCompletionProposals=&Background for completion proposals:
+PHPEditorPreferencePage.foregroundForCompletionProposals=&Foreground for completion proposals:
+PHPEditorPreferencePage.backgroundForMethodParameters=Bac&kground for method parameters:
+PHPEditorPreferencePage.foregroundForMethodParameters=Fo&reground for method parameters:
+PHPEditorPreferencePage.backgroundForCompletionReplacement=Back&ground for completion replacement:
+PHPEditorPreferencePage.foregroundForCompletionReplacement=Foregr&ound for completion replacement:
+PHPEditorPreferencePage.general=Appeara&nce
+PHPEditorPreferencePage.colors=Synta&x
+PHPEditorPreferencePage.codeAssist=Code A&ssist
+PHPEditorPreferencePage.change=C&hange...
+PHPEditorPreferencePage.empty_input=Empty input
+PHPEditorPreferencePage.invalid_input=''{0}'' is not a valid input.
+PHPEditorPreferencePage.lineNumberColor=Line number foreground color:
+PHPEditorPreferencePage.matchingBracketsHighlightColor2=Matching brackets highlight
+PHPEditorPreferencePage.currentLineHighlighColor=Current line highlight
+PHPEditorPreferencePage.printMarginColor2=Print margin
+PHPEditorPreferencePage.findScopeColor2=Find scope
+PHPEditorPreferencePage.linkedPositionColor2=Linked position
+PHPEditorPreferencePage.linkColor2=Link
+PHPEditorPreferencePage.synchronizeOnCursor=Synchroni&ze outline selection on cursor move (editor must be reopened)
+PHPEditorPreferencePage.appearanceOptions=Appearance co&lor options:
+PHPEditorPreferencePage.behaviourTab.title=Be&havior
+PHPEditorPreferencePage.closeStringsPHP=Automatically close str&ings in PHP mode
+PHPEditorPreferencePage.closeBracketsPHP=Automatically close &brackets and parenthesis in PHP mode
+PHPEditorPreferencePage.closeBraces=Automatically close bra&ces
+PHPEditorPreferencePage.closePHPDocs=Automatically close PHP&Docs and comments
+PHPEditorPreferencePage.wrapStrings=Smart PHP stri&ng wrapping
+PHPEditorPreferencePage.addPHPDocTags=Automatically add PHPDoc &tags
+PHPEditorPreferencePage.formatPHPDocs=Automatically format &PHPDocs and multi-line comments
+PHPEditorPreferencePage.smartPaste= Sma&rt pasting for correct indentation
+PHPEditorPreferencePage.smartHomeEnd= S&mart cursor positioning at line start and end
+PHPEditorPreferencePage.closeStringsHTML=Automatically close str&ings in HTML mode
+PHPEditorPreferencePage.closeBracketsHTML=Automatically close &brackets and parenthesis in HTML mode
+
+PHPEditorPreferencePage.hoverTab.title= Ho&vers
+
+
+JavaElementInfoPage.binary=binary
+JavaElementInfoPage.classpath_entry_kind=Classpath entry kind: 
+JavaElementInfoPage.library=library
+JavaElementInfoPage.nameLabel=Name: 
+JavaElementInfoPage.not_present=not present
+JavaElementInfoPage.package=Package: 
+JavaElementInfoPage.package_contents=Package contents: 
+JavaElementInfoPage.project=project
+JavaElementInfoPage.resource_path=Resource path: 
+JavaElementInfoPage.source=source
+JavaElementInfoPage.variable=variable
+JavaElementInfoPage.variable_path=Variable path:
+JavaElementInfoPage.location=Location:
+
+JavadocConfigurationPropertyPage.IsPackageFragmentRoot.description=Specify the location (URL) of the documentation generated by PHPDoc. The Javadoc location will contain a file called 'package-list'. For example: \'http://www.sample-url.org/doc/\'
+JavadocConfigurationPropertyPage.IsIncorrectElement.description=PHPDoc location can only be attached to JAR files in projects or Java projects
+JavadocConfigurationPropertyPage.IsJavaProject.description=Specify the location (URL) of the project\'s PHPDoc documentation. This location is used by the PHPDoc export wizard as default value and by the \'Open External PHPDoc\' action. For example: \'file://c:/myworkspace/myproject/doc/\'.
+
+JavadocConfigurationBlock.location.label=PHPDoc &Location:
+JavadocConfigurationBlock.location.button=Bro&wse...
+
+JavadocConfigurationBlock.error.invalidurl=Not a valid URL: {0}
+JavadocConfigurationBlock.error.notafolder=Location does not exist.
+JavadocConfigurationBlock.warning.packagelistnotfound=Location does not contain file 'package-list'.
+
+JavadocConfigurationBlock.javadocLocationDialog.label=PHPDoc Location Selection
+JavadocConfigurationBlock.javadocLocationDialog.message=&Select PHPDoc location:
+
+JavadocConfigurationBlock.MalformedURL.error=Invalid URL
+
+JavadocConfigurationBlock.ValidateButton.label=&Validate...
+JavadocConfigurationBlock.InvalidLocation.message= Location is invalid. Location contains neither the file \'package-list\' nor \'index.html'.
+JavadocConfigurationBlock.ValidLocation.message= Location is valid. Files \'package-list\' and \'index.html\' found. Click OK to open in browser.
+JavadocConfigurationBlock.UnableToValidateLocation.message=Unable to validate location
+JavadocConfigurationBlock.MessageDialog.title=Validating PHPDoc Location
+JavadocConfigurationBlock.EmptyJavadocLocation.warning=Enter a javadoc location
+
+JavadocPreferencePage.description=Specify the location of the PHPDoc command to be used by the PHPDoc export wizard. Location must be an absolute path.
+JavadocPreferencePage.command.label=&PHPDoc command:
+JavadocPreferencePage.command.button=Bro&wse...
+
+JavadocPreferencePage.error.notexists=PHPDoc command does not exist
+
+JavadocPreferencePage.browsedialog.title=PHPDoc Command Selection
+
+SourceAttachmentPropertyPage.error.title=Error Attaching Source
+SourceAttachmentPropertyPage.error.message=An error occurred while associating the source
+
+SourceAttachmentPropertyPage.noarchive.message=Source can only be attached to JAR files in Java projects.
+SourceAttachmentPropertyPage.containerentry.message=JAR belongs to the container ''{0}''.\nTo configure the source attachment, go directly to the corresponding configuration page (For example for JREs go to ''Installed JREs'' page in the preferences).
+
+AppearancePreferencePage.description= Appearance of Java elements in viewers:
+AppearancePreferencePage.methodreturntype.label= Show &method return types
+AppearancePreferencePage.overrideindicator.label= Show &override indicators in outline and hierarchy
+AppearancePreferencePage.pkgNamePatternEnable.label= &Compress package name segments (except for the last one)
+AppearancePreferencePage.pkgNamePattern.label= Com&pression pattern (e.g. given package name 'net.sourceforge.phpdt' pattern '.' will compress it to '..jdt',  '0' to 'jdt', '1~.' to 'o~.e~.jdt'):
+
+AppearancePreferencePage.showMembersInPackagesView=S&how members in Package Explorer
+AppearancePreferencePage.stackViewsVerticallyInTheJavaBrowsingPerspective=&Stack views vertically in the Java Browsing perspective
+AppearancePreferencePage.preferenceOnlyEffectiveForNewPerspectives=Note: This preference will only take effect on new perspectives
+AppearancePreferencePage.packageNameCompressionPattern.error.isEmpty=Enter a package name compression pattern
+
+CodeFormatterPreferencePage.description=Options for the PHP Code Formatter:
+
+CodeFormatterPreferencePage.empty_input=Empty input
+CodeFormatterPreferencePage.invalid_input=''{0}'' is not a valid input.
+
+CodeFormatterPreferencePage.newline_opening_braces.label=I&nsert a new line before an opening brace
+CodeFormatterPreferencePage.newline_control_statement.label=Insert new &lines in control statements
+CodeFormatterPreferencePage.newline_clear_lines=Clear all &blank lines
+CodeFormatterPreferencePage.newline_else_if.label=&Insert new line between 'else if'
+CodeFormatterPreferencePage.newline_empty_block.label=In&sert a new line inside an empty block
+CodeFormatterPreferencePage.split_line.label=Ma&ximum line length:
+CodeFormatterPreferencePage.style_compact_assignement.label=&Compact assignment
+CodeFormatterPreferencePage.style_compact_arrays.label=Compact &arrays
+CodeFormatterPreferencePage.style_compact_string_concatenation.label=Compact &string concatenation
+CodeFormatterPreferencePage.tab_char.label=Indentation is represented by a &tab
+CodeFormatterPreferencePage.tab_size.label=&Number of spaces representing a tab:
+
+CodeFormatterPreferencePage.tab.newline.tabtitle=Ne&w Lines
+CodeFormatterPreferencePage.tab.linesplit.tabtitle=Line S&plitting
+CodeFormatterPreferencePage.tab.style.tabtitle=St&yle
+
+CompilerPreferencePage.description=Options for the Java compiler:\nNote that a full rebuild is required to make changes effective.
+CompilerPreferencePage.generation.tabtitle=Classfile &Generation
+CompilerPreferencePage.warnings.tabtitle=&Errors and Warnings
+CompilerPreferencePage.compliance.tabtitle=&JDK Compliance
+CompilerPreferencePage.others.tabtitle=&Other
+
+CompilerPreferencePage.warnings.description=Select the severity level for the following problems:
+
+CompilerPreferencePage.variable_attr.label=Add &variable attributes to generated class files (used by the debugger)
+CompilerPreferencePage.line_number_attr.label=Add &line number attributes to generated class files (used by the debugger)
+CompilerPreferencePage.source_file_attr.label=Add &source file name to generated class file (used by the debugger)
+CompilerPreferencePage.codegen_unused_local.label=Preserve &unused local variables (i.e. never read) 
+
+CompilerPreferencePage.compiler_compliance.label=&Compiler compliance level:
+CompilerPreferencePage.default_settings.label=&Use default compliance settings
+CompilerPreferencePage.source_compatibility.label=&Source compatibility:
+CompilerPreferencePage.codegen_targetplatform.label=Ge&nerated .class files compatibility:
+CompilerPreferencePage.pb_assert_as_identifier.label=&Report 'assert' as identifier:
+
+CompilerPreferencePage.pb_unreachable_code.label=&Unreachable code:
+CompilerPreferencePage.pb_invalid_import.label=Unresol&vable import statements:
+CompilerPreferencePage.pb_overriding_pkg_dflt.label=&Methods overridden but not package visible:
+CompilerPreferencePage.pb_method_naming.label=Me&thods with a constructor name:
+CompilerPreferencePage.pb_deprecation.label=Usage of de&precated API:
+CompilerPreferencePage.pb_hidden_catchblock.label=&Hidden catch blocks:
+CompilerPreferencePage.pb_unused_imports.label=Unu&sed includes:
+CompilerPreferencePage.pb_unused_local.label=Unused &local variables (i.e. never read):
+CompilerPreferencePage.pb_unused_parameter.label=U&nused parameters (i.e. never read):
+CompilerPreferencePage.pb_synth_access_emul.label=A&ccess to a non-accessible member of an enclosing type:
+CompilerPreferencePage.pb_non_externalized_strings.label=Non-e&xternalized strings:
+CompilerPreferencePage.pb_max_per_unit.label=Maximum number of problems &reported per compilation unit:
+
+CompilerPreferencePage.resource_filter.description=Enter resources and resource types that should not be copied to the output folder during a build. List is comma separated (e.g. '*.doc, plugin.xml, scripts/')
+CompilerPreferencePage.resource_filter.label=Filtered &Resources:
+CompilerPreferencePage.build_invalid_classpath.label=Stop &building when an invalid classpath is detected
+
+CompilerPreferencePage.error=Error
+CompilerPreferencePage.warning=Warning
+CompilerPreferencePage.ignore=Ignore
+
+CompilerPreferencePage.jvm11=JVM 1.1
+CompilerPreferencePage.jvm12=JVM 1.2
+CompilerPreferencePage.jvm13=JVM 1.3
+CompilerPreferencePage.jvm14=JVM 1.4
+
+CompilerPreferencePage.version11=1.1
+CompilerPreferencePage.version12=1.2
+CompilerPreferencePage.version13=1.3
+CompilerPreferencePage.version14=1.4
+
+CompilerPreferencePage.needsbuild.title=Compiler Settings Changed
+CompilerPreferencePage.needsbuild.message=The compiler settings have changed. A full rebuild is required to make changes effective. Do the full build now?
+
+CompilerPreferencePage.builderror.title=Compiler Settings
+CompilerPreferencePage.builderror.message=Problem while building. Check log for details.
+
+CompilerPreferencePage.cpl13src14.error=In 1.3 compliance level, source compatibility can not be 1.4
+CompilerPreferencePage.cpl13trg14.error=In 1.3 compliance level, the classfile compatibility can not be 1.4
+CompilerPreferencePage.src14asrterr.error=With 1.4 source compatibility, 'assert' can not be an identifier.
+CompilerPreferencePage.src14tgt14.error=With 1.4 source compatibility, the classfile compatibility must be 1.4
+
+CompilerPreferencePage.empty_input=Number of problems can not be empty.
+CompilerPreferencePage.invalid_input={0} is not a valid number of problems.
+
+CompilerPreferencePage.filter.invalidsegment.error=Filter is invalid: {0}
+
+CodeGenerationPreferencePage.description=Options for Code Generation:
+
+CodeGenerationPreferencePage.gettersetter.label=Getter and Setter Creation:
+CodeGenerationPreferencePage.gettersetter.prefix.checkbox=Remove &prefix from field names
+CodeGenerationPreferencePage.gettersetter.prefix.list=P&refix list (comma separated):
+CodeGenerationPreferencePage.gettersetter.suffix.checkbox=Remove &suffix from field names
+CodeGenerationPreferencePage.gettersetter.suffix.list=S&uffix list (comma separated):
+
+CodeGenerationPreferencePage.comments.label=Comments Creation:
+CodeGenerationPreferencePage.javadoc_comment.label=Create &PHPDoc comments for methods and types (template 'typecomment')
+CodeGenerationPreferencePage.see_comment.label=Create &non-PHPDoc comments for overridden methods
+CodeGenerationPreferencePage.file_comment.label=Create &file comments for new files (template 'filecomment')
+
+CodeGenerationPreferencePage.gettersetter.error.emptyprefix=Prefix strings can not contain an empty entry.
+CodeGenerationPreferencePage.gettersetter.error.emptysuffix=Suffix strings can not contain an empty entry.
+CodeGenerationPreferencePage.gettersetter.error.invalidprefix={0} is not a valid prefix.
+CodeGenerationPreferencePage.gettersetter.error.invalidsuffix={0} is not a valid suffix.
+
+###########
+## viewsupport
+###########
+JavaImageLabelprovider.assert.wrongImage=no image for this JavaElement Type
+
+JavaTextLabelProvider.default_package=(default package)
+JavaTextLabelProvider.import_declarations=include declarations
+JavaTextLabelProvider.initializer=\{...\}
+
+JavaElementLabels.default_package=(default package) 
+JavaElementLabels.import_container=include declarations
+JavaElementLabels.initializer=\{...\}
+JavaElementLabels.concat_string=\ -\ 
+JavaElementLabels.comma_string=,\ 
+JavaElementLabels.declseparator_string=\ :\ 
+
+StatusBarUpdater.num_elements_selected={0} items selected
+StatusBarUpdater.twopart={0} - {1}
+StatusBarUpdater.threepart={0} - {1} - {2}
+
+
+#########
+## jdt.ui
+#########
+JavaElementContentProvider.errorMessage=Child not present
+
+#########
+## util
+#########
+
+OpenTypeHierarchyUtil.error.open_view=Problems opening Type Hierarchy View
+OpenTypeHierarchyUtil.error.open_perspective=Problems opening Type Hierarchy Perspective
+OpenTypeHierarchyUtil.error.open_editor=Problems opening Java Editor
+OpenTypeHierarchyUtil.error.no_perspective=Type Hierarchy perspective not found
+OpenTypeHierarchyUtil.selectionDialog.title=Open In Type Hierarchy
+OpenTypeHierarchyUtil.selectionDialog.message=&Select the type to be shown in the Type Hierarchy:
+
+TypeInfoLabelProvider.default_package=(default package)
+TypeInfoLabelProvider.dash=\ - 
+
+JavaUIHelp.link.label=PHPDoc for {0}
+
+#########
+# DnD
+#########
+ResourceTransferDragAdapter.cannot_delete_resource=Cannot delete resources
+ResourceTransferDragAdapter.moving_resource=Moving Resources via DND
+ResourceTransferDragAdapter.cannot_delete_files=Cannot delete the following file(s)
+
+#########
+# Spelling
+#########
+
+Spelling.dictionary.file.extension=dictionary
+Spelling.error.label=The word ''{0}'' is not correctly spelled
+Spelling.correct.label=Change to ''{0}''
+Spelling.add.info=Adds the word ''{0}'' to the dictionary
+Spelling.add.label=Add ''{0}'' to dictionary
+Spelling.ignore.info=Always ignores ''{0}'' during the current session
+Spelling.ignore.label=Always ignore ''{0}''
+Spelling.case.label=Change to upper case
+Spelling.error.case.label= The word ''{0}'' should have an initial upper case letter
+
+#########
+# misc
+#########
+
+AddImportOnSelectionAction.error.message=AddImportOnSelectionAction: Failed to resolve TypeRef: {0}
+
+CompilationUnitDocumentProvider.problemsCreatingBuffer=Problems creating buffer
+
+_ClassFileDocumentProvider.problemsCreatingBuffer=Problems creating buffer
+
+NewMethodCompletionProposal.method=Method {0}
+
+JavaAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line
+JavaTextHover.createTextHover=Could not create java text hover
+
+HTMLTextPresenter.ellipsis=
+HTML2TextReader.dash=- 
+
+JavaEditor.codeassist.noCompletions=No completions available.
+
+OptionalMessageDialog.dontShowAgain= Don't show this message again
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java
new file mode 100644 (file)
index 0000000..20ed5bb
--- /dev/null
@@ -0,0 +1,924 @@
+package net.sourceforge.phpdt.internal.ui;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+public class PHPUiImages {
+
+       protected static final String NAME_PREFIX = "net.sourceforge.phpdt.internal.ui.";
+
+       protected static final int NAME_PREFIX_LENGTH = NAME_PREFIX.length();
+
+       protected static URL fgIconBaseURL = null;
+
+       // static {
+       // String pathSuffix = "icons/";
+       // try {
+       // fgIconBaseURL =
+       // new URL(
+       // PHPeclipsePlugin
+       // .getDefault()
+       // .getDescriptor()
+       // .getInstallURL(),
+       // pathSuffix);
+       // } catch (MalformedURLException e) {
+       // PHPeclipsePlugin.log(e);
+       // }
+       // }
+
+       // Determine display depth. If depth > 4 then we use high color images.
+       // Otherwise low color
+       // images are used
+       static {
+               fgIconBaseURL = WebUI.getDefault().getBundle().getEntry(
+                               "/icons/"); //$NON-NLS-1$
+       }
+
+       private static ImageRegistry fgImageRegistry = null;
+
+       private static HashMap fgAvoidSWTErrorMap = null;
+
+       protected static final String OBJ_PREFIX = "obj16";
+
+       protected static final String OVR_PREFIX = "ovr16";
+
+       protected static final String CTOOL_PREFIX = "ctool16";
+
+       public static final String IMG_CLASS = NAME_PREFIX
+                       + "class_default_obj.gif";
+
+       public static final String IMG_DEFINE = NAME_PREFIX + "define_obj.gif";
+
+       public static final String IMG_BUILTIN = NAME_PREFIX + "builtin_obj.gif";
+
+       public static final String IMG_FUN = NAME_PREFIX + "fun_obj.gif";
+
+       public static final String IMG_INC = NAME_PREFIX + "impc_obj.gif";
+
+       public static final String IMG_VAR = NAME_PREFIX + "var_obj.gif";
+
+       public static final String IMG_TABLE = NAME_PREFIX + "table_obj.gif";
+
+       public static final String IMG_COLUMN = NAME_PREFIX + "column_obj.gif";
+
+       public static final String IMG_OBJS_WARNING = NAME_PREFIX
+                       + "warning_obj.gif";
+
+       public static final String IMG_OBJS_INFO = NAME_PREFIX + "info_obj.gif";
+
+       public static final String IMG_CTOOLS_PHP_PAGE = NAME_PREFIX
+                       + "php_page.gif";
+
+       public static final String IMG_CTOOLS_PHP = NAME_PREFIX + "php.gif";
+
+       public static final String IMG_CLEAR = NAME_PREFIX + "clear.gif";
+
+       public static final ImageDescriptor DESC_CLASS = createManaged(OBJ_PREFIX,
+                       IMG_CLASS);
+
+       public static final ImageDescriptor DESC_DEFINE = createManaged(OBJ_PREFIX,
+                       IMG_DEFINE);
+
+       public static final ImageDescriptor DESC_BUILTIN = createManaged(
+                       OBJ_PREFIX, IMG_BUILTIN);
+
+       public static final ImageDescriptor DESC_FUN = createManaged(OBJ_PREFIX,
+                       IMG_FUN);
+
+       public static final ImageDescriptor DESC_INC = createManaged(OBJ_PREFIX,
+                       IMG_INC);
+
+       public static final ImageDescriptor DESC_VAR = createManaged(OBJ_PREFIX,
+                       IMG_VAR);
+
+       public static final ImageDescriptor DESC_TABLE = createManaged(OBJ_PREFIX,
+                       IMG_TABLE);
+
+       public static final ImageDescriptor DESC_COLUMN = createManaged(OBJ_PREFIX,
+                       IMG_COLUMN);
+
+       public static final ImageDescriptor DESC_OBJS_WARNING = createManaged(
+                       OBJ_PREFIX, IMG_OBJS_WARNING);
+
+       public static final ImageDescriptor DESC_OBJS_INFO = createManaged(
+                       OBJ_PREFIX, IMG_OBJS_INFO);
+
+       public static final ImageDescriptor DESC_CTOOL_PHP_PAGE = createManaged(
+                       CTOOL_PREFIX, IMG_CTOOLS_PHP_PAGE);
+
+       public static final ImageDescriptor DESC_CTOOL_PHP = createManaged(
+                       CTOOL_PREFIX, IMG_CTOOLS_PHP);
+
+       public static final ImageDescriptor DESC_CLEAR = createManaged(OBJ_PREFIX,
+                       IMG_CLEAR);
+
+       /*
+        * Set of predefined Image Descriptors.
+        */
+       private static final String T_OBJ = "obj16"; //$NON-NLS-1$
+
+       private static final String T_OVR = "ovr16"; //$NON-NLS-1$
+
+       private static final String T_WIZBAN = "wizban"; //$NON-NLS-1$
+
+       private static final String T_CLCL = "clcl16"; //$NON-NLS-1$
+
+       private static final String T_DLCL = "dlcl16"; //$NON-NLS-1$
+
+       private static final String T_ELCL = "elcl16"; //$NON-NLS-1$
+
+       private static final String T_CTOOL = "ctool16"; //$NON-NLS-1$
+
+       private static final String T_CVIEW = "cview16"; //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_NEWCLASS = create(T_WIZBAN,
+                       "newclass_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_ELCL_FILTER = create(T_ELCL,
+                       "filter_ps.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_DLCL_FILTER = create(T_DLCL,
+                       "filter_ps.gif"); //$NON-NLS-1$
+
+       /*
+        * Available cached Images in the Java plugin image registry.
+        */
+       public static final String IMG_MISC_PUBLIC = NAME_PREFIX
+                       + "methpub_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_MISC_PROTECTED = NAME_PREFIX
+                       + "methpro_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_MISC_PRIVATE = NAME_PREFIX
+                       + "methpri_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_MISC_DEFAULT = NAME_PREFIX
+                       + "methdef_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_FIELD_PUBLIC = NAME_PREFIX
+                       + "field_public_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_FIELD_PROTECTED = NAME_PREFIX
+                       + "field_protected_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_FIELD_PRIVATE = NAME_PREFIX
+                       + "field_private_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_FIELD_DEFAULT = NAME_PREFIX
+                       + "field_default_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_GHOST = NAME_PREFIX + "ghost.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_SEARCH_TSK = NAME_PREFIX
+                       + "search_tsk.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_PACKDECL = NAME_PREFIX
+                       + "packd_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_IMPDECL = NAME_PREFIX + "imp_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_IMPCONT = NAME_PREFIX + "impc_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_JSEARCH = NAME_PREFIX
+                       + "jsearch_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_SEARCH_DECL = NAME_PREFIX
+                       + "search_decl_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_SEARCH_REF = NAME_PREFIX
+                       + "search_ref_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_CLASS = NAME_PREFIX + "class_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_CLASSALT = NAME_PREFIX
+                       + "classfo_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_CLASS_DEFAULT = NAME_PREFIX
+                       + "class_default_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_INTERFACE = NAME_PREFIX + "int_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_INTERFACEALT = NAME_PREFIX
+                       + "intf_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_INTERFACE_DEFAULT = NAME_PREFIX
+                       + "int_default_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_CUNIT = NAME_PREFIX + "phpedit.png"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_CUNIT_RESOURCE = NAME_PREFIX
+                       + "jcu_resource_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_CFILE = NAME_PREFIX + "classf_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_CFILECLASS = NAME_PREFIX
+                       + "class_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_CFILEINT = NAME_PREFIX + "int_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_LOGICAL_PACKAGE = NAME_PREFIX
+                       + "logical_package_obj.gif";//$NON-NLS-1$
+
+       public static final String IMG_OJS_EMPTY_LOGICAL_PACKAGE = NAME_PREFIX
+                       + "empty_logical_package_obj.gif";//$NON-NLS-1$
+
+       public static final String IMG_OBJS_PACKAGE = NAME_PREFIX
+                       + "package_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_EMPTY_PACK_RESOURCE = NAME_PREFIX
+                       + "empty_pack_fldr_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_EMPTY_PACKAGE = NAME_PREFIX
+                       + "empty_pack_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_PACKFRAG_ROOT = NAME_PREFIX
+                       + "packagefolder_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_MISSING_PACKFRAG_ROOT = NAME_PREFIX
+                       + "packagefolder_nonexist_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_MISSING_JAR = NAME_PREFIX
+                       + "jar_nonexist_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_JAR = NAME_PREFIX + "jar_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_EXTJAR = NAME_PREFIX + "jar_l_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_JAR_WSRC = NAME_PREFIX
+                       + "jar_src_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_EXTJAR_WSRC = NAME_PREFIX
+                       + "jar_lsrc_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_ENV_VAR = NAME_PREFIX
+                       + "envvar_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_MISSING_ENV_VAR = NAME_PREFIX
+                       + "envvar_nonexist_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_JAVA_MODEL = NAME_PREFIX
+                       + "java_model_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_UNKNOWN = NAME_PREFIX
+                       + "unknown_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_LIBRARY = NAME_PREFIX
+                       + "library_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_JAVADOCTAG = NAME_PREFIX
+                       + "jdoc_tag_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_HTMLTAG = NAME_PREFIX
+                       + "html_tag_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_TEMPLATE = NAME_PREFIX
+                       + "template_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_EXCEPTION = NAME_PREFIX
+                       + "jexception_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_ERROR = NAME_PREFIX
+                       + "jrtexception_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_BREAKPOINT_INSTALLED = NAME_PREFIX
+                       + "brkpi_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_FIXABLE_PROBLEM = NAME_PREFIX
+                       + "quickfix_warning_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_FIXABLE_ERROR = NAME_PREFIX
+                       + "quickfix_error_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_SNIPPET_EVALUATING = NAME_PREFIX
+                       + "jsbook_run_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_REFACTORING_FATAL = NAME_PREFIX
+                       + "fatalerror_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_REFACTORING_ERROR = NAME_PREFIX
+                       + "error_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_REFACTORING_WARNING = NAME_PREFIX
+                       + "warning_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_REFACTORING_INFO = NAME_PREFIX
+                       + "info_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_NLS_TRANSLATE = NAME_PREFIX
+                       + "translate.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_NLS_NEVER_TRANSLATE = NAME_PREFIX
+                       + "never_translate.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_NLS_SKIP = NAME_PREFIX + "skip.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_SEARCH_READACCESS = NAME_PREFIX
+                       + "occ_read.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_SEARCH_WRITEACCESS = NAME_PREFIX
+                       + "occ_write.gif"; //$NON-NLS-1$
+
+       public static final String IMG_OBJS_SEARCH_OCCURRENCE = NAME_PREFIX
+                       + "occ_match.gif"; //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_VIEW_ERRORWARNING_TAB = create(
+                       T_CVIEW, "errorwarning_tab.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_VIEW_CLASSFILEGENERATION_TAB = create(
+                       T_CVIEW, "classfilegeneration_tab.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_VIEW_JDKCOMPLIANCE_TAB = create(
+                       T_CVIEW, "jdkcompliance_tab.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_CLCL_FILTER = create(T_CLCL,
+                       "filter_ps.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_CLCL_CODE_ASSIST = create(T_CLCL,
+                       "metharg_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_DLCL_CODE_ASSIST = create(T_DLCL,
+                       "metharg_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_MISC_PUBLIC = createManaged(T_OBJ,
+                       IMG_MISC_PUBLIC);
+
+       public static final ImageDescriptor DESC_MISC_PROTECTED = createManaged(
+                       T_OBJ, IMG_MISC_PROTECTED);
+
+       public static final ImageDescriptor DESC_MISC_PRIVATE = createManaged(
+                       T_OBJ, IMG_MISC_PRIVATE);
+
+       public static final ImageDescriptor DESC_MISC_DEFAULT = createManaged(
+                       T_OBJ, IMG_MISC_DEFAULT);
+
+       public static final ImageDescriptor DESC_FIELD_PUBLIC = createManaged(
+                       T_OBJ, IMG_FIELD_PUBLIC); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_FIELD_PROTECTED = createManaged(
+                       T_OBJ, IMG_FIELD_PROTECTED); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_FIELD_PRIVATE = createManaged(
+                       T_OBJ, IMG_FIELD_PRIVATE); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_FIELD_DEFAULT = createManaged(
+                       T_OBJ, IMG_FIELD_DEFAULT); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_MENU_SHIFT_RIGHT = create(T_CTOOL,
+                       "shift_r_edit.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_MENU_SHIFT_LEFT = create(T_CTOOL,
+                       "shift_l_edit.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_GHOST = createManaged(T_OBJ,
+                       IMG_OBJS_GHOST);
+
+       public static final ImageDescriptor DESC_OBJS_PACKDECL = createManaged(
+                       T_OBJ, IMG_OBJS_PACKDECL);
+
+       public static final ImageDescriptor DESC_OBJS_IMPDECL = createManaged(
+                       T_OBJ, IMG_OBJS_IMPDECL);
+
+       public static final ImageDescriptor DESC_OBJS_IMPCONT = createManaged(
+                       T_OBJ, IMG_OBJS_IMPCONT);
+
+       public static final ImageDescriptor DESC_OBJS_JSEARCH = createManaged(
+                       T_OBJ, IMG_OBJS_JSEARCH);
+
+       public static final ImageDescriptor DESC_OBJS_SEARCH_DECL = createManaged(
+                       T_OBJ, IMG_OBJS_SEARCH_DECL);
+
+       public static final ImageDescriptor DESC_OBJS_SEARCH_REF = createManaged(
+                       T_OBJ, IMG_OBJS_SEARCH_REF);
+
+       public static final ImageDescriptor DESC_OBJS_CUNIT = createManaged(T_OBJ,
+                       IMG_OBJS_CUNIT);
+
+       public static final ImageDescriptor DESC_OBJS_CUNIT_RESOURCE = createManaged(
+                       T_OBJ, IMG_OBJS_CUNIT_RESOURCE);
+
+       public static final ImageDescriptor DESC_OBJS_CFILE = createManaged(T_OBJ,
+                       IMG_OBJS_CFILE);
+
+       public static final ImageDescriptor DESC_OBJS_CFILECLASS = createManaged(
+                       T_OBJ, IMG_OBJS_CFILECLASS);
+
+       public static final ImageDescriptor DESC_OBJS_CFILEINT = createManaged(
+                       T_OBJ, IMG_OBJS_CFILEINT);
+
+       public static final ImageDescriptor DESC_OBJS_PACKAGE = createManaged(
+                       T_OBJ, IMG_OBJS_PACKAGE);
+
+       public static final ImageDescriptor DESC_OBJS_EMPTY_LOGICAL_PACKAGE = createManaged(
+                       T_OBJ, IMG_OJS_EMPTY_LOGICAL_PACKAGE);
+
+       public static final ImageDescriptor DESC_OBJS_LOGICAL_PACKAGE = createManaged(
+                       T_OBJ, IMG_OBJS_LOGICAL_PACKAGE);
+
+       public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE_RESOURCES = createManaged(
+                       T_OBJ, IMG_OBJS_EMPTY_PACK_RESOURCE);
+
+       public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE = createManaged(
+                       T_OBJ, IMG_OBJS_EMPTY_PACKAGE);
+
+       public static final ImageDescriptor DESC_OBJS_PACKFRAG_ROOT = createManaged(
+                       T_OBJ, IMG_OBJS_PACKFRAG_ROOT);
+
+       public static final ImageDescriptor DESC_OBJS_MISSING_PACKFRAG_ROOT = createManaged(
+                       T_OBJ, IMG_OBJS_MISSING_PACKFRAG_ROOT);
+
+       public static final ImageDescriptor DESC_OBJS_JAVA_MODEL = createManaged(
+                       T_OBJ, IMG_OBJS_JAVA_MODEL);
+
+       public static final ImageDescriptor DESC_OBJS_CLASS = createManaged(T_OBJ,
+                       IMG_OBJS_CLASS);
+
+       public static final ImageDescriptor DESC_OBJS_CLASS_DEFAULT = createManaged(
+                       T_OBJ, IMG_OBJS_CLASS_DEFAULT);
+
+       public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PUBLIC = create(
+                       T_OBJ, "innerclass_public_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_INNER_CLASS_DEFAULT = create(
+                       T_OBJ, "innerclass_default_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PROTECTED = create(
+                       T_OBJ, "innerclass_protected_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PRIVATE = create(
+                       T_OBJ, "innerclass_private_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_CLASSALT = createManaged(
+                       T_OBJ, IMG_OBJS_CLASSALT);
+
+       public static final ImageDescriptor DESC_OBJS_INTERFACE = createManaged(
+                       T_OBJ, IMG_OBJS_INTERFACE);
+
+       public static final ImageDescriptor DESC_OBJS_INTERFACE_DEFAULT = createManaged(
+                       T_OBJ, IMG_OBJS_INTERFACE_DEFAULT);
+
+       public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PUBLIC = create(
+                       T_OBJ, "innerinterface_public_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_DEFAULT = create(
+                       T_OBJ, "innerinterface_default_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PROTECTED = create(
+                       T_OBJ, "innerinterface_protected_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PRIVATE = create(
+                       T_OBJ, "innerinterface_private_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_INTERFACEALT = createManaged(
+                       T_OBJ, IMG_OBJS_INTERFACEALT);
+
+       public static final ImageDescriptor DESC_OBJS_JAR = createManaged(T_OBJ,
+                       IMG_OBJS_JAR);
+
+       public static final ImageDescriptor DESC_OBJS_MISSING_JAR = createManaged(
+                       T_OBJ, IMG_OBJS_MISSING_JAR);
+
+       public static final ImageDescriptor DESC_OBJS_EXTJAR = createManaged(T_OBJ,
+                       IMG_OBJS_EXTJAR);
+
+       public static final ImageDescriptor DESC_OBJS_JAR_WSRC = createManaged(
+                       T_OBJ, IMG_OBJS_JAR_WSRC);
+
+       public static final ImageDescriptor DESC_OBJS_EXTJAR_WSRC = createManaged(
+                       T_OBJ, IMG_OBJS_EXTJAR_WSRC);
+
+       public static final ImageDescriptor DESC_OBJS_ENV_VAR = createManaged(
+                       T_OBJ, IMG_OBJS_ENV_VAR);
+
+       public static final ImageDescriptor DESC_OBJS_MISSING_ENV_VAR = createManaged(
+                       T_OBJ, IMG_OBJS_MISSING_ENV_VAR);
+
+       public static final ImageDescriptor DESC_OBJS_LIBRARY = createManaged(
+                       T_OBJ, IMG_OBJS_LIBRARY);
+
+       public static final ImageDescriptor DESC_OBJS_JAVADOCTAG = createManaged(
+                       T_OBJ, IMG_OBJS_JAVADOCTAG);
+
+       public static final ImageDescriptor DESC_OBJS_HTMLTAG = createManaged(
+                       T_OBJ, IMG_OBJS_HTMLTAG);
+
+       public static final ImageDescriptor DESC_OBJS_TEMPLATE = createManaged(
+                       T_OBJ, IMG_OBJS_TEMPLATE);
+
+       public static final ImageDescriptor DESC_OBJS_EXCEPTION = createManaged(
+                       T_OBJ, IMG_OBJS_EXCEPTION);
+
+       public static final ImageDescriptor DESC_OBJS_BREAKPOINT_INSTALLED = createManaged(
+                       T_OBJ, IMG_OBJS_BREAKPOINT_INSTALLED);
+
+       public static final ImageDescriptor DESC_OBJS_ERROR = createManaged(T_OBJ,
+                       IMG_OBJS_ERROR);
+
+       public static final ImageDescriptor DESC_OBJS_FIXABLE_PROBLEM = createManaged(
+                       T_OBJ, IMG_OBJS_FIXABLE_PROBLEM);
+
+       public static final ImageDescriptor DESC_OBJS_FIXABLE_ERROR = createManaged(
+                       T_OBJ, IMG_OBJS_FIXABLE_ERROR);
+
+       public static final ImageDescriptor DESC_OBJS_SNIPPET_EVALUATING = createManaged(
+                       T_OBJ, IMG_OBJS_SNIPPET_EVALUATING);
+
+       public static final ImageDescriptor DESC_OBJS_DEFAULT_CHANGE = create(
+                       T_OBJ, "change.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_COMPOSITE_CHANGE = create(
+                       T_OBJ, "composite_change.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_CU_CHANGE = create(T_OBJ,
+                       "cu_change.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_FILE_CHANGE = create(T_OBJ,
+                       "file_change.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_TEXT_EDIT = create(T_OBJ,
+                       "text_edit.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_EXCLUSION_FILTER_ATTRIB = create(
+                       T_OBJ, "exclusion_filter_attrib.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_OUTPUT_FOLDER_ATTRIB = create(
+                       T_OBJ, "output_folder_attrib.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_SOURCE_ATTACH_ATTRIB = create(
+                       T_OBJ, "source_attach_attrib.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_JAVADOC_LOCATION_ATTRIB = create(
+                       T_OBJ, "javadoc_location_attrib.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OBJS_REFACTORING_FATAL = createManaged(
+                       T_OBJ, IMG_OBJS_REFACTORING_FATAL);
+
+       public static final ImageDescriptor DESC_OBJS_REFACTORING_ERROR = createManaged(
+                       T_OBJ, IMG_OBJS_REFACTORING_ERROR);
+
+       public static final ImageDescriptor DESC_OBJS_REFACTORING_WARNING = createManaged(
+                       T_OBJ, IMG_OBJS_REFACTORING_WARNING);
+
+       public static final ImageDescriptor DESC_OBJS_REFACTORING_INFO = createManaged(
+                       T_OBJ, IMG_OBJS_REFACTORING_INFO);
+
+       public static final ImageDescriptor DESC_OBJS_NLS_TRANSLATE = createManaged(
+                       T_OBJ, IMG_OBJS_NLS_TRANSLATE);
+
+       public static final ImageDescriptor DESC_OBJS_NLS_NEVER_TRANSLATE = createManaged(
+                       T_OBJ, IMG_OBJS_NLS_NEVER_TRANSLATE);
+
+       public static final ImageDescriptor DESC_OBJS_NLS_SKIP = createManaged(
+                       T_OBJ, IMG_OBJS_NLS_SKIP);
+
+       public static final ImageDescriptor DESC_OBJS_UNKNOWN = createManaged(
+                       T_OBJ, IMG_OBJS_UNKNOWN);
+
+       public static final ImageDescriptor DESC_OBJS_SEARCH_READACCESS = createManaged(
+                       T_OBJ, IMG_OBJS_SEARCH_READACCESS);
+
+       public static final ImageDescriptor DESC_OBJS_SEARCH_WRITEACCESS = createManaged(
+                       T_OBJ, IMG_OBJS_SEARCH_WRITEACCESS);
+
+       public static final ImageDescriptor DESC_OBJS_SEARCH_OCCURRENCE = createManaged(
+                       T_OBJ, IMG_OBJS_SEARCH_OCCURRENCE);
+
+       public static final ImageDescriptor DESC_OBJS_LOCAL_VARIABLE = create(
+                       T_OBJ, "localvariable_obj.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_STATIC = create(T_OVR,
+                       "static_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_FINAL = create(T_OVR,
+                       "final_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_ABSTRACT = create(T_OVR,
+                       "abstract_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_SYNCH = create(T_OVR,
+                       "synch_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_RUN = create(T_OVR,
+                       "run_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_WARNING = create(T_OVR,
+                       "warning_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_ERROR = create(T_OVR,
+                       "error_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_OVERRIDES = create(T_OVR,
+                       "over_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_IMPLEMENTS = create(T_OVR,
+                       "implm_co.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_CONSTRUCTOR = create(T_OVR,
+                       "constr_ovr.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_OVR_FOCUS = create(T_OVR,
+                       "focus_ovr.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_NEWFIELD = create(T_WIZBAN,
+                       "newfield_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_NEWINT = create(T_WIZBAN,
+                       "newint_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_NEWJPRJ = create(T_WIZBAN,
+                       "newjprj_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_NEWSRCFOLDR = create(
+                       T_WIZBAN, "newsrcfldr_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_NEWMETH = create(T_WIZBAN,
+                       "newmeth_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_NEWPACK = create(T_WIZBAN,
+                       "newpack_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_NEWSCRAPPAGE = create(
+                       T_WIZBAN, "newsbook_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_JAVA_LAUNCH = create(
+                       T_WIZBAN, "java_app_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_JAVA_ATTACH = create(
+                       T_WIZBAN, "java_attach_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_REFACTOR = create(T_WIZBAN,
+                       "refactor_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_REFACTOR_FIELD = create(
+                       T_WIZBAN, "fieldrefact_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_REFACTOR_METHOD = create(
+                       T_WIZBAN, "methrefact_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_REFACTOR_TYPE = create(
+                       T_WIZBAN, "typerefact_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_REFACTOR_PACKAGE = create(
+                       T_WIZBAN, "packrefact_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_REFACTOR_CODE = create(
+                       T_WIZBAN, "coderefact_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_REFACTOR_CU = create(
+                       T_WIZBAN, "compunitrefact_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_REFACTOR_PULL_UP = create(
+                       T_WIZBAN, "pullup_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_JAR_PACKAGER = create(
+                       T_WIZBAN, "jar_pack_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_JAVA_WORKINGSET = create(
+                       T_WIZBAN, "java_workingset_wiz.gif");//$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_EXPORT_JAVADOC = create(
+                       T_WIZBAN, "export_javadoc_wiz.gif");//$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_EXTERNALIZE_STRINGS = create(
+                       T_WIZBAN, "extstr_wiz.gif");//$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_WIZBAN_ADD_LIBRARY = create(
+                       T_WIZBAN, "addlibrary_wiz.gif");//$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_DISPLAYSNIPPET = create(
+                       T_CTOOL, "disp_sbook.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_RUNSNIPPET = create(T_CTOOL,
+                       "run_sbook.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_INSPSNIPPET = create(T_CTOOL,
+                       "insp_sbook.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_PACKSNIPPET = create(T_CTOOL,
+                       "pack_sbook.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_TERMSNIPPET = create(T_CTOOL,
+                       "term_sbook.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_SHOW_EMPTY_PKG = create(
+                       T_CTOOL, "show_empty_pkg.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_SHOW_SEGMENTS = create(
+                       T_CTOOL, "segment_edit.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_GOTO_NEXT_ERROR = create(
+                       T_CTOOL, "next_error_nav.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_GOTO_PREV_ERROR = create(
+                       T_CTOOL, "prev_error_nav.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_OPENTYPE = create(T_CTOOL,
+                       "opentype.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_NEWPROJECT = create(T_CTOOL,
+                       "newjprj_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_NEWPACKAGE = create(T_CTOOL,
+                       "newpack_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_NEWCLASS = create(T_CTOOL,
+                       "newclass_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_NEWINTERFACE = create(
+                       T_CTOOL, "newint_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_NEWSNIPPET = create(T_CTOOL,
+                       "newsbook_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_NEWPACKROOT = create(T_CTOOL,
+                       "newpackfolder_wiz.gif"); //$NON-NLS-1$
+
+       public static final ImageDescriptor DESC_TOOL_CLASSPATH_ORDER = create(
+                       T_OBJ, "cp_order_obj.gif"); //$NON-NLS-1$
+
+       // Keys for correction proposal. We have to put the image into the registry
+       // since "code assist" doesn't
+       // have a life cycle. So no change to dispose icons.
+
+       public static final String IMG_CORRECTION_CHANGE = NAME_PREFIX
+                       + "correction_change.gif"; //$NON-NLS-1$
+
+       public static final String IMG_CORRECTION_MOVE = NAME_PREFIX
+                       + "correction_move.gif"; //$NON-NLS-1$
+
+       public static final String IMG_CORRECTION_RENAME = NAME_PREFIX
+                       + "correction_rename.gif"; //$NON-NLS-1$
+
+       public static final String IMG_CORRECTION_DELETE_IMPORT = NAME_PREFIX
+                       + "correction_delete_import.gif"; //$NON-NLS-1$
+
+       public static final String IMG_CORRECTION_LOCAL = NAME_PREFIX
+                       + "localvariable_obj.gif"; //$NON-NLS-1$
+
+       public static final String IMG_CORRECTION_REMOVE = NAME_PREFIX
+                       + "remove_correction.gif"; //$NON-NLS-1$
+
+       public static final String IMG_CORRECTION_ADD = NAME_PREFIX
+                       + "add_correction.gif"; //$NON-NLS-1$
+
+       static {
+               createManaged(T_OBJ, IMG_CORRECTION_CHANGE);
+               createManaged(T_OBJ, IMG_CORRECTION_MOVE);
+               createManaged(T_OBJ, IMG_CORRECTION_RENAME);
+               createManaged(T_OBJ, IMG_CORRECTION_DELETE_IMPORT);
+               createManaged(T_OBJ, IMG_CORRECTION_LOCAL);
+               createManaged(T_OBJ, IMG_CORRECTION_REMOVE);
+               createManaged(T_OBJ, IMG_CORRECTION_ADD);
+       }
+
+       /**
+        * 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 (ImageDescriptor) 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.
+        */
+       public static void setToolImageDescriptors(IAction action, String iconName) {
+               setImageDescriptors(action, "tool16", iconName);
+       }
+
+       /**
+        * Sets the three image descriptors for enabled, disabled, and hovered to an
+        * action. The actions are retrieved from the *lcl16 folders.
+        */
+       public static void setLocalImageDescriptors(IAction action, String iconName) {
+               setImageDescriptors(action, "lcl16", iconName);
+       }
+
+       /*
+        * Helper method to access the image registry from the JavaPlugin class.
+        */
+       /* package */static ImageRegistry getImageRegistry() {
+               if (fgImageRegistry == null) {
+                       fgImageRegistry = new ImageRegistry();
+                       for (Iterator iter = fgAvoidSWTErrorMap.keySet().iterator(); iter
+                                       .hasNext();) {
+                               String key = (String) iter.next();
+                               fgImageRegistry.put(key, (ImageDescriptor) fgAvoidSWTErrorMap
+                                               .get(key));
+                       }
+                       fgAvoidSWTErrorMap = null;
+               }
+               return fgImageRegistry;
+       }
+
+       // ---- Helper methods to access icons on the file system
+       // --------------------------------------
+
+       protected static void setImageDescriptors(IAction action, String type,
+                       String relPath) {
+
+               try {
+                       ImageDescriptor id = ImageDescriptor.createFromURL(makeIconFileURL(
+                                       "d" + type, relPath));
+                       if (id != null)
+                               action.setDisabledImageDescriptor(id);
+               } catch (MalformedURLException e) {
+               }
+
+               try {
+                       ImageDescriptor id = ImageDescriptor.createFromURL(makeIconFileURL(
+                                       "c" + type, relPath));
+                       if (id != null)
+                               action.setHoverImageDescriptor(id);
+               } catch (MalformedURLException e) {
+               }
+
+               action.setImageDescriptor(create("e" + type, relPath));
+       }
+
+       private static ImageDescriptor createManaged(String prefix, String name) {
+               try {
+                       ImageDescriptor result = ImageDescriptor
+                                       .createFromURL(makeIconFileURL(prefix, name
+                                                       .substring(NAME_PREFIX_LENGTH)));
+                       if (fgAvoidSWTErrorMap == null) {
+                               fgAvoidSWTErrorMap = new HashMap();
+                       }
+                       fgAvoidSWTErrorMap.put(name, result);
+                       if (fgImageRegistry != null) {
+                               WebUI
+                                               .logErrorMessage("Image registry already defined"); //$NON-NLS-1$
+                       }
+                       return result;
+               } catch (MalformedURLException e) {
+                       return ImageDescriptor.getMissingImageDescriptor();
+               }
+       }
+
+       private static ImageDescriptor createManaged(String prefix, String name,
+                       String key) {
+               try {
+                       ImageDescriptor result = ImageDescriptor
+                                       .createFromURL(makeIconFileURL(prefix, name
+                                                       .substring(NAME_PREFIX_LENGTH)));
+                       if (fgAvoidSWTErrorMap == null) {
+                               fgAvoidSWTErrorMap = new HashMap();
+                       }
+                       fgAvoidSWTErrorMap.put(key, result);
+                       if (fgImageRegistry != null) {
+                               WebUI
+                                               .logErrorMessage("Image registry already defined"); //$NON-NLS-1$
+                       }
+                       return result;
+               } catch (MalformedURLException e) {
+                       return ImageDescriptor.getMissingImageDescriptor();
+               }
+       }
+
+       protected static ImageDescriptor create(String prefix, String name) {
+               try {
+                       return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name));
+               } catch (MalformedURLException e) {
+                       return ImageDescriptor.getMissingImageDescriptor();
+               }
+       }
+
+       protected static URL makeIconFileURL(String prefix, String name)
+                       throws MalformedURLException {
+               if (fgIconBaseURL == null)
+                       throw new MalformedURLException();
+
+               StringBuffer buffer = new StringBuffer(prefix);
+               buffer.append('/');
+               buffer.append(name);
+               return new URL(fgIconBaseURL, buffer.toString());
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/ResourceAdapterFactory.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/ResourceAdapterFactory.java
new file mode 100644 (file)
index 0000000..4e07b27
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.JavaCore;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdapterFactory;
+
+public class ResourceAdapterFactory implements IAdapterFactory {
+
+       private static Class[] PROPERTIES = new Class[] { IJavaElement.class };
+
+       public Class[] getAdapterList() {
+               return PROPERTIES;
+       }
+
+       public Object getAdapter(Object element, Class key) {
+               if (IJavaElement.class.equals(key)) {
+                       return JavaCore.create((IResource) element);
+               }
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AbstractToggleLinkingAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AbstractToggleLinkingAction.java
new file mode 100644 (file)
index 0000000..db98033
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * This is an action template for actions that toggle whether it links its
+ * selection to the active editor.
+ * 
+ * @since 3.0
+ */
+public abstract class AbstractToggleLinkingAction extends Action {
+
+       /**
+        * Constructs a new action.
+        */
+       public AbstractToggleLinkingAction() {
+               super(ActionMessages.getString("ToggleLinkingAction.label")); //$NON-NLS-1$
+               setDescription(ActionMessages
+                               .getString("ToggleLinkingAction.description")); //$NON-NLS-1$
+               setToolTipText(ActionMessages.getString("ToggleLinkingAction.tooltip")); //$NON-NLS-1$
+               PHPUiImages.setLocalImageDescriptors(this, "synced.gif"); //$NON-NLS-1$
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                               IJavaHelpContextIds.LINK_EDITOR_ACTION);
+       }
+
+       /**
+        * Runs the action.
+        */
+       public abstract void run();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.java
new file mode 100644 (file)
index 0000000..91d8132
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Class that gives access to the action messages resource bundle.
+ */
+public class ActionMessages {
+
+       private static final String BUNDLE_NAME = "net.sourceforge.phpdt.internal.ui.actions.ActionMessages"; //$NON-NLS-1$
+
+       private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+                       .getBundle(BUNDLE_NAME);
+
+       private ActionMessages() {
+               // 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
+        * @since 3.0
+        */
+       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);
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.properties
new file mode 100644 (file)
index 0000000..bc3ebe5
--- /dev/null
@@ -0,0 +1,235 @@
+################################################################################
+# Copyright (c) 2002 International Business Machines Corp. and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v0.5 
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v05.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+################################################################################
+
+OpenWithMenu.label=Open Wit&h
+RefactorMenu.label=Re&factor
+SourceMenu.label=&Source
+NavigateMenu.label=&Navigate
+
+BuildAction.label=&Build Project
+RebuildAction.label=Rebuild Pro&ject
+
+SelectionConverter.codeResolveOrInput_failed=Couldn't convert text selection into a PHP element
+SelectionConverter.codeResolve_failed=Couldn't convert text selection into a PHP element
+
+OpenAction.label=&Open
+OpenAction.tooltip=Open an editor on the selected element
+OpenAction.description=Open an editor on the selected element
+OpenAction.declaration.label=&Open Declaration@F3
+OpenAction.select_element=&Select or enter the element to open:
+
+OpenAction.error.title=Open
+OpenAction.error.message=Cannot open default editor.
+OpenAction.error.messageArgs=Cannot open default editor on {0}. {1}
+OpenAction.error.messageProblems=Problems Opening Editor
+OpenAction.error.messageBadSelection=Current text selection doesn't resolve to a PHP element
+
+OpenSuperImplementationAction.label=Open S&uper Implementation
+OpenSuperImplementationAction.tooltip=Open the Implementation in the Super Type
+OpenSuperImplementationAction.description=Open the Implementation in the Super Type
+OpenSuperImplementationAction.error.title=Open Super Implementation
+OpenSuperImplementationAction.error.message=Opening failed. Check log for details.
+OpenSuperImplementationAction.not_applicable=Operation not applicable to current text selection. Please position the cursor inside a method.
+OpenSuperImplementationAction.no_super_implementation=There isn''t any super implementation for method ''{0}''.
+
+OpenTypeHierarchyAction.label=Open Type Hie&rarchy
+OpenTypeHierarchyAction.tooltip=Open a type hierarchy on the selected element
+OpenTypeHierarchyAction.description=Open a type hierarchy on the selected element
+OpenTypeHierarchyAction.dialog.title=Open Type Hierarchy
+OpenTypeHierarchyAction.messages.title=Can\'t create type hierarchy
+OpenTypeHierarchyAction.messages.no_php_element=No PHP element selected.
+OpenTypeHierarchyAction.messages.no_php_resources=Selected package fragment doesn\'t contain any PHP resource.
+OpenTypeHierarchyAction.messages.no_types=Selected compilation unit doesn\'t contain a type.
+OpenTypeHierarchyAction.messages.no_valid_php_element=No valid PHP element selected.
+
+ShowInPackageViewAction.label=Show in Pac&kage Explorer
+ShowInPackageViewAction.description=Show the selected element in Package Explorer
+ShowInPackageViewAction.tooltip=Show in Package Explorer
+ShowInPackageViewAction.select_name=&Select or enter the element to reveal:
+ShowInPackageViewAction.dialog.title=Show In Package Explorer
+ShowInPackageViewAction.error.message=Internal error. Please see log for details.
+ShowInPackageViewAction.not_found=Couldn\'t reveal the selected element in Package Explorer. May be the element is filtered out.
+
+ShowInNavigatorView.label=Show in &Navigator View
+ShowInNavigatorView.dialog.title=Show in Navigator View
+ShowInNavigatorView.dialog.message=Select the element to be opened in the navigator view:
+ShowInNavigatorView.error.activation_failed=Unable to activate Resource Navigator
+ShowInNavigatorView.error.conversion_failed=Unable to convert PHP element into a resource
+
+OverrideMethodsAction.label=O&verride/Implement Methods...
+OverrideMethodsAction.description=Override or Implement Methods from super types.
+OverrideMethodsAction.tooltip=Override/Implement Methods
+
+OverrideMethodsAction.error.title=Override/Implement Methods
+OverrideMethodsAction.error.nothing_found=No methods to override found for this type.
+OverrideMethodsAction.error.type_removed_in_editor=Input type has been removed in editor.
+OverrideMethodsAction.not_applicable=Operation not applicable to current text selection. Please position the cursor inside a type.
+
+AddGetterSetterAction.label=Gene&rate Getter and Setter...
+AddGetterSetterAction.description=Generate Getter and Setter methods for the field
+AddGetterSetterAction.tooltip=Generate Getter and Setter methods for the Field
+
+AddGetterSetterAction.error.title=Generate Getter and Setter
+AddGetterSetterAction.error.actionfailed=Generating Getter and Setter Failed.
+AddGetterSetterAction.error.fieldNotExisting=The field ''{0}'' has been removed in the editor.
+AddGetterSetterAction.not_applicable=Operation not applicable to current text selection. Please select a field or a type that declares some fields.
+AddGetterSetterAction.read_only=The compilation unit in which the field ''{0}'' is declared is read only.
+
+AddGetterSetterAction.QueryDialog.title=Generate Getter and Setter
+AddGetterSetterAction.SkipSetterForFinalDialog.message=Field ''{0}'' is final.\nOK to skip creation of the setter method?
+AddGetterSetterAction.SkipExistingDialog.message=Method ''{0}'' already exists.\nSkip creation?
+AddGetterSetterAction.SkipExistingDialog.skip.label=&Skip
+AddGetterSetterAction.SkipExistingDialog.replace.label=&Replace
+AddGetterSetterAction.SkipExistingDialog.skipAll.label=Skip &All
+
+AddUnimplementedConstructorsAction.label=Add &Constructors from Superclass
+AddUnimplementedConstructorsAction.description=Evaluate and add constructors from superclass
+AddUnimplementedConstructorsAction.tooltip=Add Constructors from Superclass
+
+AddUnimplementedConstructorsAction.error.title=Add Constructors from Superclass
+AddUnimplementedConstructorsAction.error.nothing_found=No unimplemented constructors found.
+AddUnimplementedConstructorsAction.error.type_removed_in_editor=Input type has been removed in editor.
+AddUnimplementedConstructorsAction.not_applicable=Operation not applicable to current text selection. Please position the cursor inside a type.
+
+AddJavaDocStubAction.label=Add &Javadoc Comment
+AddJavaDocStubAction.description=Add a Javadoc comment stub to the member element
+AddJavaDocStubAction.tooltip=Add a Javadoc comment stub to the member element
+
+AddJavaDocStubsAction.error.dialogTitle=Add Javadoc Comment
+AddJavaDocStubsAction.error.noWorkingCopy=Could not find working copy.
+AddJavaDocStubsAction.error.memberNotExisting=Member has been removed in editor.
+AddJavaDocStubsAction.error.actionFailed=Error while adding Javadoc comment
+AddJavaDocStubsAction.not_applicable=Operation not applicable to current text selection. Please position the cursor inside a type or method.
+
+ExternalizeStringsAction.label= &Externalize Strings...
+ExternalizeStringsAction.dialog.title= Externalize Strings
+ExternalizeStringsAction.dialog.message=Couldn't open Externalize String Wizard
+
+FindStringsToExternalizeAction.label= &Find Strings to Externalize...
+FindStringsToExternalizeAction.dialog.title= Find Strings to Externalize
+FindStringsToExternalizeAction.error.message=Unexpected Exception. See log.
+FindStringsToExternalizeAction.foundStrings= {0} in {1}
+FindStringsToExternalizeAction.noStrings= No strings to externalize were found.
+FindStringsToExternalizeAction.not_externalized= {0} &not externalized string(s) found.
+FindStringsToExternalizeAction.button.label= &Externalize...
+FindStringsToExternalizeAction.hide= &Hide compilation units with no strings to externalize
+FindStringsToExternalizeAction.find_strings=Finding not externalized strings...
+
+OpenExternalJavadocAction.label=Open E&xternal Javadoc
+OpenExternalJavadocAction.description=Opens the Javadoc of the selected element in an external browser
+OpenExternalJavadocAction.tooltip=Opens the Javadoc of the selected element in an external browser
+OpenExternalJavadocAction.help_not_available=Help support not available
+OpenExternalJavadocAction.select_element=&Select or enter the element to open:
+OpenExternalJavadocAction.libraries.no_location=The documentation location for ''{0}'' has not been configured. For elements from libraries specify the Javadoc location URL on the property page of the parent JAR (''{1}'')
+OpenExternalJavadocAction.source.no_location=The documentation location for ''{0}'' has not been configured. For elements from source specify the Javadoc location URL on the property page of the parent project (''{1}'')
+OpenExternalJavadocAction.no_entry=The documentation does not contain an entry for ''{0}''.\n(File ''{1}'' does not exist.)
+OpenExternalJavadocAction.opening_failed=Opening Javadoc failed. See log for details
+OpenExternalJavadocAction.dialog.title=Open External Javadoc
+OpenExternalJavadocAction.code_resolve_failed=Couldn't convert text selection into a PHP element
+
+SelfEncapsulateFieldAction.label=&Self Encapsulate...
+SelfEncapsulateFieldAction.dialog.title=Self Encapsulate Field
+SelfEncapsulateFieldAction.dialog.unavailable=Operation unavailable on the current selection. Select a field.
+SelfEncapsulateFieldAction.dialog.cannot_perform=Cannot perform refactoring. See log for more details.
+SelfEncapsulateFieldAction.dialog.field_doesnot_exit=Field {0} doesn't exist in editor buffer anymore.
+
+OrganizeImportsAction.label=Or&ganize Imports@Ctrl+Shift+O
+OrganizeImportsAction.tooltip=Evaluate All Required Imports and Replace the Current Imports
+OrganizeImportsAction.description=Evaluate all required imports and replace the current imports
+
+OrganizeImportsAction.multi.op.description=Organizing imports...
+OrganizeImportsAction.multi.error.parse={0}: Compilation unit has parse errors. No changes applied.
+OrganizeImportsAction.multi.error.readonly={0}: Compilation unit is read-only. No changes applied.
+OrganizeImportsAction.multi.error.unresolvable={0}: Compilation unit contains ambiguous references. User interaction required.
+OrganizeImportsAction.multi.error.unexpected={0}: Unexpected error. See log for details.
+
+OrganizeImportsAction.selectiondialog.title=Organize Imports
+OrganizeImportsAction.selectiondialog.message=&Choose type to import:
+
+OrganizeImportsAction.error.title=Organize Imports
+OrganizeImportsAction.error.message=Unexpected error in organize imports. See log for details.
+
+OrganizeImportsAction.single.error.parse=Compilation unit has parse errors. No changes applied.
+
+OrganizeImportsAction.summary_added={0} import(s) added.
+OrganizeImportsAction.summary_removed={0} import(s) removed.
+
+OrganizeImportsAction.multi.status.title=Organize Imports
+OrganizeImportsAction.multi.status.description=Problems while organizing imports on some compilation units. See 'Details' for more information.
+
+OpenBrowserUtil.help_not_available=Help support not available
+
+MemberFilterActionGroup.hide_fields.label=Hide Fields
+MemberFilterActionGroup.hide_fields.tooltip=Hide Fields
+MemberFilterActionGroup.hide_fields.description=Toggles the visibility of fields
+
+MemberFilterActionGroup.hide_static.label=Hide Static Members
+MemberFilterActionGroup.hide_static.tooltip=Hide Static Members
+MemberFilterActionGroup.hide_static.description=Toggles the visibility of static members
+
+MemberFilterActionGroup.hide_nonpublic.label=Hide Non-Public Members
+MemberFilterActionGroup.hide_nonpublic.tooltip=Hide Non-Public Members
+MemberFilterActionGroup.hide_nonpublic.description=Toggles the visibility of non-public members
+
+NewWizardsActionGroup.new=Ne&w
+
+OpenProjectAction.dialog.title=Open Project
+OpenProjectAction.dialog.message=Select project(s) to be opened
+OpenProjectAction.error.message=Problems while opening projects
+OpenProjectAction.no_php_nature.one=The following project doesn't have a PHP nature and is therefore not present in the Package Explorer:
+OpenProjectAction.no_php_nature.multiple=The following projects don't have a PHP nature and are therefore not present in the Package Explorer:
+
+AddGetterSetterAction.dialog.title=&Select Methods to Create in Type ''{0}'':
+AddGetterSetterAction.one_selected=1 method selected
+AddGetterSetterAction.methods_selected={0} methods selected
+AddGettSetterAction.typeContainsNoFields.message=The type contains no fields or all fields have getters/setters already.
+
+OpenJavaPerspectiveAction.dialog.title=Open PHP Perspective
+OpenJavaPerspectiveAction.error.open_failed=Couldn\'t open PHP perspective
+
+OpenJavaBrowsingPerspectiveAction.dialog.title=Open PHP Browsing Perspective
+OpenJavaBrowsingPerspectiveAction.error.open_failed=Couldn\'t open PHP browsing perspective
+
+OpenTypeInHierarchyAction.label=Open Type in Hierarchy...@Ctrl+Shift+H
+OpenTypeInHierarchyAction.description=Open a type a the type hierarchy
+OpenTypeInHierarchyAction.tooltip=Open a type in a type hierarchy
+OpenTypeInHierarchyAction.dialogMessage=&Choose a type (? = any character, * = any string):
+OpenTypeInHierarchyAction.dialogTitle=Open Type in Hierarchy
+
+RefreshAction.label= Re&fresh
+RefreshAction.toolTip= Refresh
+RefreshAction.progressMessage= Refreshing...
+RefreshAction.error.title= Refresh Problems
+RefreshAction.error.message= Problems occurred refreshing the selected resources.
+RefreshAction.locationDeleted.title= Project location has been deleted
+RefreshAction.locationDeleted.message= The location for project {0} ({1}) has been deleted.\n Delete {0} from the workspace?
+
+ModifyParameterAction.problem.title=Refactoring
+ModifyParameterAction.problem.message=Operation not possible.
+
+PullUpAction.problem.title=Refactoring
+PullUpAction.problem.message=Operation not possible.
+
+OverrideMethodQuery.groupMethodsByTypes=Group methods by &types
+OverrideMethodQuery.dialog.title=Override/Implement Methods
+OverrideMethodQuery.dialog.description=&Select methods to override or implement:
+OverrideMethodQuery.selectioninfo.one={0} method selected.
+OverrideMethodQuery.selectioninfo.more={0} methods selected.
+
+ActionUtil.notOnBuildPath.title=Operation Cannot be Performed
+ActionUtil.notOnBuildPath.message=The resource is not on the build path of a PHP project.
+
+SelectAllAction.label= Select A&ll
+SelectAllAction.tooltip= Select All
+
+ToggleLinkingAction.label=Lin&k With Editor
+ToggleLinkingAction.tooltip=Link with Editor
+ToggleLinkingAction.description=Link with active editor
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionUtil.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/ActionUtil.java
new file mode 100644 (file)
index 0000000..5c19554
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.internal.corext.refactoring.util.ResourceUtil;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+
+/*
+ * http://dev.eclipse.org/bugs/show_bug.cgi?id=19104
+ */
+public class ActionUtil {
+
+       private ActionUtil() {
+       }
+
+       // bug 31998 we will have to disable renaming of linked packages (and cus)
+       public static boolean mustDisableJavaModelAction(Shell shell, Object element) {
+               if (!(element instanceof IPackageFragment)
+                               && !(element instanceof IPackageFragmentRoot))
+                       return false;
+
+               IResource resource = ResourceUtil.getResource(element);
+               if ((resource == null) || (!(resource instanceof IFolder))
+                               || (!resource.isLinked()))
+                       return false;
+
+               MessageDialog
+                               .openInformation(
+                                               shell,
+                                               ActionMessages.getString("ActionUtil.not_possible"), ActionMessages.getString("ActionUtil.no_linked")); //$NON-NLS-1$ //$NON-NLS-2$
+               return true;
+       }
+
+       public static boolean isProcessable(Shell shell, PHPEditor editor) {
+               if (editor == null)
+                       return true;
+               IJavaElement input = SelectionConverter.getInput(editor);
+               // if a Java editor doesn't have an input of type Java element
+               // then it is for sure not on the build path
+               if (input == null) {
+                       MessageDialog.openInformation(shell, ActionMessages
+                                       .getString("ActionUtil.notOnBuildPath.title"), //$NON-NLS-1$
+                                       ActionMessages
+                                                       .getString("ActionUtil.notOnBuildPath.message")); //$NON-NLS-1$
+                       return false;
+               }
+               return isProcessable(shell, input);
+       }
+
+       public static boolean isProcessable(Shell shell, Object element) {
+               if (!(element instanceof IJavaElement))
+                       return true;
+
+               if (isOnBuildPath((IJavaElement) element))
+                       return true;
+               MessageDialog.openInformation(shell, ActionMessages
+                               .getString("ActionUtil.notOnBuildPath.title"), //$NON-NLS-1$
+                               ActionMessages.getString("ActionUtil.notOnBuildPath.message")); //$NON-NLS-1$
+               return false;
+       }
+
+       public static boolean isOnBuildPath(IJavaElement element) {
+               // fix for bug http://dev.eclipse.org/bugs/show_bug.cgi?id=20051
+               if (element.getElementType() == IJavaElement.JAVA_PROJECT)
+                       return true;
+               IJavaProject project = element.getJavaProject();
+               try {
+                       // if (!project.isOnClasspath(element))
+                       // return false;
+                       IProject resourceProject = project.getProject();
+                       if (resourceProject == null)
+                               return false;
+                       IProjectNature nature = resourceProject
+                                       .getNature(/*WebUI*/PHPeclipsePlugin.PHP_NATURE_ID);
+                       // We have a Java project
+                       if (nature != null)
+                               return true;
+               } catch (CoreException e) {
+               }
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AddBlockCommentAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AddBlockCommentAction.java
new file mode 100644 (file)
index 0000000..1d2f1c7
--- /dev/null
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPartitioningException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Action that encloses the editor's current selection with Java block comment
+ * terminators (<code>&#47;&#42;</code> and <code>&#42;&#47;</code>).
+ * 
+ * @since 3.0
+ */
+public class AddBlockCommentAction extends BlockCommentAction {
+
+       /**
+        * Creates a new instance.
+        * 
+        * @param bundle
+        *            the resource bundle
+        * @param prefix
+        *            a prefix to be prepended to the various resource keys
+        *            (described in <code>ResourceAction</code> constructor), or
+        *            <code>null</code> if none
+        * @param editor
+        *            the text editor
+        */
+       public AddBlockCommentAction(ResourceBundle bundle, String prefix,
+                       ITextEditor editor) {
+               super(bundle, prefix, editor);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.actions.BlockCommentAction#runInternal(org.eclipse.jface.text.ITextSelection,
+        *      org.eclipse.jface.text.IDocumentExtension3,
+        *      net.sourceforge.phpdt.internal.ui.actions.BlockCommentAction.Edit.EditFactory)
+        */
+       protected void runInternal(ITextSelection selection,
+                       IDocumentExtension3 docExtension, Edit.EditFactory factory)
+                       throws BadLocationException, BadPartitioningException {
+               int selectionOffset = selection.getOffset();
+               int selectionEndOffset = selectionOffset + selection.getLength();
+               List edits = new LinkedList();
+               ITypedRegion partition = docExtension.getPartition(
+                               IPHPPartitions.PHP_PARTITIONING, selectionOffset, false);
+
+               handleFirstPartition(partition, edits, factory, selectionOffset);
+
+               while (partition.getOffset() + partition.getLength() < selectionEndOffset) {
+                       partition = handleInteriorPartition(partition, edits, factory,
+                                       docExtension);
+               }
+
+               handleLastPartition(partition, edits, factory, selectionEndOffset);
+
+               executeEdits(edits);
+       }
+
+       /**
+        * Handle the first partition of the selected text.
+        * 
+        * @param partition
+        * @param edits
+        * @param factory
+        * @param offset
+        */
+       private void handleFirstPartition(ITypedRegion partition, List edits,
+                       Edit.EditFactory factory, int offset) throws BadLocationException {
+
+               int partOffset = partition.getOffset();
+               String partType = partition.getType();
+
+               Assert.isTrue(partOffset <= offset, "illegal partition"); //$NON-NLS-1$
+
+               // first partition: mark start of comment
+               if (partType == IDocument.DEFAULT_CONTENT_TYPE
+                               || partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE) {
+                       // Java code: right where selection starts
+                       edits.add(factory.createEdit(offset, 0, getCommentStart()));
+               } else if (isSpecialPartition(partType)) {
+                       // special types: include the entire partition
+                       edits.add(factory.createEdit(partOffset, 0, getCommentStart()));
+               } // javadoc: no mark, will only start after comment
+
+       }
+
+       /**
+        * Handles the end of the given partition and the start of the next
+        * partition, which is returned.
+        * 
+        * @param partition
+        * @param edits
+        * @param factory
+        * @param docExtension
+        * @return
+        * @throws BadLocationException
+        * @throws BadPartitioningException
+        */
+       private ITypedRegion handleInteriorPartition(ITypedRegion partition,
+                       List edits, Edit.EditFactory factory,
+                       IDocumentExtension3 docExtension) throws BadPartitioningException,
+                       BadLocationException {
+
+               // end of previous partition
+               String partType = partition.getType();
+               int partEndOffset = partition.getOffset() + partition.getLength();
+               int tokenLength = getCommentStart().length();
+
+               boolean wasJavadoc = false; // true if the previous partition is javadoc
+
+               if (partType == IPHPPartitions.PHP_PHPDOC_COMMENT) {
+
+                       wasJavadoc = true;
+
+               } else if (partType == IPHPPartitions.PHP_MULTILINE_COMMENT) {
+
+                       // already in a comment - remove ending mark
+                       edits.add(factory.createEdit(partEndOffset - tokenLength,
+                                       tokenLength, "")); //$NON-NLS-1$
+
+               }
+
+               // advance to next partition
+               partition = docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING,
+                               partEndOffset, false);
+               partType = partition.getType();
+
+               // start of next partition
+               if (wasJavadoc) {
+
+                       // if previous was javadoc, and the current one is not, then add
+                       // block comment start
+                       if (partType == IDocument.DEFAULT_CONTENT_TYPE
+                                       || partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE
+                                       || isSpecialPartition(partType)) {
+                               edits.add(factory.createEdit(partition.getOffset(), 0,
+                                               getCommentStart()));
+                       }
+
+               } else { // !wasJavadoc
+
+                       if (partType == IPHPPartitions.PHP_PHPDOC_COMMENT) {
+                               // if next is javadoc, end block comment before
+                               edits.add(factory.createEdit(partition.getOffset(), 0,
+                                               getCommentEnd()));
+                       } else if (partType == IPHPPartitions.PHP_MULTILINE_COMMENT) {
+                               // already in a comment - remove startToken
+                               edits.add(factory.createEdit(partition.getOffset(),
+                                               getCommentStart().length(), "")); //$NON-NLS-1$
+                       }
+               }
+
+               return partition;
+       }
+
+       /**
+        * Handles the end of the last partition.
+        * 
+        * @param partition
+        * @param edits
+        * @param factory
+        * @param endOffset
+        */
+       private void handleLastPartition(ITypedRegion partition, List edits,
+                       Edit.EditFactory factory, int endOffset)
+                       throws BadLocationException {
+
+               String partType = partition.getType();
+
+               if (partType == IDocument.DEFAULT_CONTENT_TYPE
+                               || partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE) {
+                       // normal java: end comment where selection ends
+                       edits.add(factory.createEdit(endOffset, 0, getCommentEnd()));
+               } else if (isSpecialPartition(partType)) {
+                       // special types: consume entire partition
+                       edits.add(factory.createEdit(partition.getOffset()
+                                       + partition.getLength(), 0, getCommentEnd()));
+               }
+
+       }
+
+       /**
+        * Returns whether <code>partType</code> is special, i.e. a Java
+        * <code>String</code>,<code>Character</code>, or
+        * <code>Line End Comment</code> partition.
+        * 
+        * @param partType
+        *            the partition type to check
+        * @return <code>true</code> if <code>partType</code> is special,
+        *         <code>false</code> otherwise
+        */
+       private boolean isSpecialPartition(String partType) {
+               // return partType == IJavaPartitions.JAVA_CHARACTER
+               return partType == IPHPPartitions.PHP_STRING_DQ
+                               || partType == IPHPPartitions.PHP_STRING_SQ
+                               || partType == IPHPPartitions.PHP_STRING_HEREDOC
+                               || partType == IPHPPartitions.PHP_SINGLELINE_COMMENT;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.actions.BlockCommentAction#validSelection(org.eclipse.jface.text.ITextSelection)
+        */
+       protected boolean isValidSelection(ITextSelection selection) {
+               return selection != null && !selection.isEmpty()
+                               && selection.getLength() > 0;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AddTaskAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/AddTaskAction.java
new file mode 100644 (file)
index 0000000..b885182
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import net.sourceforge.phpdt.ui.actions.SelectionDispatchAction;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.views.tasklist.TaskPropertiesDialog;
+
+public class AddTaskAction extends SelectionDispatchAction {
+
+       public AddTaskAction(IWorkbenchSite site) {
+               super(site);
+               setEnabled(false);
+               // WorkbenchHelp.setHelp(this, IJavaHelpContextIds.ADD_TASK_ACTION);
+       }
+
+       protected void selectionChanged(IStructuredSelection selection) {
+               setEnabled(getElement(selection) != null);
+       }
+
+       protected void run(IStructuredSelection selection) {
+               IResource resource = getElement(selection);
+               if (resource == null)
+                       return;
+
+               TaskPropertiesDialog dialog = new TaskPropertiesDialog(getShell());
+               dialog.setResource(resource);
+               dialog.open();
+       }
+
+       private IResource getElement(IStructuredSelection selection) {
+               if (selection.size() != 1)
+                       return null;
+
+               Object element = selection.getFirstElement();
+               if (!(element instanceof IAdaptable))
+                       return null;
+               return (IResource) ((IAdaptable) element).getAdapter(IResource.class);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/BlockCommentAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/BlockCommentAction.java
new file mode 100644 (file)
index 0000000..1f037a8
--- /dev/null
@@ -0,0 +1,373 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPartitioningException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IPositionUpdater;
+import org.eclipse.jface.text.IRewriteTarget;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorExtension2;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * Common block comment code.
+ * 
+ * @since 3.0
+ */
+public abstract class BlockCommentAction extends TextEditorAction {
+
+       /**
+        * Creates a new instance.
+        * 
+        * @param bundle
+        * @param prefix
+        * @param editor
+        */
+       public BlockCommentAction(ResourceBundle bundle, String prefix,
+                       ITextEditor editor) {
+               super(bundle, prefix, editor);
+       }
+
+       /**
+        * An edit is a kind of <code>DocumentEvent</code>, in this case an edit
+        * instruction, that is affilitated with a <code>Position</code> on a
+        * document. The offset of the document event is not stored statically, but
+        * taken from the affiliated <code>Position</code>, which gets updated
+        * when other edits occurr.
+        */
+       static class Edit extends DocumentEvent {
+
+               /**
+                * Factory for edits which manages the creation, installation and
+                * destruction of position categories, position updaters etc. on a
+                * certain document. Once a factory has been obtained, <code>Edit</code>
+                * objects can be obtained from it which will be linked to the document
+                * by positions of one position category.
+                * <p>
+                * Clients are required to call <code>release</code> once the
+                * <code>Edit</code>s are not used any more, so the positions can be
+                * discarded.
+                * </p>
+                */
+               public static class EditFactory {
+
+                       /** The position category basename for this edits. */
+                       private static final String CATEGORY = "__positionalEditPositionCategory"; //$NON-NLS-1$
+
+                       /** The count of factories. */
+                       private static int fgCount = 0;
+
+                       /** This factory's category. */
+                       private final String fCategory;
+
+                       private IDocument fDocument;
+
+                       private IPositionUpdater fUpdater;
+
+                       /**
+                        * Creates a new <code>EditFactory</code> with an unambiguous
+                        * position category name.
+                        * 
+                        * @param document
+                        *            the document that is being edited.
+                        */
+                       public EditFactory(IDocument document) {
+                               fCategory = CATEGORY + fgCount++;
+                               fDocument = document;
+                       }
+
+                       /**
+                        * Creates a new edition on the document of this factory.
+                        * 
+                        * @param offset
+                        *            the offset of the edition at the point when is
+                        *            created.
+                        * @param length
+                        *            the length of the edition (not updated via the
+                        *            position update mechanism)
+                        * @param text
+                        *            the text to be replaced on the document
+                        * @return an <code>Edit</code> reflecting the edition on the
+                        *         document
+                        */
+                       public Edit createEdit(int offset, int length, String text)
+                                       throws BadLocationException {
+
+                               if (!fDocument.containsPositionCategory(fCategory)) {
+                                       fDocument.addPositionCategory(fCategory);
+                                       fUpdater = new DefaultPositionUpdater(fCategory);
+                                       fDocument.addPositionUpdater(fUpdater);
+                               }
+
+                               Position position = new Position(offset);
+                               try {
+                                       fDocument.addPosition(fCategory, position);
+                               } catch (BadPositionCategoryException e) {
+                                       Assert.isTrue(false);
+                               }
+                               return new Edit(fDocument, length, text, position);
+                       }
+
+                       /**
+                        * Releases the position category on the document and uninstalls the
+                        * position updater. <code>Edit</code>s managed by this factory
+                        * are not updated after this call.
+                        */
+                       public void release() {
+                               if (fDocument != null
+                                               && fDocument.containsPositionCategory(fCategory)) {
+                                       fDocument.removePositionUpdater(fUpdater);
+                                       try {
+                                               fDocument.removePositionCategory(fCategory);
+                                       } catch (BadPositionCategoryException e) {
+                                               Assert.isTrue(false);
+                                       }
+                                       fDocument = null;
+                                       fUpdater = null;
+                               }
+                       }
+               }
+
+               /** The position in the document where this edit be executed. */
+               private Position fPosition;
+
+               /**
+                * Creates a new edition on <code>document</code>, taking its offset
+                * from <code>position</code>.
+                * 
+                * @param document
+                *            the document being edited
+                * @param length
+                *            the length of the edition
+                * @param text
+                *            the replacement text of the edition
+                * @param position
+                *            the position keeping the edition's offset
+                */
+               protected Edit(IDocument document, int length, String text,
+                               Position position) {
+                       super(document, 0, length, text);
+                       fPosition = position;
+               }
+
+               /*
+                * @see org.eclipse.jface.text.DocumentEvent#getOffset()
+                */
+               public int getOffset() {
+                       return fPosition.getOffset();
+               }
+
+               /**
+                * Executes the edition on document. The offset is taken from the
+                * position.
+                * 
+                * @throws BadLocationException
+                *             if the execution of the document fails.
+                */
+               public void perform() throws BadLocationException {
+                       getDocument().replace(getOffset(), getLength(), getText());
+               }
+
+       }
+
+       public void run() {
+               if (!isEnabled())
+                       return;
+
+               ITextEditor editor = getTextEditor();
+               if (editor == null || !ensureEditable(editor))
+                       return;
+
+               ITextSelection selection = getCurrentSelection();
+               if (!isValidSelection(selection))
+                       return;
+
+               if (!validateEditorInputState())
+                       return;
+
+               IDocumentProvider docProvider = editor.getDocumentProvider();
+               IEditorInput input = editor.getEditorInput();
+               if (docProvider == null || input == null)
+                       return;
+
+               IDocument document = docProvider.getDocument(input);
+               if (document == null)
+                       return;
+
+               IDocumentExtension3 docExtension;
+               if (document instanceof IDocumentExtension3)
+                       docExtension = (IDocumentExtension3) document;
+               else
+                       return;
+
+               IRewriteTarget target = (IRewriteTarget) editor
+                               .getAdapter(IRewriteTarget.class);
+               if (target != null) {
+                       target.beginCompoundChange();
+               }
+
+               Edit.EditFactory factory = new Edit.EditFactory(document);
+
+               try {
+                       runInternal(selection, docExtension, factory);
+
+               } catch (BadLocationException e) {
+                       // can happen on concurrent modification, deletion etc. of the
+                       // document
+                       // -> don't complain, just bail out
+               } catch (BadPartitioningException e) {
+                       // should not happen
+                       Assert.isTrue(false, "bad partitioning"); //$NON-NLS-1$
+               } finally {
+                       factory.release();
+
+                       if (target != null) {
+                               target.endCompoundChange();
+                       }
+               }
+       }
+
+       /**
+        * Calls <code>perform</code> on all <code>Edit</code>s in
+        * <code>edits</code>.
+        * 
+        * @param edits
+        *            a list of <code>Edit</code>s
+        * @throws BadLocationException
+        *             if an <code>Edit</code> threw such an exception.
+        */
+       protected void executeEdits(List edits) throws BadLocationException {
+               for (Iterator it = edits.iterator(); it.hasNext();) {
+                       Edit edit = (Edit) it.next();
+                       edit.perform();
+               }
+       }
+
+       /**
+        * Ensures that the editor is modifyable. If the editor is an instance of
+        * <code>ITextEditorExtension2</code>, its
+        * <code>validateEditorInputState</code> method is called, otherwise, the
+        * result of <code>isEditable</code> is returned.
+        * 
+        * @param editor
+        *            the editor to be checked
+        * @return <code>true</code> if the editor is editable, <code>false</code>
+        *         otherwise
+        */
+       protected boolean ensureEditable(ITextEditor editor) {
+               Assert.isNotNull(editor);
+
+               if (editor instanceof ITextEditorExtension2) {
+                       ITextEditorExtension2 ext = (ITextEditorExtension2) editor;
+                       return ext.validateEditorInputState();
+               }
+
+               return editor.isEditable();
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.IUpdate#update()
+        */
+       public void update() {
+               super.update();
+
+               if (isEnabled()) {
+                       if (!canModifyEditor() || !isValidSelection(getCurrentSelection()))
+                               setEnabled(false);
+               }
+       }
+
+       /**
+        * Returns the editor's selection, or <code>null</code> if no selection
+        * can be obtained or the editor is <code>null</code>.
+        * 
+        * @return the selection of the action's editor, or <code>null</code>
+        */
+       protected ITextSelection getCurrentSelection() {
+               ITextEditor editor = getTextEditor();
+               if (editor != null) {
+                       ISelectionProvider provider = editor.getSelectionProvider();
+                       if (provider != null) {
+                               ISelection selection = provider.getSelection();
+                               if (selection instanceof ITextSelection)
+                                       return (ITextSelection) selection;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Runs the real command once all the editor, document, and selection checks
+        * have succeeded.
+        * 
+        * @param selection
+        *            the current selection we are being called for
+        * @param docExtension
+        *            the document extension where we get the partitioning from
+        * @param factory
+        *            the edit factory we can use to create <code>Edit</code>s
+        * @throws BadLocationException
+        *             if an edition fails
+        * @throws BadPartitioningException
+        *             if a partitioning call fails
+        */
+       protected abstract void runInternal(ITextSelection selection,
+                       IDocumentExtension3 docExtension, Edit.EditFactory factory)
+                       throws BadLocationException, BadPartitioningException;
+
+       /**
+        * Checks whether <code>selection</code> is valid.
+        * 
+        * @param selection
+        *            the selection to check
+        * @return <code>true</code> if the selection is valid, <code>false</code>
+        *         otherwise
+        */
+       protected abstract boolean isValidSelection(ITextSelection selection);
+
+       /**
+        * Returns the text to be inserted at the selection start.
+        * 
+        * @return the text to be inserted at the selection start
+        */
+       protected String getCommentStart() {
+               // for now: no space story
+               return "/*"; //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the text to be inserted at the selection end.
+        * 
+        * @return the text to be inserted at the selection end
+        */
+       protected String getCommentEnd() {
+               // for now: no space story
+               return "*/"; //$NON-NLS-1$
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/CompositeActionGroup.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/CompositeActionGroup.java
new file mode 100644 (file)
index 0000000..ab643ef
--- /dev/null
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionGroup;
+
+public class CompositeActionGroup extends ActionGroup {
+
+       private ActionGroup[] fGroups;
+
+       public CompositeActionGroup() {
+       }
+
+       public CompositeActionGroup(ActionGroup[] groups) {
+               setGroups(groups);
+       }
+
+       protected void setGroups(ActionGroup[] groups) {
+               Assert.isTrue(fGroups == null);
+               Assert.isNotNull(groups);
+               fGroups = groups;
+       }
+
+       public ActionGroup get(int index) {
+               if (fGroups == null)
+                       return null;
+               return fGroups[index];
+       }
+
+       public void addGroup(ActionGroup group) {
+               if (fGroups == null) {
+                       fGroups = new ActionGroup[] { group };
+               } else {
+                       ActionGroup[] newGroups = new ActionGroup[fGroups.length + 1];
+                       System.arraycopy(fGroups, 0, newGroups, 0, fGroups.length);
+                       newGroups[fGroups.length] = group;
+                       fGroups = newGroups;
+               }
+       }
+
+       public void dispose() {
+               super.dispose();
+               if (fGroups == null)
+                       return;
+               for (int i = 0; i < fGroups.length; i++) {
+                       fGroups[i].dispose();
+               }
+       }
+
+       public void fillActionBars(IActionBars actionBars) {
+               super.fillActionBars(actionBars);
+               if (fGroups == null)
+                       return;
+               for (int i = 0; i < fGroups.length; i++) {
+                       fGroups[i].fillActionBars(actionBars);
+               }
+       }
+
+       public void fillContextMenu(IMenuManager menu) {
+               super.fillContextMenu(menu);
+               if (fGroups == null)
+                       return;
+               for (int i = 0; i < fGroups.length; i++) {
+                       fGroups[i].fillContextMenu(menu);
+               }
+       }
+
+       public void setContext(ActionContext context) {
+               super.setContext(context);
+               if (fGroups == null)
+                       return;
+               for (int i = 0; i < fGroups.length; i++) {
+                       fGroups[i].setContext(context);
+               }
+       }
+
+       public void updateActionBars() {
+               super.updateActionBars();
+               if (fGroups == null)
+                       return;
+               for (int i = 0; i < fGroups.length; i++) {
+                       fGroups[i].updateActionBars();
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingActionGroup.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingActionGroup.java
new file mode 100644 (file)
index 0000000..844fe84
--- /dev/null
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+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.TextOperationAction;
+
+/**
+ * Groups the JDT folding actions.
+ * 
+ * @since 3.0
+ */
+public class FoldingActionGroup extends ActionGroup {
+       private ProjectionViewer fViewer;
+
+       private TextOperationAction fToggle;
+
+       private TextOperationAction fExpand;
+
+       private TextOperationAction fCollapse;
+
+       private TextOperationAction fExpandAll;
+
+       private IProjectionListener fProjectionListener;
+
+       /**
+        * 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(ITextEditor editor, ITextViewer viewer) {
+               if (viewer instanceof ProjectionViewer) {
+                       fViewer = (ProjectionViewer) viewer;
+
+                       fProjectionListener = new IProjectionListener() {
+
+                               public void projectionEnabled() {
+                                       update();
+                               }
+
+                               public void projectionDisabled() {
+                                       update();
+                               }
+                       };
+
+                       fViewer.addProjectionListener(fProjectionListener);
+
+                       fToggle = new TextOperationAction(ActionMessages
+                                       .getResourceBundle(),
+                                       "Projection.Toggle.", editor, ProjectionViewer.TOGGLE, true); //$NON-NLS-1$
+                       fToggle.setChecked(true);
+                       fToggle.setActionDefinitionId(IFoldingCommandIds.FOLDING_TOGGLE);
+                       editor.setAction("FoldingToggle", fToggle); //$NON-NLS-1$
+
+                       fExpandAll = new TextOperationAction(
+                                       ActionMessages.getResourceBundle(),
+                                       "Projection.ExpandAll.", editor, ProjectionViewer.EXPAND_ALL, true); //$NON-NLS-1$
+                       fExpandAll
+                                       .setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND_ALL);
+                       editor.setAction("FoldingExpandAll", fExpandAll); //$NON-NLS-1$
+
+                       fExpand = new TextOperationAction(ActionMessages
+                                       .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(
+                                       ActionMessages.getResourceBundle(),
+                                       "Projection.Collapse.", editor, ProjectionViewer.COLLAPSE, true); //$NON-NLS-1$
+                       fCollapse
+                                       .setActionDefinitionId(IFoldingCommandIds.FOLDING_COLLAPSE);
+                       editor.setAction("FoldingCollapse", fCollapse); //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Returns <code>true</code> if the group is enabled.
+        * 
+        * <pre>
+        *  Invariant: isEnabled() &lt;=&gt; 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.getProjectionAnnotationModel() != null);
+                       fExpand.update();
+                       fExpandAll.update();
+                       fCollapse.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);
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.actions.ActionGroup#updateActionBars()
+        */
+       public void updateActionBars() {
+               update();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingExpandAllRulerAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingExpandAllRulerAction.java
new file mode 100644 (file)
index 0000000..9cbd454
--- /dev/null
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.AbstractRulerActionDelegate;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+/**
+ * Groups the JDT folding actions.
+ * 
+ * @since 3.0
+ */
+public class FoldingExpandAllRulerAction extends AbstractRulerActionDelegate {
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#createAction(org.eclipse.ui.texteditor.ITextEditor,
+        *      org.eclipse.jface.text.source.IVerticalRulerInfo)
+        */
+       protected IAction createAction(ITextEditor editor,
+                       IVerticalRulerInfo rulerInfo) {
+               TextOperationAction action = new TextOperationAction(
+                               ActionMessages.getResourceBundle(),
+                               "Projection.ExpandAll.", editor, ProjectionViewer.EXPAND_ALL, true); //$NON-NLS-1$
+               action.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND_ALL);
+               return action;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingToggleRulerAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/FoldingToggleRulerAction.java
new file mode 100644 (file)
index 0000000..49502ea
--- /dev/null
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.AbstractRulerActionDelegate;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+/**
+ * Groups the JDT folding actions.
+ * 
+ * @since 3.0
+ */
+public class FoldingToggleRulerAction extends AbstractRulerActionDelegate {
+
+       private IAction fUIAction;
+
+       private TextOperationAction fAction;
+
+       private ITextEditor fTextEditor;
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#createAction(org.eclipse.ui.texteditor.ITextEditor,
+        *      org.eclipse.jface.text.source.IVerticalRulerInfo)
+        */
+       protected IAction createAction(ITextEditor editor,
+                       IVerticalRulerInfo rulerInfo) {
+               fTextEditor = editor;
+               fAction = new TextOperationAction(ActionMessages.getResourceBundle(),
+                               "Projection.Toggle.", editor, ProjectionViewer.TOGGLE, true); //$NON-NLS-1$
+               fAction.setActionDefinitionId(IFoldingCommandIds.FOLDING_TOGGLE);
+
+               return fAction;
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction,
+        *      org.eclipse.ui.IEditorPart)
+        */
+       public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) {
+               fUIAction = callerAction;
+               super.setActiveEditor(callerAction, targetEditor);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
+        */
+       public void menuAboutToShow(IMenuManager manager) {
+               update();
+               super.menuAboutToShow(manager);
+       }
+
+       private void update() {
+               if (fTextEditor instanceof PHPEditor) {
+                       ISourceViewer viewer = ((PHPEditor) fTextEditor).getViewer();
+                       if (viewer instanceof ProjectionViewer) {
+                               boolean enabled = ((ProjectionViewer) viewer)
+                                               .getProjectionAnnotationModel() != null;
+                               fUIAction.setChecked(enabled);
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/IndentAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/IndentAction.java
new file mode 100644 (file)
index 0000000..0e133f0
--- /dev/null
@@ -0,0 +1,562 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.formatter.DefaultCodeFormatterConstants;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner;
+import net.sourceforge.phpdt.internal.ui.text.JavaIndenter;
+import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager;
+import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager.UndoSpec;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.JavaDocAutoIndentStrategy;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.IRewriteTarget;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorExtension3;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * Indents a line or range of lines in a Java document to its correct position.
+ * No complete AST must be present, the indentation is computed using
+ * heuristics. The algorith used is fast for single lines, but does not store
+ * any information and therefore not so efficient for large line ranges.
+ * 
+ * @see net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner
+ * @see net.sourceforge.phpdt.internal.ui.text.JavaIndenter
+ * @since 3.0
+ */
+public class IndentAction extends TextEditorAction {
+
+       /** The caret offset after an indent operation. */
+       private int fCaretOffset;
+
+       /**
+        * Whether this is the action invoked by TAB. When <code>true</code>,
+        * indentation behaves differently to accomodate normal TAB operation.
+        */
+       private final boolean fIsTabAction;
+
+       /**
+        * Creates a new instance.
+        * 
+        * @param bundle
+        *            the resource bundle
+        * @param prefix
+        *            the prefix to use for keys in <code>bundle</code>
+        * @param editor
+        *            the text editor
+        * @param isTabAction
+        *            whether the action should insert tabs if over the indentation
+        */
+       public IndentAction(ResourceBundle bundle, String prefix,
+                       ITextEditor editor, boolean isTabAction) {
+               super(bundle, prefix, editor);
+               fIsTabAction = isTabAction;
+       }
+
+       /*
+        * @see org.eclipse.jface.action.Action#run()
+        */
+       public void run() {
+               // update has been called by the framework
+               if (!isEnabled() || !validateEditorInputState())
+                       return;
+
+               ITextSelection selection = getSelection();
+               final IDocument document = getDocument();
+
+               if (document != null) {
+
+                       final int offset = selection.getOffset();
+                       final int length = selection.getLength();
+                       final Position end = new Position(offset + length);
+                       final int firstLine, nLines;
+                       fCaretOffset = -1;
+
+                       try {
+                               document.addPosition(end);
+                               firstLine = document.getLineOfOffset(offset);
+                               // check for marginal (zero-length) lines
+                               int minusOne = length == 0 ? 0 : 1;
+                               nLines = document.getLineOfOffset(offset + length - minusOne)
+                                               - firstLine + 1;
+                       } catch (BadLocationException e) {
+                               // will only happen on concurrent modification
+                               WebUI.log(new Status(IStatus.ERROR, WebUI
+                                               .getPluginId(), IStatus.OK, "", e)); //$NON-NLS-1$
+                               return;
+                       }
+
+                       Runnable runnable = new Runnable() {
+                               public void run() {
+                                       IRewriteTarget target = (IRewriteTarget) getTextEditor()
+                                                       .getAdapter(IRewriteTarget.class);
+                                       if (target != null) {
+                                               target.beginCompoundChange();
+                                               target.setRedraw(false);
+                                       }
+
+                                       try {
+                                               JavaHeuristicScanner scanner = new JavaHeuristicScanner(
+                                                               document);
+                                               JavaIndenter indenter = new JavaIndenter(document,
+                                                               scanner);
+                                               boolean hasChanged = false;
+                                               for (int i = 0; i < nLines; i++) {
+                                                       hasChanged |= indentLine(document, firstLine + i,
+                                                                       offset, indenter, scanner);
+                                               }
+
+                                               // update caret position: move to new position when
+                                               // indenting just one line
+                                               // keep selection when indenting multiple
+                                               int newOffset, newLength;
+                                               if (fIsTabAction) {
+                                                       newOffset = fCaretOffset;
+                                                       newLength = 0;
+                                               } else if (nLines > 1) {
+                                                       newOffset = offset;
+                                                       newLength = end.getOffset() - offset;
+                                               } else {
+                                                       newOffset = fCaretOffset;
+                                                       newLength = 0;
+                                               }
+
+                                               // always reset the selection if anything was replaced
+                                               // but not when we had a singleline nontab invocation
+                                               if (newOffset != -1
+                                                               && (hasChanged || newOffset != offset || newLength != length))
+                                                       selectAndReveal(newOffset, newLength);
+
+                                               document.removePosition(end);
+                                       } catch (BadLocationException e) {
+                                               // will only happen on concurrent modification
+                                               WebUI.log(new Status(IStatus.ERROR,
+                                                               WebUI.getPluginId(), IStatus.OK,
+                                                               "ConcurrentModification in IndentAction", e)); //$NON-NLS-1$
+
+                                       } finally {
+
+                                               if (target != null) {
+                                                       target.endCompoundChange();
+                                                       target.setRedraw(true);
+                                               }
+                                       }
+                               }
+                       };
+
+                       if (nLines > 50) {
+                               Display display = getTextEditor().getEditorSite()
+                                               .getWorkbenchWindow().getShell().getDisplay();
+                               BusyIndicator.showWhile(display, runnable);
+                       } else
+                               runnable.run();
+
+               }
+       }
+
+       /**
+        * Selects the given range on the editor.
+        * 
+        * @param newOffset
+        *            the selection offset
+        * @param newLength
+        *            the selection range
+        */
+       private void selectAndReveal(int newOffset, int newLength) {
+               Assert.isTrue(newOffset >= 0);
+               Assert.isTrue(newLength >= 0);
+               ITextEditor editor = getTextEditor();
+               if (editor instanceof PHPEditor) {
+                       ISourceViewer viewer = ((PHPEditor) editor).getViewer();
+                       if (viewer != null)
+                               viewer.setSelectedRange(newOffset, newLength);
+               } else
+                       // this is too intrusive, but will never get called anyway
+                       getTextEditor().selectAndReveal(newOffset, newLength);
+
+       }
+
+       /**
+        * Indents a single line using the java heuristic scanner. Javadoc and
+        * multiline comments are indented as specified by the
+        * <code>JavaDocAutoIndentStrategy</code>.
+        * 
+        * @param document
+        *            the document
+        * @param line
+        *            the line to be indented
+        * @param caret
+        *            the caret position
+        * @param indenter
+        *            the java indenter
+        * @param scanner
+        *            the heuristic scanner
+        * @return <code>true</code> if <code>document</code> was modified,
+        *         <code>false</code> otherwise
+        * @throws BadLocationException
+        *             if the document got changed concurrently
+        */
+       private boolean indentLine(IDocument document, int line, int caret,
+                       JavaIndenter indenter, JavaHeuristicScanner scanner)
+                       throws BadLocationException {
+               IRegion currentLine = document.getLineInformation(line);
+               int offset = currentLine.getOffset();
+               int wsStart = offset; // where we start searching for non-WS; after
+                                                               // the "//" in single line comments
+
+               String indent = null;
+               if (offset < document.getLength()) {
+                       ITypedRegion partition = TextUtilities.getPartition(document,
+                                       IPHPPartitions.PHP_PARTITIONING, offset, true);
+                       String type = partition.getType();
+                       if (type.equals(IPHPPartitions.PHP_PHPDOC_COMMENT)
+                                       || type.equals(IPHPPartitions.PHP_MULTILINE_COMMENT)) {
+
+                               // TODO this is a hack
+                               // what I want to do
+                               // new JavaDocAutoIndentStrategy().indentLineAtOffset(document,
+                               // offset);
+                               // return;
+
+                               int start = 0;
+                               if (line > 0) {
+
+                                       IRegion previousLine = document
+                                                       .getLineInformation(line - 1);
+                                       start = previousLine.getOffset() + previousLine.getLength();
+                               }
+
+                               DocumentCommand command = new DocumentCommand() {
+                               };
+                               command.text = "\n"; //$NON-NLS-1$
+                               command.offset = start;
+                               new JavaDocAutoIndentStrategy(IPHPPartitions.PHP_PARTITIONING)
+                                               .customizeDocumentCommand(document, command);
+                               int to = 1;
+                               while (to < command.text.length()
+                                               && Character.isWhitespace(command.text.charAt(to)))
+                                       to++;
+                               indent = command.text.substring(1, to);
+
+// omit Java style
+//                     } else if (!fIsTabAction && partition.getOffset() == offset
+//                                     && type.equals(IPHPPartitions.PHP_SINGLELINE_COMMENT)) {
+//
+//                             // line comment starting at position 0 -> indent inside
+//                             int slashes = 2;
+//                             while (slashes < document.getLength() - 1
+//                                             && document.get(offset + slashes, 2).equals("//")) //$NON-NLS-1$
+//                                     slashes += 2;
+//
+//                             wsStart = offset + slashes;
+//
+//                             StringBuffer computed = indenter.computeIndentation(offset);
+//                             int tabSize = PHPeclipsePlugin
+//                                             .getDefault()
+//                                             .getPreferenceStore()
+//                                             .getInt(
+//                                                             AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+//                             while (slashes > 0 && computed.length() > 0) {
+//                                     char c = computed.charAt(0);
+//                                     if (c == '\t')
+//                                             if (slashes > tabSize)
+//                                                     slashes -= tabSize;
+//                                             else
+//                                                     break;
+//                                     else if (c == ' ')
+//                                             slashes--;
+//                                     else
+//                                             break;
+//
+//                                     computed.deleteCharAt(0);
+//                             }
+//
+//                             indent = document.get(offset, wsStart - offset) + computed;
+
+                       }
+               }
+
+               // standard java indentation
+               if (indent == null) {
+                       StringBuffer computed = indenter.computeIndentation(offset);
+                       if (computed != null)
+                               indent = computed.toString();
+                       else
+                               //indent = new String();
+                               return true; // prevent affecting html part
+               }
+
+               // change document:
+               // get current white space
+               int lineLength = currentLine.getLength();
+               int end = scanner.findNonWhitespaceForwardInAnyPartition(wsStart,
+                               offset + lineLength);
+               if (end == JavaHeuristicScanner.NOT_FOUND)
+                       end = offset + lineLength;
+               int length = end - offset;
+               String currentIndent = document.get(offset, length);
+
+               // if we are right before the text start / line end, and already after
+               // the insertion point
+               // then just insert a tab.
+               if (fIsTabAction && caret == end
+                               && whiteSpaceLength(currentIndent) >= whiteSpaceLength(indent)) {
+                       String tab = getTabEquivalent();
+                       document.replace(caret, 0, tab);
+                       fCaretOffset = caret + tab.length();
+                       return true;
+               }
+
+               // set the caret offset so it can be used when setting the selection
+               if (caret >= offset && caret <= end)
+                       fCaretOffset = offset + indent.length();
+               else
+                       fCaretOffset = -1;
+
+               // only change the document if it is a real change
+               if (!indent.equals(currentIndent)) {
+                       String deletedText = document.get(offset, length);
+                       document.replace(offset, length, indent);
+
+                       if (fIsTabAction
+                                       && indent.length() > currentIndent.length()
+                                       && WebUI.getDefault().getPreferenceStore()
+                                                       .getBoolean(
+                                                                       PreferenceConstants.EDITOR_SMART_BACKSPACE)) {
+                               ITextEditor editor = getTextEditor();
+                               if (editor != null) {
+                                       final SmartBackspaceManager manager = (SmartBackspaceManager) editor
+                                                       .getAdapter(SmartBackspaceManager.class);
+                                       if (manager != null) {
+                                               try {
+                                                       // restore smart portion
+                                                       ReplaceEdit smart = new ReplaceEdit(offset, indent
+                                                                       .length(), deletedText);
+
+                                                       final UndoSpec spec = new UndoSpec(offset
+                                                                       + indent.length(), new Region(caret, 0),
+                                                                       new TextEdit[] { smart }, 2, null);
+                                                       manager.register(spec);
+                                               } catch (MalformedTreeException e) {
+                                                       // log & ignore
+                                                       WebUI.log(new Status(IStatus.ERROR,
+                                                                       WebUI.getPluginId(), IStatus.OK,
+                                                                       "Illegal smart backspace action", e)); //$NON-NLS-1$
+                                               }
+                                       }
+                               }
+                       }
+
+                       return true;
+               } else
+                       return false;
+       }
+
+       /**
+        * Returns the size in characters of a string. All characters count one,
+        * tabs count the editor's preference for the tab display
+        * 
+        * @param indent
+        *            the string to be measured.
+        * @return
+        */
+       private int whiteSpaceLength(String indent) {
+               if (indent == null)
+                       return 0;
+               else {
+                       int size = 0;
+                       int l = indent.length();
+                       int tabSize = WebUI.getDefault().getPreferenceStore().getInt(
+                                                       AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+
+                       for (int i = 0; i < l; i++)
+                               size += indent.charAt(i) == '\t' ? tabSize : 1;
+                       return size;
+               }
+       }
+
+       /**
+        * Returns a tab equivalent, either as a tab character or as spaces,
+        * depending on the editor and formatter preferences.
+        * 
+        * @return a string representing one tab in the editor, never
+        *         <code>null</code>
+        */
+       private String getTabEquivalent() {
+               String tab;
+               if (WebUI.getDefault().getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_SPACES_FOR_TABS)) {
+                       int size = JavaCore.getPlugin().getPluginPreferences().getInt(
+                                       DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE);
+                       StringBuffer buf = new StringBuffer();
+                       for (int i = 0; i < size; i++)
+                               buf.append(' ');
+                       tab = buf.toString();
+               } else
+                       tab = "\t"; //$NON-NLS-1$
+
+               return tab;
+       }
+
+       /**
+        * Returns the editor's selection provider.
+        * 
+        * @return the editor's selection provider or <code>null</code>
+        */
+       private ISelectionProvider getSelectionProvider() {
+               ITextEditor editor = getTextEditor();
+               if (editor != null) {
+                       return editor.getSelectionProvider();
+               }
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.IUpdate#update()
+        */
+       public void update() {
+               super.update();
+
+               if (isEnabled())
+                       if (fIsTabAction)
+                               setEnabled(canModifyEditor() && isSmartMode()
+                                               && isValidSelection());
+                       else
+                               setEnabled(canModifyEditor() && !getSelection().isEmpty());
+       }
+
+       /**
+        * Returns if the current selection is valid, i.e. whether it is empty and
+        * the caret in the whitespace at the start of a line, or covers multiple
+        * lines.
+        * 
+        * @return <code>true</code> if the selection is valid for an indent
+        *         operation
+        */
+       private boolean isValidSelection() {
+               ITextSelection selection = getSelection();
+               if (selection.isEmpty())
+                       return false;
+
+               int offset = selection.getOffset();
+               int length = selection.getLength();
+
+               IDocument document = getDocument();
+               if (document == null)
+                       return false;
+
+               try {
+                       IRegion firstLine = document.getLineInformationOfOffset(offset);
+                       int lineOffset = firstLine.getOffset();
+
+                       // either the selection has to be empty and the caret in the WS at
+                       // the line start
+                       // or the selection has to extend over multiple lines
+                       if (length == 0)
+                               return document.get(lineOffset, offset - lineOffset).trim()
+                                               .length() == 0;
+                       else
+                               // return lineOffset + firstLine.getLength() < offset + length;
+                               return false; // only enable for empty selections for now
+
+               } catch (BadLocationException e) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Returns the smart preference state.
+        * 
+        * @return <code>true</code> if smart mode is on, <code>false</code>
+        *         otherwise
+        */
+       private boolean isSmartMode() {
+               ITextEditor editor = getTextEditor();
+
+               if (editor instanceof ITextEditorExtension3)
+                       return ((ITextEditorExtension3) editor).getInsertMode() == ITextEditorExtension3.SMART_INSERT;
+
+               return false;
+       }
+
+       /**
+        * Returns the document currently displayed in the editor, or
+        * <code>null</code> if none can be obtained.
+        * 
+        * @return the current document or <code>null</code>
+        */
+       private IDocument getDocument() {
+
+               ITextEditor editor = getTextEditor();
+               if (editor != null) {
+
+                       IDocumentProvider provider = editor.getDocumentProvider();
+                       IEditorInput input = editor.getEditorInput();
+                       if (provider != null && input != null)
+                               return provider.getDocument(input);
+
+               }
+               return null;
+       }
+
+       /**
+        * Returns the selection on the editor or an invalid selection if none can
+        * be obtained. Returns never <code>null</code>.
+        * 
+        * @return the current selection, never <code>null</code>
+        */
+       private ITextSelection getSelection() {
+               ISelectionProvider provider = getSelectionProvider();
+               if (provider != null) {
+
+                       ISelection selection = provider.getSelection();
+                       if (selection instanceof ITextSelection)
+                               return (ITextSelection) selection;
+               }
+
+               // null object
+               return TextSelection.emptySelection();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/OpenActionUtil.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/OpenActionUtil.java
new file mode 100644 (file)
index 0000000..02c7b6b
--- /dev/null
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.ui.JavaElementLabelProvider;
+import net.sourceforge.phpeclipse.phpeditor.EditorUtility;
+
+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 JavaModelException,
+                       PartInitException {
+               open(element, true);
+       }
+
+       /**
+        * Opens the editor on the given element and subsequently selects it.
+        */
+       public static void open(Object element, boolean activate)
+                       throws JavaModelException, PartInitException {
+               IEditorPart part = EditorUtility.openInEditor(element, activate);
+               if (element instanceof IJavaElement)
+                       EditorUtility.revealInEditor(part, (IJavaElement) element);
+       }
+
+       /**
+        * Filters out source references from the given code resolve results. A
+        * utility method that can be called by subclassers.
+        */
+       public static List filterResolveResults(IJavaElement[] codeResolveResults) {
+               int nResults = codeResolveResults.length;
+               List refs = new ArrayList(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 ambigous java element. Utility method
+        * that can be called by subclassers.
+        */
+       public static IJavaElement selectJavaElement(IJavaElement[] elements,
+                       Shell shell, String title, String message) {
+
+               int nResults = elements.length;
+
+               if (nResults == 0)
+                       return null;
+
+               if (nResults == 1)
+                       return elements[0];
+
+               int flags = JavaElementLabelProvider.SHOW_DEFAULT
+                               | JavaElementLabelProvider.SHOW_QUALIFIED
+                               | JavaElementLabelProvider.SHOW_ROOT;
+
+               ElementListSelectionDialog dialog = new ElementListSelectionDialog(
+                               shell, new JavaElementLabelProvider(flags));
+               dialog.setTitle(title);
+               dialog.setMessage(message);
+               dialog.setElements(elements);
+
+               if (dialog.open() == ElementListSelectionDialog.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 IJavaElement)
+                                               return (IJavaElement) current;
+                               }
+                       }
+               }
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/RemoveBlockCommentAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/RemoveBlockCommentAction.java
new file mode 100644 (file)
index 0000000..f1709fc
--- /dev/null
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPartitioningException;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Action that removes the enclosing comment marks from a Java block comment.
+ * 
+ * @since 3.0
+ */
+public class RemoveBlockCommentAction extends BlockCommentAction {
+
+       /**
+        * Creates a new instance.
+        * 
+        * @param bundle
+        *            the resource bundle
+        * @param prefix
+        *            a prefix to be prepended to the various resource keys
+        *            (described in <code>ResourceAction</code> constructor), or
+        *            <code>null</code> if none
+        * @param editor
+        *            the text editor
+        */
+       public RemoveBlockCommentAction(ResourceBundle bundle, String prefix,
+                       ITextEditor editor) {
+               super(bundle, prefix, editor);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.actions.AddBlockCommentAction#runInternal(org.eclipse.jface.text.ITextSelection,
+        *      org.eclipse.jface.text.IDocumentExtension3,
+        *      net.sourceforge.phpdt.internal.ui.actions.AddBlockCommentAction.Edit.EditFactory)
+        */
+       protected void runInternal(ITextSelection selection,
+                       IDocumentExtension3 docExtension, Edit.EditFactory factory)
+                       throws BadPartitioningException, BadLocationException {
+               List edits = new LinkedList();
+               int tokenLength = getCommentStart().length();
+
+               int offset = selection.getOffset();
+               int endOffset = offset + selection.getLength();
+
+               ITypedRegion partition = docExtension.getPartition(
+                               IPHPPartitions.PHP_PARTITIONING, offset, false);
+               int partOffset = partition.getOffset();
+               int partEndOffset = partOffset + partition.getLength();
+
+               while (partEndOffset < endOffset) {
+
+                       if (partition.getType() == IPHPPartitions.PHP_MULTILINE_COMMENT) {
+                               edits.add(factory.createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
+                               edits.add(factory.createEdit(partEndOffset - tokenLength,
+                                               tokenLength, "")); //$NON-NLS-1$
+                       }
+
+                       partition = docExtension.getPartition(
+                                       IPHPPartitions.PHP_PARTITIONING, partEndOffset, false);
+                       partOffset = partition.getOffset();
+                       partEndOffset = partOffset + partition.getLength();
+               }
+
+               if (partition.getType() == IPHPPartitions.PHP_MULTILINE_COMMENT) {
+                       edits.add(factory.createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
+                       edits.add(factory.createEdit(partEndOffset - tokenLength,
+                                       tokenLength, "")); //$NON-NLS-1$
+               }
+
+               executeEdits(edits);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.actions.AddBlockCommentAction#validSelection(org.eclipse.jface.text.ITextSelection)
+        */
+       protected boolean isValidSelection(ITextSelection selection) {
+               return selection != null && !selection.isEmpty();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/SelectionConverter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/SelectionConverter.java
new file mode 100644 (file)
index 0000000..7fb9328
--- /dev/null
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IWorkbenchPart;
+
+public class SelectionConverter {
+
+       private static final IJavaElement[] EMPTY_RESULT = new IJavaElement[0];
+
+       private SelectionConverter() {
+               // no instance
+       }
+
+       /**
+        * Converts the selection provided by the given part into a structured
+        * selection. The following conversion rules are used:
+        * <ul>
+        * <li><code>part instanceof PHPEditor</code>: returns a structured
+        * selection using code resolve to convert the editor's text selection.</li>
+        * <li><code>part instanceof IWorkbenchPart</code>: returns the part's
+        * selection if it is a structured selection.</li>
+        * <li><code>default</code>: returns an empty structured selection.</li>
+        * </ul>
+        */
+       public static IStructuredSelection getStructuredSelection(
+                       IWorkbenchPart part) throws JavaModelException {
+               if (part instanceof PHPEditor)
+                       return new StructuredSelection(codeResolve((PHPEditor) part));
+               ISelectionProvider provider = part.getSite().getSelectionProvider();
+               if (provider != null) {
+                       ISelection selection = provider.getSelection();
+                       if (selection instanceof IStructuredSelection)
+                               return (IStructuredSelection) selection;
+               }
+               return StructuredSelection.EMPTY;
+       }
+
+       /**
+        * Converts the given structured selection into an array of Java elements.
+        * An empty array is returned if one of the elements stored in the
+        * structured selection is not of tupe <code>IJavaElement</code>
+        */
+       public static IJavaElement[] getElements(IStructuredSelection selection) {
+               if (!selection.isEmpty()) {
+                       IJavaElement[] result = new IJavaElement[selection.size()];
+                       int i = 0;
+                       for (Iterator iter = selection.iterator(); iter.hasNext(); i++) {
+                               Object element = (Object) iter.next();
+                               if (!(element instanceof IJavaElement))
+                                       return EMPTY_RESULT;
+                               result[i] = (IJavaElement) element;
+                       }
+                       return result;
+               }
+               return EMPTY_RESULT;
+       }
+
+       public static boolean canOperateOn(PHPEditor editor) {
+               if (editor == null)
+                       return false;
+               return getInput(editor) != null;
+
+       }
+
+       /**
+        * Converts the text selection provided by the given editor into an array of
+        * Java elements. If the selection doesn't cover a Java element and the
+        * selection's length is greater than 0 the methods returns the editor's
+        * input element.
+        */
+       public static IJavaElement[] codeResolveOrInput(PHPEditor editor)
+                       throws JavaModelException {
+               IJavaElement input = getInput(editor);
+               ITextSelection selection = (ITextSelection) editor
+                               .getSelectionProvider().getSelection();
+               IJavaElement[] result = codeResolve(input, selection);
+               if (result.length == 0) {
+                       result = new IJavaElement[] { input };
+               }
+               return result;
+       }
+
+       public static IJavaElement[] codeResolveOrInputHandled(PHPEditor editor,
+                       Shell shell, String title) {
+               try {
+                       return codeResolveOrInput(editor);
+               } catch (JavaModelException e) {
+                       ExceptionHandler.handle(e, shell, title, ActionMessages
+                                       .getString("SelectionConverter.codeResolve_failed")); //$NON-NLS-1$
+               }
+               return null;
+       }
+
+       /**
+        * Converts the text selection provided by the given editor a Java element
+        * by asking the user if code reolve returned more than one result. If the
+        * selection doesn't cover a Java element and the selection's length is
+        * greater than 0 the methods returns the editor's input element.
+        */
+       public static IJavaElement codeResolveOrInput(PHPEditor editor,
+                       Shell shell, String title, String message)
+                       throws JavaModelException {
+               IJavaElement[] elements = codeResolveOrInput(editor);
+               if (elements == null || elements.length == 0)
+                       return null;
+               IJavaElement candidate = elements[0];
+               if (elements.length > 1) {
+                       candidate = OpenActionUtil.selectJavaElement(elements, shell,
+                                       title, message);
+               }
+               return candidate;
+       }
+
+       public static IJavaElement codeResolveOrInputHandled(PHPEditor editor,
+                       Shell shell, String title, String message) {
+               try {
+                       return codeResolveOrInput(editor, shell, title, message);
+               } catch (JavaModelException e) {
+                       ExceptionHandler.handle(e, shell, title, ActionMessages
+                                       .getString("SelectionConverter.codeResolveOrInput_failed")); //$NON-NLS-1$
+               }
+               return null;
+       }
+
+       public static IJavaElement[] codeResolve(PHPEditor editor)
+                       throws JavaModelException {
+               return codeResolve(getInput(editor), (ITextSelection) editor
+                               .getSelectionProvider().getSelection());
+       }
+
+       /**
+        * Converts the text selection provided by the given editor a Java element
+        * by asking the user if code reolve returned more than one result. If the
+        * selection doesn't cover a Java element <code>null</code> is returned.
+        */
+       public static IJavaElement codeResolve(PHPEditor editor, Shell shell,
+                       String title, String message) throws JavaModelException {
+               IJavaElement[] elements = codeResolve(editor);
+               if (elements == null || elements.length == 0)
+                       return null;
+               IJavaElement candidate = elements[0];
+               if (elements.length > 1) {
+                       candidate = OpenActionUtil.selectJavaElement(elements, shell,
+                                       title, message);
+               }
+               return candidate;
+       }
+
+       public static IJavaElement[] codeResolveHandled(PHPEditor editor,
+                       Shell shell, String title) {
+               try {
+                       return codeResolve(editor);
+               } catch (JavaModelException e) {
+                       ExceptionHandler.handle(e, shell, title, ActionMessages
+                                       .getString("SelectionConverter.codeResolve_failed")); //$NON-NLS-1$
+               }
+               return null;
+       }
+
+       public static IJavaElement getElementAtOffset(PHPEditor editor)
+                       throws JavaModelException {
+               return getElementAtOffset(getInput(editor), (ITextSelection) editor
+                               .getSelectionProvider().getSelection());
+       }
+
+       public static IType getTypeAtOffset(PHPEditor editor)
+                       throws JavaModelException {
+               IJavaElement element = SelectionConverter.getElementAtOffset(editor);
+               IType type = (IType) element.getAncestor(IJavaElement.TYPE);
+               if (type == null) {
+                       ICompilationUnit unit = SelectionConverter
+                                       .getInputAsCompilationUnit(editor);
+                       if (unit != null)
+                               type = unit.findPrimaryType();
+               }
+               return type;
+       }
+
+       public static IJavaElement getInput(PHPEditor editor) {
+               if (editor == null)
+                       return null;
+               IEditorInput input = editor.getEditorInput();
+               // if (input instanceof IClassFileEditorInput)
+               // return ((IClassFileEditorInput)input).getClassFile();
+               IWorkingCopyManager manager = WebUI.getDefault()
+                               .getWorkingCopyManager();
+               return manager.getWorkingCopy(input);
+       }
+
+       public static ICompilationUnit getInputAsCompilationUnit(PHPEditor editor) {
+               Object editorInput = SelectionConverter.getInput(editor);
+               if (editorInput instanceof ICompilationUnit)
+                       return (ICompilationUnit) editorInput;
+               else
+                       return null;
+       }
+
+       private static IJavaElement[] codeResolve(IJavaElement input,
+                       ITextSelection selection) throws JavaModelException {
+               // if (input instanceof ICodeAssist) {
+               // IJavaElement[] elements=
+               // ((ICodeAssist)input).codeSelect(selection.getOffset(),
+               // selection.getLength());
+               // if (elements != null && elements.length > 0)
+               // return elements;
+               // }
+               return EMPTY_RESULT;
+       }
+
+       private static IJavaElement getElementAtOffset(IJavaElement input,
+                       ITextSelection selection) throws JavaModelException {
+               if (input instanceof ICompilationUnit) {
+                       ICompilationUnit cunit = (ICompilationUnit) input;
+                       if (cunit.isWorkingCopy()) {
+                               synchronized (cunit) {
+                                       cunit.reconcile();
+                               }
+                       }
+                       IJavaElement ref = cunit.getElementAt(selection.getOffset());
+                       if (ref == null)
+                               return input;
+                       else
+                               return ref;
+               }
+               // else if (input instanceof IClassFile) {
+               // IJavaElement ref=
+               // ((IClassFile)input).getElementAt(selection.getOffset());
+               // if (ref == null)
+               // return input;
+               // else
+               // return ref;
+               // }
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/SelectionDispatchAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/SelectionDispatchAction.java
new file mode 100644 (file)
index 0000000..6f71be1
--- /dev/null
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.util.Assert;
+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 plugin.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public abstract class SelectionDispatchAction extends Action implements
+               ISelectionChangedListener {
+
+       private IWorkbenchSite fSite;
+
+       /**
+        * 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;
+       }
+
+       /**
+        * 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() {
+               return getSelectionProvider().getSelection();
+       }
+
+       /**
+        * 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.
+        * 
+        * @return the site's selection provider
+        */
+       public ISelectionProvider getSelectionProvider() {
+               return fSite.getSelectionProvider();
+       }
+
+       /**
+        * 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
+        */
+       protected void selectionChanged(IStructuredSelection selection) {
+               selectionChanged((ISelection) selection);
+       }
+
+       /**
+        * Executes this actions with the given structured selection. This default
+        * implementation calls <code>run(ISelection selection)</code>.
+        */
+       protected 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
+        */
+       protected void selectionChanged(ITextSelection selection) {
+               selectionChanged((ISelection) selection);
+       }
+
+       /**
+        * Executes this actions with the given text selection. This default
+        * implementation calls <code>run(ISelection selection)</code>.
+        */
+       protected 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
+        */
+       protected void selectionChanged(ISelection selection) {
+               setEnabled(false);
+       }
+
+       /**
+        * Executes this actions with the given selection. This default
+        * implementation does nothing.
+        */
+       protected 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);
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/WorkbenchRunnableAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/actions/WorkbenchRunnableAdapter.java
new file mode 100644 (file)
index 0000000..6a85665
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.lang.reflect.InvocationTargetException;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+
+/**
+ * An <code>IRunnableWithProgress</code> that adapts and
+ * <code>IWorkspaceRunnable</code> so that is can be executed inside
+ * <code>IRunnableContext</code>. <code>OperationCanceledException</code>
+ * thrown by the apapted runnabled are cought and rethrown as a
+ * <code>InterruptedException</code>.
+ */
+public class WorkbenchRunnableAdapter implements IRunnableWithProgress {
+
+       private IWorkspaceRunnable fWorkspaceRunnable;
+
+       public WorkbenchRunnableAdapter(IWorkspaceRunnable runnable) {
+               fWorkspaceRunnable = runnable;
+       }
+
+       /*
+        * @see IRunnableWithProgress#run(IProgressMonitor)
+        */
+       public void run(IProgressMonitor monitor) throws InvocationTargetException,
+                       InterruptedException {
+               try {
+                       PHPeclipsePlugin.run(fWorkspaceRunnable, monitor);
+               } catch (OperationCanceledException e) {
+                       throw new InterruptedException(e.getMessage());
+               } catch (CoreException e) {
+                       throw new InvocationTargetException(e);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/AbstractElementListSelectionDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/AbstractElementListSelectionDialog.java
new file mode 100644 (file)
index 0000000..103f5e5
--- /dev/null
@@ -0,0 +1,460 @@
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+import net.sourceforge.phpdt.internal.ui.util.FilteredList;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * An abstract class to select elements out of a list of elements.
+ */
+public abstract class AbstractElementListSelectionDialog extends
+               SelectionStatusDialog {
+
+       private ILabelProvider fRenderer;
+
+       private boolean fIgnoreCase = true;
+
+       private boolean fIsMultipleSelection = false;
+
+       private boolean fMatchEmptyString = true;
+
+       private boolean fAllowDuplicates = true;
+
+       private Label fMessage;
+
+       protected FilteredList fFilteredList;
+
+       private Text fFilterText;
+
+       private ISelectionValidator fValidator;
+
+       private String fFilter = null;
+
+       private String fEmptyListMessage = ""; //$NON-NLS-1$
+
+       private String fEmptySelectionMessage = ""; //$NON-NLS-1$
+
+       private int fWidth = 60;
+
+       private int fHeight = 18;
+
+       private Object[] fSelection = new Object[0];
+
+       /**
+        * Constructs a list selection dialog.
+        * 
+        * @param renderer
+        *            The label renderer used
+        * @param ignoreCase
+        *            Decides if the match string ignores lower/upppr case
+        * @param multipleSelection
+        *            Allow multiple selection
+        */
+       protected AbstractElementListSelectionDialog(Shell parent,
+                       ILabelProvider renderer) {
+               super(parent);
+               fRenderer = renderer;
+
+               int shellStyle = getShellStyle();
+               setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
+       }
+
+       /**
+        * Handles default selection (double click). By default, the OK button is
+        * pressed.
+        */
+       protected void handleDefaultSelected() {
+               if (validateCurrentSelection())
+                       buttonPressed(IDialogConstants.OK_ID);
+       }
+
+       /**
+        * Specifies if sorting, filtering and folding is case sensitive.
+        */
+       public void setIgnoreCase(boolean ignoreCase) {
+               fIgnoreCase = ignoreCase;
+       }
+
+       /**
+        * Returns if sorting, filtering and folding is case sensitive.
+        */
+       public boolean isCaseIgnored() {
+               return fIgnoreCase;
+       }
+
+       /**
+        * Specifies whether everything or nothing should be filtered on empty
+        * filter string.
+        */
+       public void setMatchEmptyString(boolean matchEmptyString) {
+               fMatchEmptyString = matchEmptyString;
+       }
+
+       /**
+        * Specifies if multiple selection is allowed.
+        */
+       public void setMultipleSelection(boolean multipleSelection) {
+               fIsMultipleSelection = multipleSelection;
+       }
+
+       /**
+        * Specifies whether duplicate entries are displayed or not.
+        */
+       public void setAllowDuplicates(boolean allowDuplicates) {
+               fAllowDuplicates = allowDuplicates;
+       }
+
+       /**
+        * Sets the list size in unit of characters.
+        * 
+        * @param width
+        *            the width of the list.
+        * @param height
+        *            the height of the list.
+        */
+       public void setSize(int width, int height) {
+               fWidth = width;
+               fHeight = height;
+       }
+
+       /**
+        * Sets the message to be displayed if the list is empty.
+        * 
+        * @param message
+        *            the message to be displayed.
+        */
+       public void setEmptyListMessage(String message) {
+               fEmptyListMessage = message;
+       }
+
+       /**
+        * Sets the message to be displayed if the selection is empty.
+        * 
+        * @param message
+        *            the message to be displayed.
+        */
+       public void setEmptySelectionMessage(String message) {
+               fEmptySelectionMessage = message;
+       }
+
+       /**
+        * Sets an optional validator to check if the selection is valid. The
+        * validator is invoked whenever the selection changes.
+        * 
+        * @param validator
+        *            the validator to validate the selection.
+        */
+       public void setValidator(ISelectionValidator validator) {
+               fValidator = validator;
+       }
+
+       /**
+        * Sets the elements of the list (widget). To be called within open().
+        * 
+        * @param elements
+        *            the elements of the list.
+        */
+       protected void setListElements(Object[] elements) {
+               Assert.isNotNull(fFilteredList);
+               fFilteredList.setElements(elements);
+       }
+
+       /**
+        * Sets the filter pattern.
+        * 
+        * @param filter
+        *            the filter pattern.
+        */
+       public void setFilter(String filter) {
+               if (fFilterText == null)
+                       fFilter = filter;
+               else
+                       fFilterText.setText(filter);
+       }
+
+       /**
+        * Returns the current filter pattern.
+        * 
+        * @return returns the current filter pattern or
+        *         <code>null<code> if filter was not set.
+        */
+       public String getFilter() {
+               if (fFilteredList == null)
+                       return fFilter;
+               else
+                       return fFilteredList.getFilter();
+       }
+
+       /**
+        * Returns the indices referring the current selection. To be called within
+        * open().
+        * 
+        * @return returns the indices of the current selection.
+        */
+       protected int[] getSelectionIndices() {
+               Assert.isNotNull(fFilteredList);
+               return fFilteredList.getSelectionIndices();
+       }
+
+       /**
+        * Returns an index referring the first current selection. To be called
+        * within open().
+        * 
+        * @return returns the indices of the current selection.
+        */
+       protected int getSelectionIndex() {
+               Assert.isNotNull(fFilteredList);
+               return fFilteredList.getSelectionIndex();
+       }
+
+       /**
+        * Sets the selection referenced by an array of elements. To be called
+        * within open().
+        * 
+        * @param selection
+        *            the indices of the selection.
+        */
+       protected void setSelection(Object[] selection) {
+               Assert.isNotNull(fFilteredList);
+               fFilteredList.setSelection(selection);
+       }
+
+       /**
+        * Returns an array of the currently selected elements. To be called within
+        * or after open().
+        * 
+        * @return returns an array of the currently selected elements.
+        */
+       protected Object[] getSelectedElements() {
+               Assert.isNotNull(fFilteredList);
+               return fFilteredList.getSelection();
+       }
+
+       /**
+        * Returns all elements which are folded together to one entry in the list.
+        * 
+        * @param index
+        *            the index selecting the entry in the list.
+        * @return returns an array of elements folded together.
+        */
+       public Object[] getFoldedElements(int index) {
+               Assert.isNotNull(fFilteredList);
+               return fFilteredList.getFoldedElements(index);
+       }
+
+       /**
+        * Creates the message text widget and sets layout data.
+        * 
+        * @param composite
+        *            the parent composite of the message area.
+        */
+       protected Label createMessageArea(Composite composite) {
+               Label label = super.createMessageArea(composite);
+
+               GridData data = new GridData();
+               data.grabExcessVerticalSpace = false;
+               data.grabExcessHorizontalSpace = true;
+               data.horizontalAlignment = GridData.FILL;
+               data.verticalAlignment = GridData.BEGINNING;
+               label.setLayoutData(data);
+
+               fMessage = label;
+
+               return label;
+       }
+
+       /**
+        * Handles a selection changed event. By default, the current selection is
+        * validated.
+        */
+       protected void handleSelectionChanged() {
+               validateCurrentSelection();
+       }
+
+       /**
+        * Validates the current selection and updates the status line accordingly.
+        */
+       protected boolean validateCurrentSelection() {
+               Assert.isNotNull(fFilteredList);
+
+               IStatus status;
+               Object[] elements = getSelectedElements();
+
+               if (elements.length > 0) {
+                       if (fValidator != null) {
+                               status = fValidator.validate(elements);
+                       } else {
+                               status = new StatusInfo();
+                       }
+               } else {
+                       if (fFilteredList.isEmpty()) {
+                               status = new StatusInfo(IStatus.ERROR, fEmptyListMessage);
+                       } else {
+                               status = new StatusInfo(IStatus.ERROR, fEmptySelectionMessage);
+                       }
+               }
+
+               updateStatus(status);
+
+               return status.isOK();
+       }
+
+       /*
+        * @see Dialog#cancelPressed
+        */
+       protected void cancelPressed() {
+               setResult(null);
+               super.cancelPressed();
+       }
+
+       /**
+        * Creates a filtered list.
+        * 
+        * @param parent
+        *            the parent composite.
+        * @return returns the filtered list widget.
+        */
+       protected FilteredList createFilteredList(Composite parent) {
+               int flags = SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL
+                               | (fIsMultipleSelection ? SWT.MULTI : SWT.SINGLE);
+
+               FilteredList list = new FilteredList(parent, flags, fRenderer,
+                               fIgnoreCase, fAllowDuplicates, fMatchEmptyString);
+
+               GridData data = new GridData();
+               data.widthHint = convertWidthInCharsToPixels(fWidth);
+               data.heightHint = convertHeightInCharsToPixels(fHeight);
+               data.grabExcessVerticalSpace = true;
+               data.grabExcessHorizontalSpace = true;
+               data.horizontalAlignment = GridData.FILL;
+               data.verticalAlignment = GridData.FILL;
+               list.setLayoutData(data);
+
+               list.setFilter((fFilter == null ? "" : fFilter)); //$NON-NLS-1$         
+
+               list.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               handleDefaultSelected();
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               handleWidgetSelected();
+                       }
+               });
+
+               fFilteredList = list;
+
+               return list;
+       }
+
+       // 3515
+       private void handleWidgetSelected() {
+               Object[] newSelection = fFilteredList.getSelection();
+
+               if (newSelection.length != fSelection.length) {
+                       fSelection = newSelection;
+                       handleSelectionChanged();
+               } else {
+                       for (int i = 0; i != newSelection.length; i++) {
+                               if (!newSelection[i].equals(fSelection[i])) {
+                                       fSelection = newSelection;
+                                       handleSelectionChanged();
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       protected Text createFilterText(Composite parent) {
+               Text text = new Text(parent, SWT.BORDER);
+
+               GridData data = new GridData();
+               data.grabExcessVerticalSpace = false;
+               data.grabExcessHorizontalSpace = true;
+               data.horizontalAlignment = GridData.FILL;
+               data.verticalAlignment = GridData.BEGINNING;
+               text.setLayoutData(data);
+
+               text.setText((fFilter == null ? "" : fFilter)); //$NON-NLS-1$
+
+               Listener listener = new Listener() {
+                       public void handleEvent(Event e) {
+                               fFilteredList.setFilter(fFilterText.getText());
+                       }
+               };
+               text.addListener(SWT.Modify, listener);
+
+               text.addKeyListener(new KeyListener() {
+                       public void keyPressed(KeyEvent e) {
+                               if (e.keyCode == SWT.ARROW_DOWN)
+                                       fFilteredList.setFocus();
+                       }
+
+                       public void keyReleased(KeyEvent e) {
+                       }
+               });
+
+               fFilterText = text;
+
+               return text;
+       }
+
+       /*
+        * @see Window#open()
+        */
+       public int open() {
+               BusyIndicator.showWhile(null, new Runnable() {
+                       public void run() {
+                               access$superOpen();
+                       }
+               });
+               return getReturnCode();
+       }
+
+       private void access$superOpen() {
+               super.open();
+       }
+
+       /*
+        * @see Window#create(Shell)
+        */
+       public void create() {
+               super.create();
+
+               Assert.isNotNull(fFilteredList);
+
+               if (fFilteredList.isEmpty()) {
+                       handleEmptyList();
+               } else {
+                       validateCurrentSelection();
+                       fFilterText.selectAll();
+                       fFilterText.setFocus();
+               }
+       }
+
+       /**
+        * Handles empty list by disabling widgets.
+        */
+       protected void handleEmptyList() {
+               fMessage.setEnabled(false);
+               fFilterText.setEnabled(false);
+               fFilteredList.setEnabled(false);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/CheckedTreeSelectionDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/CheckedTreeSelectionDialog.java
new file mode 100644 (file)
index 0000000..deb47fc
--- /dev/null
@@ -0,0 +1,353 @@
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.ContainerCheckedTreeViewer;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+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.SelectionAdapter;
+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.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;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * A class to select elements out of a tree structure.
+ */
+public class CheckedTreeSelectionDialog extends SelectionStatusDialog {
+
+       private CheckboxTreeViewer fViewer;
+
+       private ILabelProvider fLabelProvider;
+
+       private ITreeContentProvider fContentProvider;
+
+       private ISelectionValidator fValidator = null;
+
+       private ViewerSorter fSorter;
+
+       private String fEmptyListMessage = "No entries available";
+
+       private IStatus fCurrStatus = new StatusInfo();
+
+       private List fFilters;
+
+       private Object fInput;
+
+       private boolean fIsEmpty;
+
+       private int fWidth = 60;
+
+       private int fHeight = 18;
+
+       private boolean fContainerMode;
+
+       private Object[] fExpandedElements;
+
+       /**
+        * Constructs an instance of <code>ElementTreeSelectionDialog</code>.
+        * 
+        * @param labelProvider
+        *            the label provider to render the entries
+        * @param contentProvider
+        *            the content provider to evaluate the tree structure
+        */
+       public CheckedTreeSelectionDialog(Shell parent,
+                       ILabelProvider labelProvider, ITreeContentProvider contentProvider) {
+               super(parent);
+
+               fLabelProvider = labelProvider;
+               fContentProvider = contentProvider;
+
+               setResult(new ArrayList(0));
+               setStatusLineAboveButtons(true);
+
+               fContainerMode = false;
+               fExpandedElements = null;
+
+               int shellStyle = getShellStyle();
+               setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
+       }
+
+       /**
+        * If set, the checked /gray state of containers (inner nodes) is derived
+        * from the checked state of its leaf nodes.
+        * 
+        * @param containerMode
+        *            The containerMode to set
+        */
+       public void setContainerMode(boolean containerMode) {
+               fContainerMode = containerMode;
+       }
+
+       /**
+        * Sets the initial selection. Convenience method.
+        * 
+        * @param selection
+        *            the initial selection.
+        */
+       public void setInitialSelection(Object selection) {
+               setInitialSelections(new Object[] { selection });
+       }
+
+       /**
+        * Sets the message to be displayed if the list is empty.
+        * 
+        * @param message
+        *            the message to be displayed.
+        */
+       public void setEmptyListMessage(String message) {
+               fEmptyListMessage = message;
+       }
+
+       /**
+        * Sets the sorter used by the tree viewer.
+        */
+       public void setSorter(ViewerSorter sorter) {
+               fSorter = sorter;
+       }
+
+       /**
+        * Adds a filter to the tree viewer.
+        * 
+        * @param filter
+        *            a filter.
+        */
+       public void addFilter(ViewerFilter filter) {
+               if (fFilters == null)
+                       fFilters = new ArrayList(4);
+
+               fFilters.add(filter);
+       }
+
+       /**
+        * Sets an optional validator to check if the selection is valid. The
+        * validator is invoked whenever the selection changes.
+        * 
+        * @param validator
+        *            the validator to validate the selection.
+        */
+       public void setValidator(ISelectionValidator validator) {
+               fValidator = validator;
+       }
+
+       /**
+        * Sets the tree input.
+        * 
+        * @param input
+        *            the tree input.
+        */
+       public void setInput(Object input) {
+               fInput = input;
+       }
+
+       /**
+        * Expands the tree
+        */
+       public void setExpandedElements(Object[] elements) {
+               fExpandedElements = elements;
+       }
+
+       /**
+        * Sets the size of the tree in unit of characters.
+        * 
+        * @param width
+        *            the width of the tree.
+        * @param height
+        *            the height of the tree.
+        */
+       public void setSize(int width, int height) {
+               fWidth = width;
+               fHeight = height;
+       }
+
+       protected void updateOKStatus() {
+               if (!fIsEmpty) {
+                       if (fValidator != null) {
+                               fCurrStatus = fValidator.validate(fViewer.getCheckedElements());
+                               updateStatus(fCurrStatus);
+                       } else if (!fCurrStatus.isOK()) {
+                               fCurrStatus = new StatusInfo();
+                       }
+               } else {
+                       fCurrStatus = new StatusInfo(IStatus.ERROR, fEmptyListMessage);
+               }
+               updateStatus(fCurrStatus);
+       }
+
+       /*
+        * @see Window#open()
+        */
+       public int open() {
+               fIsEmpty = evaluateIfTreeEmpty(fInput);
+               BusyIndicator.showWhile(null, new Runnable() {
+                       public void run() {
+                               access$superOpen();
+                       }
+               });
+
+               return getReturnCode();
+       }
+
+       private void access$superOpen() {
+               super.open();
+       }
+
+       /**
+        * Handles cancel button pressed event.
+        */
+       protected void cancelPressed() {
+               setResult(null);
+               super.cancelPressed();
+       }
+
+       /*
+        * @see SelectionStatusDialog#computeResult()
+        */
+       protected void computeResult() {
+               setResult(Arrays.asList(fViewer.getCheckedElements()));
+       }
+
+       /*
+        * @see Window#create()
+        */
+       public void create() {
+               super.create();
+
+               List initialSelections = getInitialElementSelections();
+               if (initialSelections != null) {
+                       fViewer.setCheckedElements(initialSelections.toArray());
+               }
+
+               if (fExpandedElements != null) {
+                       fViewer.setExpandedElements(fExpandedElements);
+               }
+
+               updateOKStatus();
+       }
+
+       /*
+        * @see Dialog#createDialogArea(Composite)
+        */
+       protected Control createDialogArea(Composite parent) {
+               Composite composite = (Composite) super.createDialogArea(parent);
+
+               Label messageLabel = createMessageArea(composite);
+               Control treeWidget = createTreeViewer(composite);
+               Control buttonComposite = createSelectionButtons(composite);
+
+               GridData data = new GridData(GridData.FILL_BOTH);
+               data.widthHint = convertWidthInCharsToPixels(fWidth);
+               data.heightHint = convertHeightInCharsToPixels(fHeight);
+               treeWidget.setLayoutData(data);
+
+               if (fIsEmpty) {
+                       messageLabel.setEnabled(false);
+                       treeWidget.setEnabled(false);
+                       buttonComposite.setEnabled(false);
+               }
+
+               return composite;
+       }
+
+       private Tree createTreeViewer(Composite parent) {
+               if (fContainerMode) {
+                       fViewer = new ContainerCheckedTreeViewer(parent, SWT.BORDER);
+               } else {
+                       fViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
+               }
+
+               fViewer.setContentProvider(fContentProvider);
+               fViewer.setLabelProvider(fLabelProvider);
+               fViewer.addCheckStateListener(new ICheckStateListener() {
+                       public void checkStateChanged(CheckStateChangedEvent event) {
+                               updateOKStatus();
+                       }
+               });
+
+               fViewer.setSorter(fSorter);
+               if (fFilters != null) {
+                       for (int i = 0; i != fFilters.size(); i++)
+                               fViewer.addFilter((ViewerFilter) fFilters.get(i));
+               }
+
+               fViewer.setInput(fInput);
+
+               return fViewer.getTree();
+       }
+
+       /**
+        * Add the selection and deselection buttons to the dialog.
+        * 
+        * @param composite
+        *            org.eclipse.swt.widgets.Composite
+        */
+       private Composite createSelectionButtons(Composite composite) {
+
+               Composite buttonComposite = new Composite(composite, SWT.RIGHT);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               buttonComposite.setLayout(layout);
+               GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END
+                               | GridData.GRAB_HORIZONTAL);
+               data.grabExcessHorizontalSpace = true;
+               composite.setData(data);
+
+               Button selectButton = createButton(buttonComposite,
+                               IDialogConstants.SELECT_ALL_ID, "Select &All", false);
+
+               SelectionListener listener = new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               fViewer
+                                               .setCheckedElements(fContentProvider
+                                                               .getElements(fInput));
+                               updateOKStatus();
+                       }
+               };
+               selectButton.addSelectionListener(listener);
+
+               Button deselectButton = createButton(buttonComposite,
+                               IDialogConstants.DESELECT_ALL_ID, "&Deselect All", false);
+
+               listener = new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               fViewer.setCheckedElements(new Object[0]);
+                               updateOKStatus();
+                       }
+               };
+               deselectButton.addSelectionListener(listener);
+               return buttonComposite;
+       }
+
+       private boolean evaluateIfTreeEmpty(Object input) {
+               Object[] elements = fContentProvider.getElements(input);
+               if (elements.length > 0) {
+                       if (fFilters != null) {
+                               for (int i = 0; i < fFilters.size(); i++) {
+                                       ViewerFilter curr = (ViewerFilter) fFilters.get(i);
+                                       elements = curr.filter(fViewer, input, elements);
+                               }
+                       }
+               }
+               return elements.length == 0;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/ElementListSelectionDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/ElementListSelectionDialog.java
new file mode 100644 (file)
index 0000000..e8588c5
--- /dev/null
@@ -0,0 +1,67 @@
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A class to select elements out of a list of elements.
+ */
+public class ElementListSelectionDialog extends
+               AbstractElementListSelectionDialog {
+
+       private Object[] fElements;
+
+       /**
+        * Creates a list selection dialog.
+        * 
+        * @param parent
+        *            the parent widget.
+        * @param renderer
+        *            the label renderer.
+        */
+       public ElementListSelectionDialog(Shell parent, ILabelProvider renderer) {
+               super(parent, renderer);
+       }
+
+       /**
+        * Sets the elements of the list.
+        * 
+        * @param elements
+        *            the elements of the list.
+        */
+       public void setElements(Object[] elements) {
+               fElements = elements;
+       }
+
+       /*
+        * @see SelectionStatusDialog#computeResult()
+        */
+       protected void computeResult() {
+               setResult(Arrays.asList(getSelectedElements()));
+       }
+
+       /*
+        * @see Dialog#createDialogArea(Composite)
+        */
+       protected Control createDialogArea(Composite parent) {
+               Composite contents = (Composite) super.createDialogArea(parent);
+
+               createMessageArea(contents);
+               createFilterText(contents);
+               createFilteredList(contents);
+
+               setListElements(fElements);
+
+               List initialSelections = getInitialElementSelections();
+               if (initialSelections != null)
+                       setSelection(initialSelections.toArray());
+
+               return contents;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/ISelectionValidator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/ISelectionValidator.java
new file mode 100644 (file)
index 0000000..dacdc87
--- /dev/null
@@ -0,0 +1,9 @@
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+import org.eclipse.core.runtime.IStatus;
+
+public interface ISelectionValidator {
+
+       IStatus validate(Object[] selection);
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/MessageLine.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/MessageLine.java
new file mode 100644 (file)
index 0000000..dc9ac8d
--- /dev/null
@@ -0,0 +1,87 @@
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A message line displaying a status.
+ */
+public class MessageLine extends CLabel {
+
+       private static final RGB ERROR_BACKGROUND_RGB = new RGB(230, 226, 221);
+
+       private Color fNormalMsgAreaBackground;
+
+       private Color fErrorMsgAreaBackground;
+
+       /**
+        * Creates a new message line as a child of the given parent.
+        */
+       public MessageLine(Composite parent) {
+               this(parent, SWT.LEFT);
+       }
+
+       /**
+        * Creates a new message line as a child of the parent and with the given
+        * SWT stylebits.
+        */
+       public MessageLine(Composite parent, int style) {
+               super(parent, style);
+               fNormalMsgAreaBackground = getBackground();
+               fErrorMsgAreaBackground = null;
+       }
+
+       private Image findImage(IStatus status) {
+               if (status.isOK()) {
+                       return null;
+               } else if (status.matches(IStatus.ERROR)) {
+                       return PHPUiImages.get(PHPUiImages.IMG_OBJS_ERROR);
+               } else if (status.matches(IStatus.WARNING)) {
+                       return PHPUiImages.get(PHPUiImages.IMG_OBJS_WARNING);
+               } else if (status.matches(IStatus.INFO)) {
+                       return PHPUiImages.get(PHPUiImages.IMG_OBJS_INFO);
+               }
+               return null;
+       }
+
+       /**
+        * Sets the message and image to the given status. <code>null</code> is a
+        * valid argument and will set the empty text and no image
+        */
+       public void setErrorStatus(IStatus status) {
+               if (status != null) {
+                       String message = status.getMessage();
+                       if (message != null && message.length() > 0) {
+                               setText(message);
+                               setImage(findImage(status));
+                               if (fErrorMsgAreaBackground == null) {
+                                       fErrorMsgAreaBackground = new Color(getDisplay(),
+                                                       ERROR_BACKGROUND_RGB);
+                               }
+                               setBackground(fErrorMsgAreaBackground);
+                               return;
+                       }
+               }
+               setText("");
+               setImage(null);
+               setBackground(fNormalMsgAreaBackground);
+       }
+
+       /*
+        * @see Widget#dispose()
+        */
+       public void dispose() {
+               if (fErrorMsgAreaBackground != null) {
+                       fErrorMsgAreaBackground.dispose();
+                       fErrorMsgAreaBackground = null;
+               }
+               super.dispose();
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/SelectionStatusDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/SelectionStatusDialog.java
new file mode 100644 (file)
index 0000000..eb6514f
--- /dev/null
@@ -0,0 +1,154 @@
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+import java.util.Arrays;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+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.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+/**
+ * An abstract base class for dialogs with a status bar and ok/cancel buttons.
+ * The status message must be passed over as StatusInfo object and can be an
+ * error, warning or ok. The OK button is enabled or disabled depending on the
+ * status.
+ */
+public abstract class SelectionStatusDialog extends SelectionDialog {
+
+       private MessageLine fStatusLine;
+
+       private IStatus fLastStatus;
+
+       private Image fImage;
+
+       private boolean fStatusLineAboveButtons = false;
+
+       /**
+        * Creates an instance of a <code>SelectionStatusDialog</code>.
+        */
+       public SelectionStatusDialog(Shell parent) {
+               super(parent);
+       }
+
+       /**
+        * Controls whether status line appears to the left of the buttons (default)
+        * or above them.
+        * 
+        * @param aboveButtons
+        *            if <code>true</code> status line is placed above buttons; if
+        *            <code>false</code> to the right
+        */
+       public void setStatusLineAboveButtons(boolean aboveButtons) {
+               fStatusLineAboveButtons = aboveButtons;
+       }
+
+       /**
+        * Sets the image for this dialog.
+        * 
+        * @param image
+        *            the image.
+        */
+       public void setImage(Image image) {
+               fImage = image;
+       }
+
+       /**
+        * Returns the first element from the list of results. Returns
+        * <code>null</code> if no element has been selected.
+        * 
+        * @return the first result element if one exists. Otherwise
+        *         <code>null</code> is returned.
+        */
+       public Object getFirstResult() {
+               Object[] result = getResult();
+               if (result == null || result.length == 0)
+                       return null;
+               return result[0];
+       }
+
+       /**
+        * Sets a result element at the given position.
+        */
+       protected void setResult(int position, Object element) {
+               Object[] result = getResult();
+               result[position] = element;
+               setResult(Arrays.asList(result));
+       }
+
+       /**
+        * Compute the result and return it.
+        */
+       protected abstract void computeResult();
+
+       protected void configureShell(Shell shell) {
+               super.configureShell(shell);
+               if (fImage != null)
+                       shell.setImage(fImage);
+       }
+
+       /**
+        * Update the dialog's status line to reflect the given status. It is safe
+        * to call this method before the dialog has been opened.
+        */
+       protected void updateStatus(IStatus status) {
+               fLastStatus = status;
+               if (fStatusLine != null && !fStatusLine.isDisposed()) {
+                       updateButtonsEnableState(status);
+                       fStatusLine.setErrorStatus(status);
+               }
+       }
+
+       /**
+        * Update the status of the ok button to reflect the given status.
+        * Subclasses may override this method to update additional buttons.
+        */
+       protected void updateButtonsEnableState(IStatus status) {
+               Button okButton = getOkButton();
+               if (okButton != null && !okButton.isDisposed())
+                       okButton.setEnabled(!status.matches(IStatus.ERROR));
+       }
+
+       protected void okPressed() {
+               computeResult();
+               super.okPressed();
+       }
+
+       public void create() {
+               super.create();
+               if (fLastStatus != null)
+                       updateStatus(fLastStatus);
+       }
+
+       protected Control createButtonBar(Composite parent) {
+               Composite composite = new Composite(parent, SWT.NULL);
+               GridLayout layout = new GridLayout();
+               if (fStatusLineAboveButtons) {
+                       layout.marginWidth = 5;
+               } else {
+                       layout.numColumns = 2;
+               }
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               composite.setLayout(layout);
+               composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               fStatusLine = new MessageLine(composite);
+               fStatusLine.setAlignment(SWT.LEFT);
+               fStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               fStatusLine.setErrorStatus(null);
+
+               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalIndent = convertWidthInCharsToPixels(1);
+               fStatusLine.setLayoutData(gd);
+
+               super.createButtonBar(composite);
+               return composite;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusDialog.java
new file mode 100644 (file)
index 0000000..b58b7fb
--- /dev/null
@@ -0,0 +1,168 @@
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+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.Shell;
+
+/**
+ * An abstract base class for dialogs with a status bar and ok/cancel buttons.
+ * The status message must be passed over as StatusInfo object and can be an
+ * error, warning or ok. The OK button is enabled or disabled depending on the
+ * status.
+ */
+public abstract class StatusDialog extends Dialog {
+
+       private Button fOkButton;
+
+       private MessageLine fStatusLine;
+
+       private IStatus fLastStatus;
+
+       private String fTitle;
+
+       private Image fImage;
+
+       private boolean fStatusLineAboveButtons;
+
+       /**
+        * Creates an instane of a status dialog.
+        */
+       public StatusDialog(Shell parent) {
+               super(parent);
+               fStatusLineAboveButtons = false;
+       }
+
+       /**
+        * Specifies whether status line appears to the left of the buttons
+        * (default) or above them.
+        * 
+        * @param aboveButtons
+        *            if <code>true</code> status line is placed above buttons; if
+        *            <code>false</code> to the right
+        */
+       public void setStatusLineAboveButtons(boolean aboveButtons) {
+               fStatusLineAboveButtons = aboveButtons;
+       }
+
+       /**
+        * Update the dialog's status line to reflect the given status. It is save
+        * to call this method before the dialog has been opened.
+        */
+       protected void updateStatus(IStatus status) {
+               fLastStatus = status;
+               if (fStatusLine != null && !fStatusLine.isDisposed()) {
+                       updateButtonsEnableState(status);
+                       fStatusLine.setErrorStatus(status);
+               }
+       }
+
+       /**
+        * Returns the last status.
+        */
+       public IStatus getStatus() {
+               return fLastStatus;
+       }
+
+       /**
+        * Updates the status of the ok button to reflect the given status.
+        * Subclasses may override this method to update additional buttons.
+        * 
+        * @param status
+        *            the status.
+        */
+       protected void updateButtonsEnableState(IStatus status) {
+               if (fOkButton != null && !fOkButton.isDisposed())
+                       fOkButton.setEnabled(!status.matches(IStatus.ERROR));
+       }
+
+       /*
+        * @see Window#create(Shell)
+        */
+       protected void configureShell(Shell shell) {
+               super.configureShell(shell);
+               if (fTitle != null)
+                       shell.setText(fTitle);
+       }
+
+       /*
+        * @see Window#create()
+        */
+       public void create() {
+               super.create();
+               if (fLastStatus != null) {
+                       // policy: dialogs are not allowed to come up with an error message
+                       if (fLastStatus.matches(IStatus.ERROR)) {
+                               StatusInfo status = new StatusInfo();
+                               status.setError(""); //$NON-NLS-1$
+                               fLastStatus = status;
+                       }
+                       updateStatus(fLastStatus);
+               }
+       }
+
+       /*
+        * @see Dialog#createButtonsForButtonBar(Composite)
+        */
+       protected void createButtonsForButtonBar(Composite parent) {
+               fOkButton = createButton(parent, IDialogConstants.OK_ID,
+                               IDialogConstants.OK_LABEL, true);
+               createButton(parent, IDialogConstants.CANCEL_ID,
+                               IDialogConstants.CANCEL_LABEL, false);
+       }
+
+       /*
+        * @see Dialog#createButtonBar(Composite)
+        */
+       protected Control createButtonBar(Composite parent) {
+               Composite composite = new Composite(parent, SWT.NULL);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               layout.marginHeight = 0;
+               layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+               composite.setLayout(layout);
+               composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               fStatusLine = new MessageLine(composite);
+               fStatusLine.setAlignment(SWT.LEFT);
+               fStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               fStatusLine.setErrorStatus(null); //$NON-NLS-1$
+
+               super.createButtonBar(composite);
+               return composite;
+       }
+
+       /**
+        * Sets the title for this dialog.
+        * 
+        * @param title
+        *            the title.
+        */
+       public void setTitle(String title) {
+               fTitle = title != null ? title : ""; //$NON-NLS-1$
+               Shell shell = getShell();
+               if ((shell != null) && !shell.isDisposed())
+                       shell.setText(fTitle);
+       }
+
+       /**
+        * Sets the image for this dialog.
+        * 
+        * @param image
+        *            the image.
+        */
+       public void setImage(Image image) {
+               fImage = image;
+               Shell shell = getShell();
+               if ((shell != null) && !shell.isDisposed())
+                       shell.setImage(fImage);
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusInfo.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusInfo.java
new file mode 100644 (file)
index 0000000..0c5ee8f
--- /dev/null
@@ -0,0 +1,176 @@
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * A settable IStatus. Can be an error, warning, info or ok. For error, info and
+ * warning states, a message describes the problem.
+ */
+public class StatusInfo implements IStatus {
+
+       private String fStatusMessage;
+
+       private int fSeverity;
+
+       /**
+        * Creates a status set to OK (no message)
+        */
+       public StatusInfo() {
+               this(OK, null);
+       }
+
+       /**
+        * Creates a status .
+        * 
+        * @param severity
+        *            The status severity: ERROR, WARNING, INFO and OK.
+        * @param message
+        *            The message of the status. Applies only for ERROR, WARNING and
+        *            INFO.
+        */
+       public StatusInfo(int severity, String message) {
+               fStatusMessage = message;
+               fSeverity = severity;
+       }
+
+       /**
+        * Returns if the status' severity is OK.
+        */
+       public boolean isOK() {
+               return fSeverity == IStatus.OK;
+       }
+
+       /**
+        * Returns if the status' severity is WARNING.
+        */
+       public boolean isWarning() {
+               return fSeverity == IStatus.WARNING;
+       }
+
+       /**
+        * Returns if the status' severity is INFO.
+        */
+       public boolean isInfo() {
+               return fSeverity == IStatus.INFO;
+       }
+
+       /**
+        * Returns if the status' severity is ERROR.
+        */
+       public boolean isError() {
+               return fSeverity == IStatus.ERROR;
+       }
+
+       /**
+        * @see IStatus#getMessage
+        */
+       public String getMessage() {
+               return fStatusMessage;
+       }
+
+       /**
+        * Sets the status to ERROR.
+        * 
+        * @param The
+        *            error message (can be empty, but not null)
+        */
+       public void setError(String errorMessage) {
+               Assert.isNotNull(errorMessage);
+               fStatusMessage = errorMessage;
+               fSeverity = IStatus.ERROR;
+       }
+
+       /**
+        * Sets the status to WARNING.
+        * 
+        * @param The
+        *            warning message (can be empty, but not null)
+        */
+       public void setWarning(String warningMessage) {
+               Assert.isNotNull(warningMessage);
+               fStatusMessage = warningMessage;
+               fSeverity = IStatus.WARNING;
+       }
+
+       /**
+        * Sets the status to INFO.
+        * 
+        * @param The
+        *            info message (can be empty, but not null)
+        */
+       public void setInfo(String infoMessage) {
+               Assert.isNotNull(infoMessage);
+               fStatusMessage = infoMessage;
+               fSeverity = IStatus.INFO;
+       }
+
+       /**
+        * Sets the status to OK.
+        */
+       public void setOK() {
+               fStatusMessage = null;
+               fSeverity = IStatus.OK;
+       }
+
+       /*
+        * @see IStatus#matches(int)
+        */
+       public boolean matches(int severityMask) {
+               return (fSeverity & severityMask) != 0;
+       }
+
+       /**
+        * Returns always <code>false</code>.
+        * 
+        * @see IStatus#isMultiStatus()
+        */
+       public boolean isMultiStatus() {
+               return false;
+       }
+
+       /*
+        * @see IStatus#getSeverity()
+        */
+       public int getSeverity() {
+               return fSeverity;
+       }
+
+       /*
+        * @see IStatus#getPlugin()
+        */
+       public String getPlugin() {
+               return WebUI.PLUGIN_ID;
+       }
+
+       /**
+        * Returns always <code>null</code>.
+        * 
+        * @see IStatus#getException()
+        */
+       public Throwable getException() {
+               return null;
+       }
+
+       /**
+        * Returns always the error severity.
+        * 
+        * @see IStatus#getCode()
+        */
+       public int getCode() {
+               return fSeverity;
+       }
+
+       /**
+        * Returns always <code>null</code>.
+        * 
+        * @see IStatus#getChildren()
+        */
+       public IStatus[] getChildren() {
+               return new IStatus[0];
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusUtil.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dialogs/StatusUtil.java
new file mode 100644 (file)
index 0000000..f87adf0
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.dialogs;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.DialogPage;
+
+/**
+ * A utility class to work with IStatus.
+ */
+public class StatusUtil {
+
+       /**
+        * Compares two instances of <code>IStatus</code>. The more severe is
+        * returned: An error is more severe than a warning, and a warning is more
+        * severe than ok. If the two stati have the same severity, the second is
+        * returned.
+        */
+       public static IStatus getMoreSevere(IStatus s1, IStatus s2) {
+               if (s1.getSeverity() > s2.getSeverity()) {
+                       return s1;
+               } else {
+                       return s2;
+               }
+       }
+
+       /**
+        * Finds the most severe status from a array of stati. An error is more
+        * severe than a warning, and a warning is more severe than ok.
+        */
+       public static IStatus getMostSevere(IStatus[] status) {
+               IStatus max = null;
+               for (int i = 0; i < status.length; i++) {
+                       IStatus curr = status[i];
+                       if (curr.matches(IStatus.ERROR)) {
+                               return curr;
+                       }
+                       if (max == null || curr.getSeverity() > max.getSeverity()) {
+                               max = curr;
+                       }
+               }
+               return max;
+       }
+
+       /**
+        * Applies the status to the status line of a dialog page.
+        */
+       public static void applyToStatusLine(DialogPage page, IStatus status) {
+               String message = status.getMessage();
+               switch (status.getSeverity()) {
+               case IStatus.OK:
+                       page.setMessage(message, DialogPage.NONE);
+                       page.setErrorMessage(null);
+                       break;
+               case IStatus.WARNING:
+                       page.setMessage(message, DialogPage.WARNING);
+                       page.setErrorMessage(null);
+                       break;
+               case IStatus.INFO:
+                       page.setMessage(message, DialogPage.INFORMATION);
+                       page.setErrorMessage(null);
+                       break;
+               default:
+                       if (message.length() == 0) {
+                               message = null;
+                       }
+                       page.setMessage(null);
+                       page.setErrorMessage(message);
+                       break;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/BasicSelectionTransferDragAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/BasicSelectionTransferDragAdapter.java
new file mode 100644 (file)
index 0000000..866f69a
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.Transfer;
+
+public class BasicSelectionTransferDragAdapter extends DragSourceAdapter
+               implements TransferDragSourceListener {
+
+       private ISelectionProvider fProvider;
+
+       public BasicSelectionTransferDragAdapter(ISelectionProvider provider) {
+               Assert.isNotNull(provider);
+               fProvider = provider;
+       }
+
+       /**
+        * @see TransferDragSourceListener#getTransfer
+        */
+       public Transfer getTransfer() {
+               return LocalSelectionTransfer.getInstance();
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see org.eclipse.swt.dnd.DragSourceListener#dragStart
+        */
+       public void dragStart(DragSourceEvent event) {
+               ISelection selection = fProvider.getSelection();
+               LocalSelectionTransfer.getInstance().setSelection(selection);
+               LocalSelectionTransfer.getInstance().setSelectionSetTime(event.time);
+               event.doit = isDragable(selection);
+       }
+
+       /**
+        * Checks if the elements contained in the given selection can be dragged.
+        * <p>
+        * Subclasses may override.
+        * 
+        * @param selection
+        *            containing the elements to be dragged
+        */
+       protected boolean isDragable(ISelection selection) {
+               return true;
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see org.eclipse.swt.dnd.DragSourceListener#dragSetData
+        */
+       public void dragSetData(DragSourceEvent event) {
+               // For consistency set the data to the selection even though
+               // the selection is provided by the LocalSelectionTransfer
+               // to the drop target adapter.
+               event.data = LocalSelectionTransfer.getInstance().getSelection();
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see org.eclipse.swt.dnd.DragSourceListener#dragFinished
+        */
+       public void dragFinished(DragSourceEvent event) {
+               // We assume that the drop target listener has done all
+               // the work.
+               Assert.isTrue(event.detail == DND.DROP_NONE);
+               LocalSelectionTransfer.getInstance().setSelection(null);
+               LocalSelectionTransfer.getInstance().setSelectionSetTime(0);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDragAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDragAdapter.java
new file mode 100644 (file)
index 0000000..df9c40a
--- /dev/null
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.TransferData;
+
+/**
+ * A delegating drag adapter negotiates between a set of
+ * <code>TransferDragSourceListener</code>s On <code>dragStart</code> the
+ * adapter determines the listener to be used for any further <code>drag*</code>
+ * callback.
+ */
+public class DelegatingDragAdapter implements DragSourceListener {
+
+       private TransferDragSourceListener[] fPossibleListeners;
+
+       private List fActiveListeners;
+
+       private TransferDragSourceListener fFinishListener;
+
+       public DelegatingDragAdapter(TransferDragSourceListener[] listeners) {
+               setPossibleListeners(listeners);
+       }
+
+       protected void setPossibleListeners(TransferDragSourceListener[] listeners) {
+               Assert.isNotNull(listeners);
+               Assert
+                               .isTrue(fActiveListeners == null,
+                                               "Can only set possible listeners before drag operation has started"); //$NON-NLS-1$
+               fPossibleListeners = listeners;
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DragSourceListener
+        */
+       public void dragStart(DragSourceEvent event) {
+               fFinishListener = null;
+               boolean saveDoit = event.doit;
+               Object saveData = event.data;
+               boolean doIt = false;
+               List transfers = new ArrayList(fPossibleListeners.length);
+               fActiveListeners = new ArrayList(fPossibleListeners.length);
+
+               for (int i = 0; i < fPossibleListeners.length; i++) {
+                       TransferDragSourceListener listener = fPossibleListeners[i];
+                       event.doit = saveDoit;
+                       listener.dragStart(event);
+                       if (event.doit) {
+                               transfers.add(listener.getTransfer());
+                               fActiveListeners.add(listener);
+                       }
+                       doIt = doIt || event.doit;
+               }
+               if (doIt) {
+                       ((DragSource) event.widget).setTransfer((Transfer[]) transfers
+                                       .toArray(new Transfer[transfers.size()]));
+               }
+               event.data = saveData;
+               event.doit = doIt;
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DragSourceListener
+        */
+       public void dragSetData(DragSourceEvent event) {
+               fFinishListener = getListener(event.dataType);
+               if (fFinishListener != null)
+                       fFinishListener.dragSetData(event);
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DragSourceListener
+        */
+       public void dragFinished(DragSourceEvent event) {
+               try {
+                       if (fFinishListener != null) {
+                               fFinishListener.dragFinished(event);
+                       } else {
+                               // If the user presses Escape then we get a dragFinished without
+                               // getting a dragSetData before.
+                               fFinishListener = getListener(event.dataType);
+                               if (fFinishListener != null)
+                                       fFinishListener.dragFinished(event);
+                       }
+               } finally {
+                       fFinishListener = null;
+                       fActiveListeners = null;
+               }
+       }
+
+       private TransferDragSourceListener getListener(TransferData type) {
+               if (type == null)
+                       return null;
+
+               for (Iterator iter = fActiveListeners.iterator(); iter.hasNext();) {
+                       TransferDragSourceListener listener = (TransferDragSourceListener) iter
+                                       .next();
+                       if (listener.getTransfer().isSupportedType(type)) {
+                               return listener;
+                       }
+               }
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDropAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/DelegatingDropAdapter.java
new file mode 100644 (file)
index 0000000..4424f34
--- /dev/null
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.dnd.TransferData;
+
+/**
+ * A delegating drop adapter negotiates between a set of
+ * <code>TransferDropTargetListener</code>s On <code>dragEnter</code> the
+ * adapter determines the listener to be used for any further <code>drag*</code>
+ * callback.
+ */
+public class DelegatingDropAdapter implements DropTargetListener {
+
+       private TransferDropTargetListener[] fListeners;
+
+       private TransferDropTargetListener fChosenListener;
+
+       /**
+        * Creates a new delegating drop adapter.
+        * 
+        * @param listeners
+        *            an array of potential listeners
+        */
+       public DelegatingDropAdapter(TransferDropTargetListener[] listeners) {
+               fListeners = listeners;
+               Assert.isNotNull(listeners);
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DropTargetListener
+        */
+       public void dragEnter(DropTargetEvent event) {
+               fChosenListener = null;
+               event.currentDataType = selectPreferredListener(event.dataTypes);
+               if (fChosenListener != null)
+                       fChosenListener.dragEnter(event);
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DropTargetListener
+        */
+       public void dragLeave(DropTargetEvent event) {
+               if (fChosenListener != null)
+                       fChosenListener.dragLeave(event);
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DropTargetListener
+        */
+       public void dragOperationChanged(DropTargetEvent event) {
+               if (fChosenListener != null)
+                       fChosenListener.dragOperationChanged(event);
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DropTargetListener
+        */
+       public void dragOver(DropTargetEvent event) {
+               if (fChosenListener != null)
+                       fChosenListener.dragOver(event);
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DropTargetListener
+        */
+       public void drop(DropTargetEvent event) {
+               if (fChosenListener != null)
+                       fChosenListener.drop(event);
+               fChosenListener = null;
+       }
+
+       /*
+        * non Java-doc
+        * 
+        * @see DropTargetListener
+        */
+       public void dropAccept(DropTargetEvent event) {
+               if (fChosenListener != null)
+                       fChosenListener.dropAccept(event);
+       }
+
+       private TransferData selectPreferredListener(TransferData[] dataTypes) {
+               for (int i = 0; i < fListeners.length; i++) {
+                       TransferData data = computeTransferData(dataTypes, fListeners[i]);
+                       if (data != null)
+                               return data;
+               }
+               return null;
+       }
+
+       private TransferData computeTransferData(TransferData[] dataTypes,
+                       TransferDropTargetListener listener) {
+               for (int i = 0; i < dataTypes.length; i++) {
+                       if (listener.getTransfer().isSupportedType(dataTypes[i])) {
+                               fChosenListener = listener;
+                               return dataTypes[i];
+                       }
+               }
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDragAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDragAdapter.java
new file mode 100644 (file)
index 0000000..63351c2
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.dnd.DragSourceEvent;
+
+public class JdtViewerDragAdapter extends DelegatingDragAdapter {
+
+       private StructuredViewer fViewer;
+
+       public JdtViewerDragAdapter(StructuredViewer viewer,
+                       TransferDragSourceListener[] listeners) {
+               super(listeners);
+               Assert.isNotNull(viewer);
+               fViewer = viewer;
+       }
+
+       public void dragStart(DragSourceEvent event) {
+               IStructuredSelection selection = (IStructuredSelection) fViewer
+                               .getSelection();
+               if (selection.isEmpty()) {
+                       event.doit = false;
+                       return;
+               }
+               super.dragStart(event);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java
new file mode 100644 (file)
index 0000000..7e2143b
--- /dev/null
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * A drag and drop adapter to be used together with structured viewers. The
+ * adapater delegates the <code>dragEnter</code>, <code>dragOperationChanged
+ * </code>,
+ * <code>dragOver</code> and <code>dropAccept</code> method to the
+ * <code>validateDrop</code> method. Furthermore it adds location feedback.
+ */
+public class JdtViewerDropAdapter implements DropTargetListener {
+
+       /**
+        * Constant describing the position of the mouse cursor relative to the
+        * target object. This means the mouse is positioned slightly before the
+        * target.
+        */
+       protected static final int LOCATION_BEFORE = 1;
+
+       /**
+        * Constant describing the position of the mouse cursor relative to the
+        * target object. This means the mouse is positioned slightly after the
+        * target.
+        */
+       protected static final int LOCATION_AFTER = 2;
+
+       /**
+        * Constant describing the position of the mouse cursor relative to the
+        * target object. This means the mouse is positioned directly on the target.
+        */
+       protected static final int LOCATION_ON = 3;
+
+       /**
+        * Constant describing the position of the mouse cursor relative to the
+        * target object. This means the mouse is not positioned over or near any
+        * valid target.
+        */
+       protected static final int LOCATION_NONE = 4;
+
+       /**
+        * The threshold used to determine if the mouse is before or after an item.
+        */
+       private static final int LOCATION_EPSILON = 5;
+
+       /**
+        * Style to enable location feedback.
+        */
+       public static final int INSERTION_FEEDBACK = 1 << 1;
+
+       private StructuredViewer fViewer;
+
+       private int fFeedback;
+
+       private boolean fShowInsertionFeedback;
+
+       private int fRequestedOperation;
+
+       private int fLastOperation;
+
+       protected int fLocation;
+
+       protected Object fTarget;
+
+       public JdtViewerDropAdapter(StructuredViewer viewer, int feedback) {
+               fViewer = viewer;
+               Assert.isNotNull(fViewer);
+               fFeedback = feedback;
+               fLastOperation = -1;
+       }
+
+       /**
+        * Controls whether the drop adapter shows insertion feedback or not.
+        * 
+        * @param showInsertionFeedback
+        *            <code>true</code> if the drop adapter is supposed to show
+        *            insertion feedback. Otherwise <code>false</code>
+        */
+       public void showInsertionFeedback(boolean showInsertionFeedback) {
+               fShowInsertionFeedback = showInsertionFeedback;
+       }
+
+       /**
+        * Returns the viewer this adapter is working on.
+        */
+       protected StructuredViewer getViewer() {
+               return fViewer;
+       }
+
+       // ---- Hooks to override
+       // -----------------------------------------------------
+
+       /**
+        * The actual drop has occurred. Calls
+        * <code>drop(Object target, DropTargetEvent event)
+        * </code>.
+        * 
+        * @see DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
+        */
+       public void drop(DropTargetEvent event) {
+               drop(fTarget, event);
+       }
+
+       /**
+        * The actual drop has occurred.
+        * 
+        * @param target
+        *            the drop target in form of a domain element.
+        * @param event
+        *            the drop traget event
+        */
+       public void drop(Object target, DropTargetEvent event) {
+       }
+
+       /**
+        * Checks if the drop is valid. The method calls <code>validateDrop
+        * (Object target, DropTargetEvent event). Implementors can alter the 
+        * <code>currentDataType</code> field and the <code>detail</code> field 
+        * to give feedback about drop acceptence.
+        */
+       public void validateDrop(DropTargetEvent event) {
+               validateDrop(fTarget, event, fRequestedOperation);
+       }
+
+       /**
+        * Checks if the drop on the current target is valid. The method can alter
+        * the <code>currentDataType</code> field and the <code>
+        * detail</code>
+        * field to give feedback about drop acceptence.
+        * 
+        * @param target
+        *            the drop target in form of a domain element.
+        * @param event
+        *            the drop traget event
+        * @param operation
+        *            the operation requested by the user.
+        */
+       public void validateDrop(Object target, DropTargetEvent event, int operation) {
+       }
+
+       public void dragEnter(DropTargetEvent event) {
+               dragOperationChanged(event);
+       }
+
+       public void dragLeave(DropTargetEvent event) {
+               fTarget = null;
+               fLocation = LOCATION_NONE;
+       }
+
+       public void dragOperationChanged(DropTargetEvent event) {
+               fRequestedOperation = event.detail;
+               fTarget = computeTarget(event);
+               fLocation = computeLocation(event);
+               validateDrop(event);
+               fLastOperation = event.detail;
+               computeFeedback(event);
+       }
+
+       public void dragOver(DropTargetEvent event) {
+               Object oldTarget = fTarget;
+               fTarget = computeTarget(event);
+
+               // set the location feedback
+               int oldLocation = fLocation;
+               fLocation = computeLocation(event);
+               if (oldLocation != fLocation || oldTarget != fTarget
+                               || fLastOperation != event.detail) {
+                       validateDrop(event);
+                       fLastOperation = event.detail;
+               } else {
+                       event.detail = fLastOperation;
+               }
+               computeFeedback(event);
+       }
+
+       public void dropAccept(DropTargetEvent event) {
+               fTarget = computeTarget(event);
+               validateDrop(event);
+               fLastOperation = event.detail;
+       }
+
+       /**
+        * Returns the data held by <code>event.item</code>. Inside a viewer this
+        * corresponds to the items data model element.
+        */
+       protected Object computeTarget(DropTargetEvent event) {
+               return event.item == null ? null : event.item.getData();
+       }
+
+       /**
+        * Returns the position of the given coordinates relative to the given
+        * target. The position is determined to be before, after, or on the item,
+        * based on some threshold value. The return value is one of the LOCATION_*
+        * constants defined in this class.
+        */
+       final protected int computeLocation(DropTargetEvent event) {
+               if (!(event.item instanceof Item))
+                       return LOCATION_NONE;
+
+               Item item = (Item) event.item;
+               Point coordinates = fViewer.getControl().toControl(
+                               new Point(event.x, event.y));
+               Rectangle bounds = getBounds(item);
+               if (bounds == null) {
+                       return LOCATION_NONE;
+               }
+               if ((coordinates.y - bounds.y) < LOCATION_EPSILON) {
+                       return LOCATION_BEFORE;
+               }
+               if ((bounds.y + bounds.height - coordinates.y) < LOCATION_EPSILON) {
+                       return LOCATION_AFTER;
+               }
+               return LOCATION_ON;
+       }
+
+       /**
+        * Returns the bounds of the given item, or <code>null</code> if it is not
+        * a valid type of item.
+        */
+       private Rectangle getBounds(Item item) {
+               if (item instanceof TreeItem)
+                       return ((TreeItem) item).getBounds();
+
+               if (item instanceof TableItem)
+                       return ((TableItem) item).getBounds(0);
+
+               return null;
+       }
+
+       /**
+        * Sets the drag under feedback corresponding to the value of
+        * <code>fLocation</code> and the <code>INSERTION_FEEDBACK</code> style
+        * bit.
+        */
+       protected void computeFeedback(DropTargetEvent event) {
+               if (!fShowInsertionFeedback && fLocation != LOCATION_NONE) {
+                       event.feedback = DND.FEEDBACK_SELECT;
+               } else {
+                       if (fLocation == LOCATION_BEFORE) {
+                               event.feedback = DND.FEEDBACK_INSERT_BEFORE;
+                       } else if (fLocation == LOCATION_AFTER) {
+                               event.feedback = DND.FEEDBACK_INSERT_AFTER;
+                       }
+               }
+               event.feedback |= fFeedback;
+       }
+
+       /**
+        * Sets the drop operation to </code>DROP_NODE<code>.
+        */
+       protected void clearDropOperation(DropTargetEvent event) {
+               event.detail = DND.DROP_NONE;
+       }
+
+       /**
+        * Returns the requested drop operation.
+        */
+       protected int getRequestedOperation() {
+               return fRequestedOperation;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/LocalSelectionTransfer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/LocalSelectionTransfer.java
new file mode 100644 (file)
index 0000000..49ea330
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.dnd.ByteArrayTransfer;
+import org.eclipse.swt.dnd.TransferData;
+
+public class LocalSelectionTransfer extends ByteArrayTransfer {
+
+       // First attempt to create a UUID for the type name to make sure that
+       // different Eclipse applications use different "types" of
+       // <code>LocalSelectionTransfer</code>
+       private static final String TYPE_NAME = "local-selection-transfer-format" + (new Long(System.currentTimeMillis())).toString(); //$NON-NLS-1$;
+
+       private static final int TYPEID = registerType(TYPE_NAME);
+
+       private static final LocalSelectionTransfer INSTANCE = new LocalSelectionTransfer();
+
+       private ISelection fSelection;
+
+       private int fSelectionSetTime;
+
+       private LocalSelectionTransfer() {
+       }
+
+       /**
+        * Returns the singleton.
+        */
+       public static LocalSelectionTransfer getInstance() {
+               return INSTANCE;
+       }
+
+       /**
+        * Sets the transfer data for local use.
+        */
+       public void setSelection(ISelection s) {
+               fSelection = s;
+       }
+
+       /**
+        * Returns the local transfer data.
+        */
+       public ISelection getSelection() {
+               return fSelection;
+       }
+
+       public void javaToNative(Object object, TransferData transferData) {
+               // No encoding needed since this is a hardcoded string read and written
+               // in the same process.
+               // See nativeToJava below
+               byte[] check = TYPE_NAME.getBytes();
+               super.javaToNative(check, transferData);
+       }
+
+       public Object nativeToJava(TransferData transferData) {
+               Object result = super.nativeToJava(transferData);
+               if (isInvalidNativeType(result)) {
+                       WebUI.log(IStatus.ERROR, PHPUIMessages
+                                       .getString("LocalSelectionTransfer.errorMessage")); //$NON-NLS-1$
+               }
+               return fSelection;
+       }
+
+       private boolean isInvalidNativeType(Object result) {
+               // No encoding needed since this is a hardcoded string read and written
+               // in the same process.
+               // See javaToNative above
+               return !(result instanceof byte[])
+                               || !TYPE_NAME.equals(new String((byte[]) result));
+       }
+
+       /**
+        * The type id used to identify this transfer.
+        */
+       protected int[] getTypeIds() {
+               return new int[] { TYPEID };
+       }
+
+       protected String[] getTypeNames() {
+               return new String[] { TYPE_NAME };
+       }
+
+       public int getSelectionSetTime() {
+               return fSelectionSetTime;
+       }
+
+       public void setSelectionSetTime(int time) {
+               fSelectionSetTime = time;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/ResourceTransferDragAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/ResourceTransferDragAdapter.java
new file mode 100644 (file)
index 0000000..8157ce9
--- /dev/null
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.IJavaStatusConstants;
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * A drag adapter that transfers the current selection as </code> IResource</code>.
+ * Only those elements in the selection are part of the transfer which can be
+ * converted into an <code>IResource </code>.
+ */
+public class ResourceTransferDragAdapter extends DragSourceAdapter implements
+               TransferDragSourceListener {
+
+       private ISelectionProvider fProvider;
+
+       private static final List EMPTY_LIST = new ArrayList(0);
+
+       /**
+        * Creates a new ResourceTransferDragAdapter for the given selection
+        * provider.
+        * 
+        * @param provider
+        *            the selection provider to access the viewer's selection
+        */
+       public ResourceTransferDragAdapter(ISelectionProvider provider) {
+               fProvider = provider;
+               Assert.isNotNull(fProvider);
+       }
+
+       public Transfer getTransfer() {
+               return ResourceTransfer.getInstance();
+       }
+
+       public void dragStart(DragSourceEvent event) {
+               event.doit = convertSelection().size() > 0;
+       }
+
+       public void dragSetData(DragSourceEvent event) {
+               List resources = convertSelection();
+               event.data = (IResource[]) resources.toArray(new IResource[resources
+                               .size()]);
+       }
+
+       public void dragFinished(DragSourceEvent event) {
+               if (!event.doit)
+                       return;
+
+               if (event.detail == DND.DROP_MOVE) {
+                       handleFinishedDropMove(event);
+               }
+       }
+
+       private List convertSelection() {
+               ISelection s = fProvider.getSelection();
+               if (!(s instanceof IStructuredSelection))
+                       return EMPTY_LIST;
+               IStructuredSelection selection = (IStructuredSelection) s;
+               List result = new ArrayList(selection.size());
+               for (Iterator iter = selection.iterator(); iter.hasNext();) {
+                       Object element = iter.next();
+                       if (element instanceof IAdaptable) {
+                               IAdaptable adaptable = (IAdaptable) element;
+                               IResource resource = (IResource) adaptable
+                                               .getAdapter(IResource.class);
+                               if (resource != null)
+                                       result.add(resource);
+                       }
+               }
+               return result;
+       }
+
+       private void handleFinishedDropMove(DragSourceEvent event) {
+               MultiStatus status = new MultiStatus(
+                               WebUI.getPluginId(),
+                               IJavaStatusConstants.INTERNAL_ERROR,
+                               PHPUIMessages
+                                               .getString("ResourceTransferDragAdapter.cannot_delete_resource"), //$NON-NLS-1$
+                               null);
+               List resources = convertSelection();
+               for (Iterator iter = resources.iterator(); iter.hasNext();) {
+                       IResource resource = (IResource) iter.next();
+                       try {
+                               resource.delete(true, null);
+                       } catch (CoreException e) {
+                               status.add(e.getStatus());
+                       }
+               }
+               if (status.getChildren().length > 0) {
+                       Shell parent = SWTUtil.getShell(event.widget);
+                       ErrorDialog error = new ErrorDialog(
+                                       parent,
+                                       PHPUIMessages
+                                                       .getString("ResourceTransferDragAdapter.moving_resource"), //$NON-NLS-1$
+                                       PHPUIMessages
+                                                       .getString("ResourceTransferDragAdapter.cannot_delete_files"), //$NON-NLS-1$
+                                       status, IStatus.ERROR);
+                       error.open();
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDragSourceListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDragSourceListener.java
new file mode 100644 (file)
index 0000000..dbe83c8
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.swt.dnd.Transfer;
+
+/**
+ * A special drag source listener which is typed with a
+ * <code>TransferData</code>.
+ */
+public interface TransferDragSourceListener extends DragSourceListener {
+
+       /**
+        * Returns the transfer used by this drag source.
+        */
+       public Transfer getTransfer();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDropTargetListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/dnd/TransferDropTargetListener.java
new file mode 100644 (file)
index 0000000..abea4ab
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.dnd;
+
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.dnd.Transfer;
+
+/**
+ * A special drop target listener which is typed with a
+ * <code>TransferData</code>.
+ */
+public interface TransferDropTargetListener extends DropTargetListener {
+
+       /**
+        * Returns the transfer used by this drop target.
+        */
+       public Transfer getTransfer();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ClassFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ClassFilter.java
new file mode 100644 (file)
index 0000000..850db3b
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters classes
+ */
+public class ClassFilter extends ViewerFilter {
+
+       /*
+        * @see ViewerFilter
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof IType) {
+                       try {
+                               return ((IType) element).isInterface();
+                       } catch (JavaModelException ex) {
+                               return true;
+                       }
+               }
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ClosedProjectFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ClosedProjectFilter.java
new file mode 100644 (file)
index 0000000..2ac29b1
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters closed projects
+ */
+public class ClosedProjectFilter extends ViewerFilter {
+
+       /*
+        * @see ViewerFilter
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof IJavaElement)
+                       return ((IJavaElement) element).getJavaProject().getProject()
+                                       .isOpen();
+               if (element instanceof IResource)
+                       return ((IResource) element).getProject().isOpen();
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/CustomFiltersDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/CustomFiltersDialog.java
new file mode 100644 (file)
index 0000000..8060d76
--- /dev/null
@@ -0,0 +1,442 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+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.Image;
+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;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+public class CustomFiltersDialog extends SelectionDialog {
+
+       private static final String SEPARATOR = ","; //$NON-NLS-1$
+
+       private String fViewId;
+
+       private boolean fEnablePatterns;
+
+       private String[] fPatterns;
+
+       private String[] fEnabledFilterIds;
+
+       private FilterDescriptor[] fBuiltInFilters;
+
+       private CheckboxTableViewer fCheckBoxList;
+
+       private Button fEnableUserDefinedPatterns;
+
+       private Text fUserDefinedPatterns;
+
+       private Stack fFilterDescriptorChangeHistory;
+
+       /**
+        * Creates a dialog to customize Java element filters.
+        * 
+        * @param shell
+        *            the parent shell
+        * @param viewId
+        *            the id of the view
+        * @param enablePatterns
+        *            <code>true</code> if pattern filters are enabled
+        * @param patterns
+        *            the filter patterns
+        * @param enabledFilterIds
+        *            the Ids of the enabled filters
+        */
+       public CustomFiltersDialog(Shell shell, String viewId,
+                       boolean enablePatterns, String[] patterns, String[] enabledFilterIds) {
+
+               super(shell);
+               Assert.isNotNull(viewId);
+               Assert.isNotNull(patterns);
+               Assert.isNotNull(enabledFilterIds);
+
+               fViewId = viewId;
+               fPatterns = patterns;
+               fEnablePatterns = enablePatterns;
+               fEnabledFilterIds = enabledFilterIds;
+
+               fBuiltInFilters = FilterDescriptor.getFilterDescriptors(fViewId);
+               fFilterDescriptorChangeHistory = new Stack();
+               setShellStyle(getShellStyle() | SWT.RESIZE);
+       }
+
+       protected void configureShell(Shell shell) {
+               setTitle(FilterMessages.getString("CustomFiltersDialog.title")); //$NON-NLS-1$
+               setMessage(FilterMessages
+                               .getString("CustomFiltersDialog.filterList.label")); //$NON-NLS-1$
+               super.configureShell(shell);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(shell,
+                               IJavaHelpContextIds.CUSTOM_FILTERS_DIALOG);
+       }
+
+       /**
+        * Overrides method in Dialog
+        * 
+        * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
+        */
+       protected Control createDialogArea(Composite parent) {
+               initializeDialogUnits(parent);
+               // create a composite with standard margins and spacing
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+               layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+               layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+               layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+               composite.setLayout(layout);
+               composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+               composite.setFont(parent.getFont());
+               Composite group = composite;
+
+               // Checkbox
+               fEnableUserDefinedPatterns = new Button(group, SWT.CHECK);
+               fEnableUserDefinedPatterns.setFocus();
+               fEnableUserDefinedPatterns.setText(FilterMessages
+                               .getString("CustomFiltersDialog.enableUserDefinedPattern")); //$NON-NLS-1$
+
+               // Pattern field
+               fUserDefinedPatterns = new Text(group, SWT.SINGLE | SWT.BORDER);
+               GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.GRAB_HORIZONTAL);
+               data.widthHint = convertWidthInCharsToPixels(59);
+               fUserDefinedPatterns.setLayoutData(data);
+               String patterns = convertToString(fPatterns, SEPARATOR);
+               fUserDefinedPatterns.setText(patterns);
+
+               // Info text
+               final Label info = new Label(group, SWT.LEFT);
+               info.setText(FilterMessages
+                               .getString("CustomFiltersDialog.patternInfo")); //$NON-NLS-1$
+
+               // Enabling / disabling of pattern group
+               fEnableUserDefinedPatterns.setSelection(fEnablePatterns);
+               fUserDefinedPatterns.setEnabled(fEnablePatterns);
+               info.setEnabled(fEnablePatterns);
+               fEnableUserDefinedPatterns.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               boolean state = fEnableUserDefinedPatterns.getSelection();
+                               fUserDefinedPatterns.setEnabled(state);
+                               info.setEnabled(fEnableUserDefinedPatterns.getSelection());
+                               if (state)
+                                       fUserDefinedPatterns.setFocus();
+                       }
+               });
+
+               // Filters provided by extension point
+               if (fBuiltInFilters.length > 0)
+                       createCheckBoxList(group);
+
+               applyDialogFont(parent);
+               return parent;
+       }
+
+       private void createCheckBoxList(Composite parent) {
+               // Filler
+               new Label(parent, SWT.NONE);
+
+               Label info = new Label(parent, SWT.LEFT);
+               info.setText(FilterMessages
+                               .getString("CustomFiltersDialog.filterList.label")); //$NON-NLS-1$
+
+               fCheckBoxList = CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
+               GridData data = new GridData(GridData.FILL_BOTH);
+               data.heightHint = fCheckBoxList.getTable().getItemHeight() * 10;
+               fCheckBoxList.getTable().setLayoutData(data);
+
+               fCheckBoxList.setLabelProvider(createLabelPrivder());
+               fCheckBoxList.setContentProvider(new ArrayContentProvider());
+
+               fCheckBoxList.setInput(fBuiltInFilters);
+               setInitialSelections(getEnabledFilterDescriptors());
+
+               List initialSelection = getInitialElementSelections();
+               if (initialSelection != null && !initialSelection.isEmpty())
+                       checkInitialSelections();
+
+               // Description
+               info = new Label(parent, SWT.LEFT);
+               info.setText(FilterMessages
+                               .getString("CustomFiltersDialog.description.label")); //$NON-NLS-1$
+               final Text description = new Text(parent, SWT.LEFT | SWT.WRAP
+                               | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL);
+               data = new GridData(GridData.FILL_HORIZONTAL);
+               data.heightHint = convertHeightInCharsToPixels(3);
+               description.setLayoutData(data);
+               fCheckBoxList
+                               .addSelectionChangedListener(new ISelectionChangedListener() {
+                                       public void selectionChanged(SelectionChangedEvent event) {
+                                               ISelection selection = event.getSelection();
+                                               if (selection instanceof IStructuredSelection) {
+                                                       Object selectedElement = ((IStructuredSelection) selection)
+                                                                       .getFirstElement();
+                                                       if (selectedElement instanceof FilterDescriptor)
+                                                               description
+                                                                               .setText(((FilterDescriptor) selectedElement)
+                                                                                               .getDescription());
+                                               }
+                                       }
+                               });
+               fCheckBoxList.addCheckStateListener(new ICheckStateListener() {
+                       /*
+                        * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
+                        */
+                       public void checkStateChanged(CheckStateChangedEvent event) {
+                               Object element = event.getElement();
+                               if (element instanceof FilterDescriptor) {
+                                       // renew if already touched
+                                       if (fFilterDescriptorChangeHistory.contains(element))
+                                               fFilterDescriptorChangeHistory.remove(element);
+                                       fFilterDescriptorChangeHistory.push(element);
+                               }
+                       }
+               });
+
+               addSelectionButtons(parent);
+       }
+
+       private void addSelectionButtons(Composite composite) {
+               Composite buttonComposite = new Composite(composite, SWT.RIGHT);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               buttonComposite.setLayout(layout);
+               GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END
+                               | GridData.GRAB_HORIZONTAL);
+               data.grabExcessHorizontalSpace = true;
+               composite.setData(data);
+
+               // Select All button
+               String label = FilterMessages
+                               .getString("CustomFiltersDialog.SelectAllButton.label"); //$NON-NLS-1$
+               Button selectButton = createButton(buttonComposite,
+                               IDialogConstants.SELECT_ALL_ID, label, false);
+               SWTUtil.setButtonDimensionHint(selectButton);
+               SelectionListener listener = new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               fCheckBoxList.setAllChecked(true);
+                               fFilterDescriptorChangeHistory.clear();
+                               for (int i = 0; i < fBuiltInFilters.length; i++)
+                                       fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]);
+                       }
+               };
+               selectButton.addSelectionListener(listener);
+
+               // De-select All button
+               label = FilterMessages
+                               .getString("CustomFiltersDialog.DeselectAllButton.label"); //$NON-NLS-1$
+               Button deselectButton = createButton(buttonComposite,
+                               IDialogConstants.DESELECT_ALL_ID, label, false);
+               SWTUtil.setButtonDimensionHint(deselectButton);
+               listener = new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               fCheckBoxList.setAllChecked(false);
+                               fFilterDescriptorChangeHistory.clear();
+                               for (int i = 0; i < fBuiltInFilters.length; i++)
+                                       fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]);
+                       }
+               };
+               deselectButton.addSelectionListener(listener);
+       }
+
+       private void checkInitialSelections() {
+               Iterator itemsToCheck = getInitialElementSelections().iterator();
+               while (itemsToCheck.hasNext())
+                       fCheckBoxList.setChecked(itemsToCheck.next(), true);
+       }
+
+       protected void okPressed() {
+               if (fBuiltInFilters != null) {
+                       ArrayList result = new ArrayList();
+                       for (int i = 0; i < fBuiltInFilters.length; ++i) {
+                               if (fCheckBoxList.getChecked(fBuiltInFilters[i]))
+                                       result.add(fBuiltInFilters[i]);
+                       }
+                       setResult(result);
+               }
+               super.okPressed();
+       }
+
+       private ILabelProvider createLabelPrivder() {
+               return new LabelProvider() {
+                       public Image getImage(Object element) {
+                               return null;
+                       }
+
+                       public String getText(Object element) {
+                               if (element instanceof FilterDescriptor)
+                                       return ((FilterDescriptor) element).getName();
+                               else
+                                       return null;
+                       }
+               };
+       }
+
+       // ---------- result handling ----------
+
+       protected void setResult(List newResult) {
+               super.setResult(newResult);
+               if (fUserDefinedPatterns.getText().length() > 0) {
+                       fEnablePatterns = fEnableUserDefinedPatterns.getSelection();
+                       fPatterns = convertFromString(fUserDefinedPatterns.getText(),
+                                       SEPARATOR);
+               } else {
+                       fEnablePatterns = false;
+                       fPatterns = new String[0];
+               }
+       }
+
+       /**
+        * @return the patterns which have been entered by the user
+        */
+       public String[] getUserDefinedPatterns() {
+               return fPatterns;
+       }
+
+       /**
+        * @return the Ids of the enabled built-in filters
+        */
+       public String[] getEnabledFilterIds() {
+               Object[] result = getResult();
+               Set enabledIds = new HashSet(result.length);
+               for (int i = 0; i < result.length; i++)
+                       enabledIds.add(((FilterDescriptor) result[i]).getId());
+               return (String[]) enabledIds.toArray(new String[enabledIds.size()]);
+       }
+
+       /**
+        * @return <code>true</code> if the user-defined patterns are disabled
+        */
+       public boolean areUserDefinedPatternsEnabled() {
+               return fEnablePatterns;
+       }
+
+       /**
+        * @return a stack with the filter descriptor check history
+        * @since 3.0
+        */
+       public Stack getFilterDescriptorChangeHistory() {
+               return fFilterDescriptorChangeHistory;
+       }
+
+       private FilterDescriptor[] getEnabledFilterDescriptors() {
+               FilterDescriptor[] filterDescs = fBuiltInFilters;
+               List result = new ArrayList(filterDescs.length);
+               List enabledFilterIds = Arrays.asList(fEnabledFilterIds);
+               for (int i = 0; i < filterDescs.length; i++) {
+                       String id = filterDescs[i].getId();
+                       if (enabledFilterIds.contains(id))
+                               result.add(filterDescs[i]);
+               }
+               return (FilterDescriptor[]) result.toArray(new FilterDescriptor[result
+                               .size()]);
+       }
+
+       public static String[] convertFromString(String patterns, String separator) {
+               StringTokenizer tokenizer = new StringTokenizer(patterns, separator,
+                               true);
+               int tokenCount = tokenizer.countTokens();
+               List result = new ArrayList(tokenCount);
+               boolean escape = false;
+               boolean append = false;
+               while (tokenizer.hasMoreTokens()) {
+                       String token = tokenizer.nextToken().trim();
+                       if (separator.equals(token)) {
+                               if (!escape)
+                                       escape = true;
+                               else {
+                                       addPattern(result, separator);
+                                       append = true;
+                               }
+                       } else {
+                               if (!append)
+                                       result.add(token);
+                               else
+                                       addPattern(result, token);
+                               append = false;
+                               escape = false;
+                       }
+               }
+               return (String[]) result.toArray(new String[result.size()]);
+       }
+
+       private static void addPattern(List list, String pattern) {
+               if (list.isEmpty())
+                       list.add(pattern);
+               else {
+                       int index = list.size() - 1;
+                       list.set(index, ((String) list.get(index)) + pattern);
+               }
+       }
+
+       public static String convertToString(String[] patterns, String separator) {
+               int length = patterns.length;
+               StringBuffer strBuf = new StringBuffer();
+               if (length > 0)
+                       strBuf.append(escapeSeparator(patterns[0], separator));
+               else
+                       return ""; //$NON-NLS-1$
+               int i = 1;
+               while (i < length) {
+                       strBuf.append(separator);
+                       strBuf.append(" "); //$NON-NLS-1$
+                       strBuf.append(escapeSeparator(patterns[i++], separator));
+               }
+               return strBuf.toString();
+       }
+
+       private static String escapeSeparator(String pattern, String separator) {
+               int length = pattern.length();
+               StringBuffer buf = new StringBuffer(length);
+               for (int i = 0; i < length; i++) {
+                       char ch = pattern.charAt(i); //$NON-NLS-1$
+                       if (separator.equals(String.valueOf(ch)))
+                               buf.append(ch);
+                       buf.append(ch);
+               }
+               return buf.toString();
+
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FieldsFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FieldsFilter.java
new file mode 100644 (file)
index 0000000..ad3fd39
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilter;
+
+/**
+ * Fields filter.
+ * 
+ * @since 3.0
+ */
+public class FieldsFilter extends MemberFilter {
+       public FieldsFilter() {
+               addFilter(MemberFilter.FILTER_FIELDS);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterDescriptor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterDescriptor.java
new file mode 100644 (file)
index 0000000..9c722b6
--- /dev/null
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.ui.IPluginContribution;
+import org.eclipse.ui.activities.WorkbenchActivityHelper;
+
+/**
+ * Represents a custom filter which is provided by the
+ * "net.sourceforge.phpdt.ui.javaElementFilters" extension point.
+ * 
+ * since 2.0
+ */
+public class FilterDescriptor implements Comparable, IPluginContribution {
+
+       private static String PATTERN_FILTER_ID_PREFIX = "_patternFilterId_"; //$NON-NLS-1$
+
+       private static final String EXTENSION_POINT_NAME = "phpElementFilters"; //$NON-NLS-1$
+
+       private static final String FILTER_TAG = "filter"; //$NON-NLS-1$
+
+       private static final String PATTERN_ATTRIBUTE = "pattern"; //$NON-NLS-1$        
+
+       private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
+
+       /**
+        * @deprecated as of 3.0 use {@link FilterDescriptor#TARGET_ID_ATTRIBUTE}
+        */
+       private static final String VIEW_ID_ATTRIBUTE = "viewId"; //$NON-NLS-1$
+
+       private static final String TARGET_ID_ATTRIBUTE = "targetId"; //$NON-NLS-1$
+
+       private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
+
+       private static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$
+
+       private static final String ENABLED_ATTRIBUTE = "enabled"; //$NON-NLS-1$
+
+       private static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$        
+
+       /**
+        * @deprecated use "enabled" instead
+        */
+       private static final String SELECTED_ATTRIBUTE = "selected"; //$NON-NLS-1$
+
+       private static FilterDescriptor[] fgFilterDescriptors;
+
+       private IConfigurationElement fElement;
+
+       /**
+        * Returns all contributed Java element filters.
+        */
+       public static FilterDescriptor[] getFilterDescriptors() {
+               if (fgFilterDescriptors == null) {
+                       IExtensionRegistry registry = Platform.getExtensionRegistry();
+                       IConfigurationElement[] elements = registry
+                                       .getConfigurationElementsFor(WebUI.PLUGIN_ID,
+                                                       EXTENSION_POINT_NAME);
+                       fgFilterDescriptors = createFilterDescriptors(elements);
+               }
+               return fgFilterDescriptors;
+       }
+
+       /**
+        * Returns all Java element filters which are contributed to the given view.
+        */
+       public static FilterDescriptor[] getFilterDescriptors(String targetId) {
+               FilterDescriptor[] filterDescs = FilterDescriptor
+                               .getFilterDescriptors();
+               List result = new ArrayList(filterDescs.length);
+               for (int i = 0; i < filterDescs.length; i++) {
+                       String tid = filterDescs[i].getTargetId();
+                       if (WorkbenchActivityHelper.filterItem(filterDescs[i]))
+                               continue;
+                       if (tid == null || tid.equals(targetId))
+                               result.add(filterDescs[i]);
+               }
+               return (FilterDescriptor[]) result.toArray(new FilterDescriptor[result
+                               .size()]);
+       }
+
+       /**
+        * Creates a new filter descriptor for the given configuration element.
+        */
+       private FilterDescriptor(IConfigurationElement element) {
+               fElement = element;
+               // it is either a pattern filter or a custom filter
+               Assert
+                               .isTrue(
+                                               isPatternFilter() ^ isCustomFilter(),
+                                               "An extension for extension-point net.sourceforge.phpdt.ui.javaElementFilters does not specify a correct filter"); //$NON-NLS-1$
+               Assert
+                               .isNotNull(
+                                               getId(),
+                                               "An extension for extension-point net.sourceforge.phpdt.ui.javaElementFilters does not provide a valid ID"); //$NON-NLS-1$
+               Assert
+                               .isNotNull(
+                                               getName(),
+                                               "An extension for extension-point net.sourceforge.phpdt.ui.javaElementFilters does not provide a valid name"); //$NON-NLS-1$
+       }
+
+       /**
+        * Creates a new <code>ViewerFilter</code>. This method is only valid for
+        * viewer filters.
+        */
+       public ViewerFilter createViewerFilter() {
+               if (!isCustomFilter())
+                       return null;
+
+               final ViewerFilter[] result = new ViewerFilter[1];
+               String message = FilterMessages.getFormattedString(
+                               "FilterDescriptor.filterCreationError.message", getId()); //$NON-NLS-1$
+               ISafeRunnable code = new SafeRunnable(message) {
+                       /*
+                        * @see org.eclipse.core.runtime.ISafeRunnable#run()
+                        */
+                       public void run() throws Exception {
+                               result[0] = (ViewerFilter) fElement
+                                               .createExecutableExtension(CLASS_ATTRIBUTE);
+                       }
+
+               };
+               Platform.run(code);
+               return result[0];
+       }
+
+       // ---- XML Attribute accessors
+       // ---------------------------------------------
+
+       /**
+        * Returns the filter's id.
+        * <p>
+        * This attribute is mandatory for custom filters. The ID for pattern
+        * filters is PATTERN_FILTER_ID_PREFIX plus the pattern itself.
+        * </p>
+        */
+       public String getId() {
+               if (isPatternFilter()) {
+                       String targetId = getTargetId();
+                       if (targetId == null)
+                               return PATTERN_FILTER_ID_PREFIX + getPattern();
+                       else
+                               return targetId + PATTERN_FILTER_ID_PREFIX + getPattern();
+               } else
+                       return fElement.getAttribute(ID_ATTRIBUTE);
+       }
+
+       /**
+        * Returns the filter's name.
+        * <p>
+        * If the name of a pattern filter is missing then the pattern is used as
+        * its name.
+        * </p>
+        */
+       public String getName() {
+               String name = fElement.getAttribute(NAME_ATTRIBUTE);
+               if (name == null && isPatternFilter())
+                       name = getPattern();
+               return name;
+       }
+
+       /**
+        * Returns the filter's pattern.
+        * 
+        * @return the pattern string or <code>null</code> if it's not a pattern
+        *         filter
+        */
+       public String getPattern() {
+               return fElement.getAttribute(PATTERN_ATTRIBUTE);
+       }
+
+       /**
+        * Returns the filter's viewId.
+        * 
+        * @return the view ID or <code>null</code> if the filter is for all views
+        * @since 3.0
+        */
+       public String getTargetId() {
+               String tid = fElement.getAttribute(TARGET_ID_ATTRIBUTE);
+
+               if (tid != null)
+                       return tid;
+
+               // Backwards compatibility code
+               return fElement.getAttribute(VIEW_ID_ATTRIBUTE);
+
+       }
+
+       /**
+        * Returns the filter's description.
+        * 
+        * @return the description or <code>null</code> if no description is
+        *         provided
+        */
+       public String getDescription() {
+               String description = fElement.getAttribute(DESCRIPTION_ATTRIBUTE);
+               if (description == null)
+                       description = ""; //$NON-NLS-1$
+               return description;
+       }
+
+       /**
+        * @return <code>true</code> if this filter is a custom filter.
+        */
+       public boolean isPatternFilter() {
+               return getPattern() != null;
+       }
+
+       /**
+        * @return <code>true</code> if this filter is a pattern filter.
+        */
+       public boolean isCustomFilter() {
+               return fElement.getAttribute(CLASS_ATTRIBUTE) != null;
+       }
+
+       /**
+        * Returns <code>true</code> if the filter is initially enabled.
+        * 
+        * This attribute is optional and defaults to <code>true</code>.
+        */
+       public boolean isEnabled() {
+               String strVal = fElement.getAttribute(ENABLED_ATTRIBUTE);
+               if (strVal == null)
+                       // backward compatibility
+                       strVal = fElement.getAttribute(SELECTED_ATTRIBUTE);
+               return strVal == null || Boolean.valueOf(strVal).booleanValue();
+       }
+
+       /*
+        * Implements a method from IComparable
+        */
+       public int compareTo(Object o) {
+               if (o instanceof FilterDescriptor)
+                       return Collator.getInstance().compare(getName(),
+                                       ((FilterDescriptor) o).getName());
+               else
+                       return Integer.MIN_VALUE;
+       }
+
+       // ---- initialization ---------------------------------------------------
+
+       /**
+        * Creates the filter descriptors.
+        */
+       private static FilterDescriptor[] createFilterDescriptors(
+                       IConfigurationElement[] elements) {
+               List result = new ArrayList(5);
+               Set descIds = new HashSet(5);
+               for (int i = 0; i < elements.length; i++) {
+                       final IConfigurationElement element = elements[i];
+                       if (FILTER_TAG.equals(element.getName())) {
+
+                               final FilterDescriptor[] desc = new FilterDescriptor[1];
+                               Platform
+                                               .run(new SafeRunnable(
+                                                               FilterMessages
+                                                                               .getString("FilterDescriptor.filterDescriptionCreationError.message")) { //$NON-NLS-1$
+                                                       public void run() throws Exception {
+                                                               desc[0] = new FilterDescriptor(element);
+                                                       }
+                                               });
+
+                               if (desc[0] != null && !descIds.contains(desc[0].getId())) {
+                                       result.add(desc[0]);
+                                       descIds.add(desc[0].getId());
+                               }
+                       }
+               }
+               Collections.sort(result);
+               return (FilterDescriptor[]) result.toArray(new FilterDescriptor[result
+                               .size()]);
+       }
+
+       public String getLocalId() {
+               return fElement.getAttribute(ID_ATTRIBUTE);
+       }
+
+       public String getPluginId() {
+               return fElement.getDeclaringExtension().getNamespace();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.java
new file mode 100644 (file)
index 0000000..7ed3444
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class FilterMessages {
+
+       private static final String RESOURCE_BUNDLE = FilterMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private FilterMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               String format = null;
+               try {
+                       format = fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+               return MessageFormat.format(format, args);
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               String format = null;
+               try {
+                       format = fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+               if (arg == null)
+                       arg = ""; //$NON-NLS-1$
+               return MessageFormat.format(format, new Object[] { arg });
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.properties
new file mode 100644 (file)
index 0000000..5904766
--- /dev/null
@@ -0,0 +1,24 @@
+###############################################################################
+# Copyright (c) 2000, 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+CustomFiltersDialog.title= Java Element Filters
+CustomFiltersDialog.patternInfo= The patterns are separated by comma, where\n* = any string, ? = any character, ,, = ,
+CustomFiltersDialog.enableUserDefinedPattern= &Name filter patterns (matching names will be hidden):
+CustomFiltersDialog.filterList.label= S&elect the elements to exclude from the view:
+CustomFiltersDialog.description.label= Filter description:
+CustomFiltersDialog.SelectAllButton.label= &Select All
+CustomFiltersDialog.DeselectAllButton.label= &Deselect All
+
+OpenCustomFiltersDialogAction.text= &Filters...
+
+FilterDescriptor.filterDescriptionCreationError.message= One of the extensions for extension-point net.sourceforge.phpdt.ui.javaElementFilters is incorrect.
+FilterDescriptor.filterCreationError.title= Filter Creation Error
+FilterDescriptor.filterCreationError.message= The net.sourceforge.phpdt.ui.javaElementFilters plug-in extension "{0}" specifies a viewer filter class which does not exist.
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ImportDeclarationFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/ImportDeclarationFilter.java
new file mode 100644 (file)
index 0000000..c317b54
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IImportContainer;
+import net.sourceforge.phpdt.core.IImportDeclaration;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters import declarations
+ */
+public class ImportDeclarationFilter extends ViewerFilter {
+
+       /*
+        * @see ViewerFilter
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               return !((element instanceof IImportContainer) || (element instanceof IImportDeclaration));
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/InterfaceFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/InterfaceFilter.java
new file mode 100644 (file)
index 0000000..cfe35e1
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters interfaces
+ */
+public class InterfaceFilter extends ViewerFilter {
+
+       /*
+        * @see ViewerFilter
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof IType) {
+                       try {
+                               return !((IType) element).isInterface();
+                       } catch (JavaModelException ex) {
+                               return true;
+                       }
+               }
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/JavaFileFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/JavaFileFilter.java
new file mode 100644 (file)
index 0000000..d406dc8
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters out all compilation units and class files elements.
+ */
+public class JavaFileFilter extends ViewerFilter {
+
+       /**
+        * Returns the result of this filter, when applied to the given inputs.
+        * 
+        * @param inputs
+        *            the set of elements to
+        * @return Returns true if element should be included in filtered set
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof ICompilationUnit)
+                       return false;
+               // if (element instanceof IClassFile)
+               // return false;
+
+               // if (element instanceof IPackageFragment)
+               // try {
+               // return ((IPackageFragment)element).getNonJavaResources().length > 0;
+               // } catch (JavaModelException ex) {
+               // return true;
+               // }
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NamePatternFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NamePatternFilter.java
new file mode 100644 (file)
index 0000000..f1dc30a
--- /dev/null
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.internal.ui.util.StringMatcher;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * The NamePatternFilter selects the elements which match the given string
+ * patterns.
+ * <p>
+ * The following characters have special meaning: ? => any character * => any
+ * string
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class NamePatternFilter extends ViewerFilter {
+       private String[] fPatterns;
+
+       private StringMatcher[] fMatchers;
+
+       /**
+        * Return the currently configured StringMatchers.
+        */
+       private StringMatcher[] getMatchers() {
+               return fMatchers;
+       }
+
+       /**
+        * Gets the patterns for the receiver.
+        */
+       public String[] getPatterns() {
+               return fPatterns;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ViewerFilter.
+        */
+       public boolean select(Viewer viewer, Object parentElement, Object element) {
+               String matchName = null;
+               if (element instanceof IJavaElement) {
+                       matchName = ((IJavaElement) element).getElementName();
+               } else if (element instanceof IAdaptable) {
+                       IAdaptable adaptable = (IAdaptable) element;
+                       IJavaElement javaElement = (IJavaElement) adaptable
+                                       .getAdapter(IJavaElement.class);
+                       if (javaElement != null)
+                               matchName = javaElement.getElementName();
+                       else {
+                               IResource resource = (IResource) adaptable
+                                               .getAdapter(IResource.class);
+                               if (resource != null)
+                                       matchName = resource.getName();
+                       }
+               }
+               if (matchName != null) {
+                       StringMatcher[] testMatchers = getMatchers();
+                       for (int i = 0; i < testMatchers.length; i++) {
+                               if (testMatchers[i].match(matchName))
+                                       return false;
+                       }
+                       return true;
+               }
+               return true;
+       }
+
+       /**
+        * Sets the patterns to filter out for the receiver.
+        * <p>
+        * The following characters have special meaning: ? => any character * =>
+        * any string
+        * </p>
+        */
+       public void setPatterns(String[] newPatterns) {
+               fPatterns = newPatterns;
+               fMatchers = new StringMatcher[newPatterns.length];
+               for (int i = 0; i < newPatterns.length; i++) {
+                       // Reset the matchers to prevent constructor overhead
+                       fMatchers[i] = new StringMatcher(newPatterns[i], true, false);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaElementFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaElementFilter.java
new file mode 100644 (file)
index 0000000..90c9fdf
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters out all non-Java elements.
+ */
+public class NonJavaElementFilter extends ViewerFilter {
+
+       /**
+        * Returns the result of this filter, when applied to the given inputs.
+        * 
+        * @param inputs
+        *            the set of elements to
+        * @return Returns true if element should be included in filtered set
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof IJavaElement)
+                       return true;
+
+               if (element instanceof IResource) {
+                       IProject project = ((IResource) element).getProject();
+                       return project == null || !project.isOpen();
+               }
+
+               // Exclude all IStorage elements which are neither Java elements nor
+               // resources
+               if (element instanceof IStorage)
+                       return false;
+
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaProjectsFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaProjectsFilter.java
new file mode 100644 (file)
index 0000000..2d3c49a
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters non-java projects
+ */
+public class NonJavaProjectsFilter extends ViewerFilter {
+
+       /*
+        * @see ViewerFilter
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof IJavaProject)
+                       return true;
+               else if (element instanceof IProject)
+                       return !((IProject) element).isOpen();
+
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicFilter.java
new file mode 100644 (file)
index 0000000..ad9a2d3
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilter;
+
+/**
+ * Non-public member filter.
+ * 
+ * @since 3.0
+ */
+public class NonPublicFilter extends MemberFilter {
+       public NonPublicFilter() {
+               addFilter(MemberFilter.FILTER_NONPUBLIC);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicTypeFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicTypeFilter.java
new file mode 100644 (file)
index 0000000..28706d9
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters non-public types
+ */
+public class NonPublicTypeFilter extends ViewerFilter {
+
+       /*
+        * @see ViewerFilter
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof IType) {
+                       IType type = (IType) element;
+                       try {
+                               return Flags.isPublic(type.getFlags());
+                       } catch (JavaModelException ex) {
+                               return true;
+                       }
+               }
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonSharedProjectFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/NonSharedProjectFilter.java
new file mode 100644 (file)
index 0000000..f9a78e3
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.team.core.RepositoryProvider;
+
+/**
+ * Filters non-shared projects and Java projects. Non-shared projects are
+ * projects that are not controlled by a team provider.
+ * 
+ * @since 2.1
+ */
+public class NonSharedProjectFilter extends ViewerFilter {
+
+       /*
+        * @see ViewerFilter
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof IProject)
+                       return isSharedProject((IProject) element);
+
+               if (element instanceof IJavaProject)
+                       return isSharedProject(((IJavaProject) element).getProject());
+
+               return true;
+       }
+
+       private boolean isSharedProject(IProject project) {
+               return !project.isAccessible() || RepositoryProvider.isShared(project);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/OutputFolderFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/OutputFolderFilter.java
new file mode 100644 (file)
index 0000000..4ac7a79
--- /dev/null
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.core.IClasspathEntry;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filters out all output folders.
+ * <p>
+ * Note: Folder which are direct children of a Java element are already filtered
+ * by the Java Model.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class OutputFolderFilter extends ViewerFilter {
+
+       /**
+        * Returns the result of this filter, when applied to the given element.
+        * 
+        * @param element
+        *            the element to test
+        * @return <code>true</code> if element should be included
+        * @since 3.0
+        */
+       public boolean select(Viewer viewer, Object parent, Object element) {
+               if (element instanceof IFolder) {
+                       IFolder folder = (IFolder) element;
+                       IProject proj = folder.getProject();
+                       try {
+                               if (!proj.hasNature(WebUI.PHP_NATURE_ID))
+                                       return true;
+
+                               IJavaProject jProject = JavaCore.create(folder.getProject());
+                               if (jProject == null || !jProject.exists())
+                                       return true;
+
+                               // Check default output location
+                               IPath defaultOutputLocation = jProject.getOutputLocation();
+                               IPath folderPath = folder.getFullPath();
+                               if (defaultOutputLocation != null
+                                               && defaultOutputLocation.equals(folderPath))
+                                       return false;
+
+                               // Check output location for each class path entry
+                               IClasspathEntry[] cpEntries = jProject.getRawClasspath();
+                               for (int i = 0, length = cpEntries.length; i < length; i++) {
+                                       IPath outputLocation = cpEntries[i].getOutputLocation();
+                                       if (outputLocation != null
+                                                       && outputLocation.equals(folderPath))
+                                               return false;
+                               }
+                       } catch (CoreException ex) {
+                               return true;
+                       }
+               }
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/StaticsFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/filters/StaticsFilter.java
new file mode 100644 (file)
index 0000000..6179f48
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilter;
+
+/**
+ * Statics filter.
+ * 
+ * @since 3.0
+ */
+public class StaticsFilter extends MemberFilter {
+       public StaticsFilter() {
+               addFilter(MemberFilter.FILTER_STATIC);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.java
new file mode 100644 (file)
index 0000000..b6a785b
--- /dev/null
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.phpdocexport;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class JavadocExportMessages {
+
+       private static final String RESOURCE_BUNDLE = JavadocExportMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private JavadocExportMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.properties
new file mode 100644 (file)
index 0000000..58866ea
--- /dev/null
@@ -0,0 +1,104 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+JavadocSpecificsWizardPage.description=Configure Javadoc arguments.
+
+
+JavadocSpecificsWizardPage.stylesheetbrowsedialog.title=Style sheet Selection
+JavadocSpecificsWizardPage.overviewbutton.label=&Overview:
+JavadocSpecificsWizardPage.overviewbrowse.label=Bro&wse...
+JavadocSpecificsWizardPage.extraoptionsfield.label=E&xtra Javadoc options (path names with white spaces must be enclosed in quotes):
+JavadocSpecificsWizardPage.overviewbrowsedialog.title=Select overview page
+JavadocSpecificsWizardPage.antscriptbutton.label=&Save the settings of this Javadoc export as an Ant script:
+JavadocSpecificsWizardPage.antscripttext.label=&Ant Script: 
+JavadocSpecificsWizardPage.antscriptbrowse.label=Brows&e...
+JavadocSpecificsWizardPage.openbrowserbutton.label=O&pen generated index file in browser
+JavadocSpecificsWizardPage.antscriptbrowsedialog.title=Destination Selection
+JavadocSpecificsWizardPage.antscriptbrowsedialog.label=&Select destination folder for ant script:
+
+JavadocSpecificsWizardPage.jdk14mode.label=JRE 1.4 source compatibility
+
+JavadocSpecificsWizardPage.overviewnotfound.error=Overview path not found.
+JavadocSpecificsWizardPage.overviewincorrect.error=Overview must be an html document.
+JavadocSpecificsWizardPage.antfileincorrect.error=Not a valid Ant file name.
+JavadocSpecificsWizardPage.antfileoverwrite.warning=The generated ant file will overwrite the existing ant file.
+JavadocTreeWizardPage.javadoctreewizardpage.description=Select types for Javadoc generation.
+JavadocTreeWizardPage.checkboxtreeandlistgroup.label=Select &types for which Javadoc will be generated:
+JavadocTreeWizardPage.visibilitygroup.label=Create Javadoc for members with visibility: 
+JavadocTreeWizardPage.privatebutton.label=Pr&ivate
+JavadocTreeWizardPage.packagebutton.label=P&ackage
+JavadocTreeWizardPage.protectedbutton.label=Pr&otected
+JavadocTreeWizardPage.publicbutton.label=P&ublic
+JavadocTreeWizardPage.standarddocletbutton.label=Use &Standard Doclet
+JavadocTreeWizardPage.destinationfield.label=&Destination: 
+JavadocTreeWizardPage.destinationbrowse.label=Bro&wse...
+JavadocTreeWizardPage.customdocletbutton.label=Use &Custom Doclet
+JavadocTreeWizardPage.docletnamefield.label=Doc&let name: 
+JavadocTreeWizardPage.docletpathfield.label=Doclet class &path: 
+JavadocTreeWizardPage.destinationbrowsedialog.title=Destination Selection
+JavadocTreeWizardPage.destinationbrowsedialog.label=&Select the Javadoc destination folder:
+JavadocTreeWizardPage.javadoccommand.error=Javadoc command location not specified on the Javadoc preference page.
+JavadocTreeWizardPage.nodocletname.error=Enter a doclet name.
+JavadocTreeWizardPage.invaliddocletname.error=Invalid doclet name.
+JavadocTreeWizardPage.invaliddocletpath.error=Not a valid doclet class path.
+JavadocTreeWizardPage.nodestination.error=Enter the destination folder.
+JavadocTreeWizardPage.invaliddestination.error=Not a valid folder.
+JavadocTreeWizardPage.invalidtreeselection.error=Select elements from tree.
+
+JavadocWizardPage.javadocwizardpage.description=Javadoc Generation
+JavadocWizard.javadocwizard.title=Generate Javadoc
+JavadocWizard.updatejavadoclocation.message=Do you want to update the Javadoc location for ''{0}'' with the chosen destination folder ''{1}''?
+JavadocWizard.updatejavadocdialog.label=Update Javadoc Location
+JavadocWizard.javadocprocess.label=Javadoc Generation
+JavadocWizard.saveresourcedialogCE.title=Save Resources
+JavadocWizard.saveresourcedialogCE.message=Saving resources failed.
+JavadocWizard.saveresourcedialogITE.title=Save Resources
+JavadocWizard.saveresourcedialogITE.message=Saving resources failed.
+JavadocWizard.savetask.name=Saving...
+JavadocWizard.launchconfig.name=Javadoc
+
+JavadocOptionsManager.antfileincorrectCE.warning=Unable to run wizard from Ant file, loading previous settings.
+JavadocOptionsManager.antfileincorrectIOE.warning=Error reading Ant file, loading previous settings.
+JavadocOptionsManager.antfileincorrectSAXE.warning=Error reading Ant file, loading previous settings.
+
+JavadcoStandardWizardPage.description=Configure Javadoc arguments for standard doclet.
+JavadcoStandardWizardPage.titlebutton.label=Document &title:
+JavadcoStandardWizardPage.basicgroup.label=Basic Options
+JavadcoStandardWizardPage.usebutton.label=Generate &use page
+JavadcoStandardWizardPage.hierarchybutton.label=Generate &hierarchy tree
+JavadcoStandardWizardPage.navigartorbutton.label=Generate navi&gator bar
+JavadcoStandardWizardPage.indexbutton.label=Generate &index
+JavadcoStandardWizardPage.seperateindexbutton.label=Separate index &per letter
+JavadcoStandardWizardPage.tagsgroup.label=Document these tags
+JavadcoStandardWizardPage.authorbutton.label=@&author
+JavadcoStandardWizardPage.versionbutton.label=@&version
+JavadcoStandardWizardPage.deprecatedbutton.label=@&deprecated
+JavadcoStandardWizardPage.deprecatedlistbutton.label=deprecated &list
+JavadcoStandardWizardPage.stylesheettext.label=St&yle sheet:
+JavadcoStandardWizardPage.selectallbutton.label=&Select All
+JavadcoStandardWizardPage.clearallbutton.label=&Clear All
+JavadcoStandardWizardPage.referencedclasses.label=Select &referenced classes to which Javadoc should create links:
+JavadcoStandardWizardPage.stylesheetnopath.error=Style sheet path not found.
+JavadcoStandardWizardPage.stylesheetnotcss.error=Style sheet must be a css document.
+JavadocStandardWizardPage.stylesheetbrowsebutton.label=Bro&wse...
+JavadocStandardWizardPage.configurebutton.label=Con&figure...
+JavadocStandardWizardPage.javadocpropertydialog.title=Configure Javadoc Location
+
+JavadocLinkDialogLabelProvider.configuredentry={0} - {1}
+JavadocLinkDialogLabelProvider.notconfiguredentry={0} - Not Configured
+JavadocTreeWizardPage.privatevisibilitydescription.label=Private: Generate Javadoc for all classes and members.
+JavadocTreeWizardPage.warning.mayoverwritefiles=Javadoc generation may overwrite existing files
+JavadocTreeWizardPage.packagevisibledescription.label=Package: Generate Javadoc for only package, protected, and public classes and members.
+JavadocTreeWizardPage.protectedvisibilitydescription.label=Protected: Generate Javadoc for only protected and public classes and members.
+JavadocTreeWizardPage.publicvisibilitydescription.label=Public: Generate Javadoc for only public classes and members.
+JavadocWizard.antInformationDialog.title=Javadoc Generation with Ant Scripts
+JavadocWizard.antInformationDialog.message=Ant file will be created.\nNote that to run the generated ant script, the operating system PATH must contain the Javadoc command.
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/AbstractConfigurationBlockPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/AbstractConfigurationBlockPreferencePage.java
new file mode 100644 (file)
index 0000000..9f5bb6b
--- /dev/null
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Abstract preference page which is used to wrap a
+ * {@link net.sourceforge.phpdt.internal.ui.preferences.IPreferenceConfigurationBlock}.
+ * 
+ * @since 3.0
+ */
+public abstract class AbstractConfigurationBlockPreferencePage extends
+               PreferencePage implements IWorkbenchPreferencePage {
+
+       private IPreferenceConfigurationBlock fConfigurationBlock;
+
+       private OverlayPreferenceStore fOverlayStore;
+
+       /**
+        * Creates a new preference page.
+        */
+       public AbstractConfigurationBlockPreferencePage() {
+               setDescription();
+               setPreferenceStore();
+               fOverlayStore = new OverlayPreferenceStore(getPreferenceStore(),
+                               new OverlayPreferenceStore.OverlayKey[] {});
+               fConfigurationBlock = createConfigurationBlock(fOverlayStore);
+       }
+
+       protected abstract IPreferenceConfigurationBlock createConfigurationBlock(
+                       OverlayPreferenceStore overlayPreferenceStore);
+
+       protected abstract String getHelpId();
+
+       protected abstract void setDescription();
+
+       protected abstract void setPreferenceStore();
+
+       /*
+        * @see IWorkbenchPreferencePage#init()
+        */
+       public void init(IWorkbench workbench) {
+       }
+
+       /*
+        * @see PreferencePage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               getHelpId());
+       }
+
+       /*
+        * @see PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+
+               fOverlayStore.load();
+               fOverlayStore.start();
+
+               fConfigurationBlock.createControl(parent);
+
+               initialize();
+
+               Dialog.applyDialogFont(parent);
+               return parent;
+       }
+
+       private void initialize() {
+               fConfigurationBlock.initialize();
+       }
+
+       /*
+        * @see PreferencePage#performOk()
+        */
+       public boolean performOk() {
+
+               fConfigurationBlock.performOk();
+
+               fOverlayStore.propagate();
+
+               WebUI.getDefault().savePluginPreferences();
+
+               return true;
+       }
+
+       /*
+        * @see PreferencePage#performDefaults()
+        */
+       public void performDefaults() {
+
+               fOverlayStore.loadDefaults();
+               fConfigurationBlock.performDefaults();
+
+               super.performDefaults();
+       }
+
+       /*
+        * @see DialogPage#dispose()
+        */
+       public void dispose() {
+
+               fConfigurationBlock.dispose();
+
+               if (fOverlayStore != null) {
+                       fOverlayStore.stop();
+                       fOverlayStore = null;
+               }
+
+               super.dispose();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeAssistConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeAssistConfigurationBlock.java
new file mode 100644 (file)
index 0000000..1a116f6
--- /dev/null
@@ -0,0 +1,645 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Configures the code assist preferences.
+ * 
+ * @since 3.0
+ */
+class CodeAssistConfigurationBlock implements IPreferenceConfigurationBlock {
+
+       private OverlayPreferenceStore fStore;
+
+       private PreferencePage fMainPreferencePage;
+
+       private List fContentAssistColorList;
+
+       private ColorEditor fContentAssistColorEditor;
+
+       private Control fAutoInsertDelayText;
+
+       private Control fAutoInsertJavaTriggerText;
+
+       private Control fAutoInsertJavaDocTriggerText;
+
+       private Control fAutoInsertHTMLTriggerText;
+
+       private Label fAutoInsertDelayLabel;
+
+       private Label fAutoInsertJavaTriggerLabel;
+
+       private Label fAutoInsertJavaDocTriggerLabel;
+
+       private Label fAutoInsertHTMLTriggerLabel;
+
+       // private Button fCompletionInsertsRadioButton;
+       // private Button fCompletionOverwritesRadioButton;
+       /**
+        * List of master/slave listeners when there's a dependency.
+        * 
+        * @see #createDependency(Button, String, Control)
+        * @since 3.0
+        */
+       private ArrayList fMasterSlaveListeners = new ArrayList();
+
+       private final String[][] fContentAssistColorListModel = new String[][] {
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.backgroundForCompletionProposals"), PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND }, //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.foregroundForCompletionProposals"), PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND }, //$NON-NLS-1$
+                       // {PreferencesMessages.getString("JavaEditorPreferencePage.backgroundForMethodParameters"),
+                       // PreferenceConstants.CODEASSIST_PARAMETERS_BACKGROUND },
+                       // //$NON-NLS-1$
+                       // {PreferencesMessages.getString("JavaEditorPreferencePage.foregroundForMethodParameters"),
+                       // PreferenceConstants.CODEASSIST_PARAMETERS_FOREGROUND },
+                       // //$NON-NLS-1$
+                       // {PreferencesMessages.getString("JavaEditorPreferencePage.backgroundForCompletionReplacement"),
+                       // PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND },
+                       // //$NON-NLS-1$
+                       // {PreferencesMessages.getString("JavaEditorPreferencePage.foregroundForCompletionReplacement"),
+                       // PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND }
+                       // //$NON-NLS-1$
+       };
+
+       private Map fCheckBoxes = new HashMap();
+
+       private SelectionListener fCheckBoxListener = new SelectionListener() {
+               public void widgetDefaultSelected(SelectionEvent e) {
+               }
+
+               public void widgetSelected(SelectionEvent e) {
+                       Button button = (Button) e.widget;
+                       fStore.setValue((String) fCheckBoxes.get(button), button
+                                       .getSelection());
+               }
+       };
+
+       private Map fTextFields = new HashMap();
+
+       private ModifyListener fTextFieldListener = new ModifyListener() {
+               public void modifyText(ModifyEvent e) {
+                       Text text = (Text) e.widget;
+                       fStore.setValue((String) fTextFields.get(text), text.getText());
+               }
+       };
+
+       private ArrayList fNumberFields = new ArrayList();
+
+       private ModifyListener fNumberFieldListener = new ModifyListener() {
+               public void modifyText(ModifyEvent e) {
+                       numberFieldChanged((Text) e.widget);
+               }
+       };
+
+       public CodeAssistConfigurationBlock(PreferencePage mainPreferencePage,
+                       OverlayPreferenceStore store) {
+               Assert.isNotNull(mainPreferencePage);
+               Assert.isNotNull(store);
+               fStore = store;
+               fStore.addKeys(createOverlayStoreKeys());
+               fMainPreferencePage = mainPreferencePage;
+       }
+
+       private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() {
+
+               ArrayList overlayKeys = new ArrayList();
+
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.INT,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_AUTOINSERT));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_PARAMETERS_BACKGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_PARAMETERS_FOREGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVA));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.STRING,
+                                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVADOC));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_HTML));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_SHOW_VISIBLE_PROPOSALS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_ORDER_PROPOSALS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_CASE_SENSITIVITY));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_ADDIMPORT));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_INSERT_COMPLETION));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_PREFIX_COMPLETION));
+
+               OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys
+                               .size()];
+               overlayKeys.toArray(keys);
+               return keys;
+       }
+
+       /**
+        * Creates page for hover preferences.
+        * 
+        * @param parent
+        *            the parent composite
+        * @return the control for the preference page
+        */
+       public Control createControl(Composite parent) {
+
+               PixelConverter pixelConverter = new PixelConverter(parent);
+
+               Composite contentAssistComposite = new Composite(parent, SWT.NONE);
+               contentAssistComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               contentAssistComposite.setLayout(layout);
+
+               // addCompletionRadioButtons(contentAssistComposite);
+
+               String label;
+               // label=
+               // PreferencesMessages.getString("JavaEditorPreferencePage.insertSingleProposalsAutomatically");
+               // //$NON-NLS-1$
+               // addCheckBox(contentAssistComposite, label,
+               // PreferenceConstants.CODEASSIST_AUTOINSERT, 0);
+               //              
+               // label=
+               // PreferencesMessages.getString("JavaEditorPreferencePage.completePrefixes");
+               // //$NON-NLS-1$
+               // addCheckBox(contentAssistComposite, label,
+               // PreferenceConstants.CODEASSIST_PREFIX_COMPLETION, 0);
+               //              
+               // label=
+               // PreferencesMessages.getString("JavaEditorPreferencePage.showOnlyProposalsVisibleInTheInvocationContext");
+               // //$NON-NLS-1$
+               // addCheckBox(contentAssistComposite, label,
+               // PreferenceConstants.CODEASSIST_SHOW_VISIBLE_PROPOSALS, 0);
+               //              
+               // label=
+               // PreferencesMessages.getString("JavaEditorPreferencePage.presentProposalsInAlphabeticalOrder");
+               // //$NON-NLS-1$
+               // addCheckBox(contentAssistComposite, label,
+               // PreferenceConstants.CODEASSIST_ORDER_PROPOSALS, 0);
+               //              
+               // label=
+               // PreferencesMessages.getString("JavaEditorPreferencePage.automaticallyAddImportInsteadOfQualifiedName");
+               // //$NON-NLS-1$
+               // addCheckBox(contentAssistComposite, label,
+               // PreferenceConstants.CODEASSIST_ADDIMPORT, 0);
+               //              
+               // label=
+               // PreferencesMessages.getString("JavaEditorPreferencePage.fillArgumentNamesOnMethodCompletion");
+               // //$NON-NLS-1$
+               // Button master= addCheckBox(contentAssistComposite, label,
+               // PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES, 0);
+               //              
+               // label=
+               // PreferencesMessages.getString("JavaEditorPreferencePage.guessArgumentNamesOnMethodCompletion");
+               // //$NON-NLS-1$
+               // Button slave= addCheckBox(contentAssistComposite, label,
+               // PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS, 0);
+               // createDependency(master,
+               // PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES, slave);
+               //              
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.enableAutoActivation"); //$NON-NLS-1$
+               final Button autoactivation = addCheckBox(contentAssistComposite,
+                               label, PreferenceConstants.CODEASSIST_AUTOACTIVATION, 0);
+               autoactivation.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               updateAutoactivationControls();
+                       }
+               });
+
+               Control[] labelledTextField;
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.autoActivationDelay"); //$NON-NLS-1$
+               labelledTextField = addLabelledTextField(contentAssistComposite, label,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY, 4, 0, true);
+               fAutoInsertDelayLabel = getLabelControl(labelledTextField);
+               fAutoInsertDelayText = getTextControl(labelledTextField);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.autoActivationTriggersForJava"); //$NON-NLS-1$
+               labelledTextField = addLabelledTextField(contentAssistComposite, label,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVA, 4,
+                               0, false);
+               fAutoInsertJavaTriggerLabel = getLabelControl(labelledTextField);
+               fAutoInsertJavaTriggerText = getTextControl(labelledTextField);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.autoActivationTriggersForJavaDoc"); //$NON-NLS-1$
+               labelledTextField = addLabelledTextField(contentAssistComposite, label,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVADOC,
+                               4, 0, false);
+               fAutoInsertJavaDocTriggerLabel = getLabelControl(labelledTextField);
+               fAutoInsertJavaDocTriggerText = getTextControl(labelledTextField);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.autoActivationTriggersForHTML"); //$NON-NLS-1$
+               labelledTextField = addLabelledTextField(contentAssistComposite, label,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_HTML, 4,
+                               0, false);
+               fAutoInsertHTMLTriggerLabel = getLabelControl(labelledTextField);
+               fAutoInsertHTMLTriggerText = getTextControl(labelledTextField);
+
+               Label l = new Label(contentAssistComposite, SWT.LEFT);
+               l.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.codeAssist.colorOptions")); //$NON-NLS-1$
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = 2;
+               l.setLayoutData(gd);
+
+               Composite editorComposite = new Composite(contentAssistComposite,
+                               SWT.NONE);
+               layout = new GridLayout();
+               layout.numColumns = 2;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               editorComposite.setLayout(layout);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.FILL_VERTICAL);
+               gd.horizontalSpan = 2;
+               editorComposite.setLayoutData(gd);
+
+               fContentAssistColorList = new List(editorComposite, SWT.SINGLE
+                               | SWT.V_SCROLL | SWT.BORDER);
+               gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+                               | GridData.FILL_HORIZONTAL);
+               gd.heightHint = pixelConverter.convertHeightInCharsToPixels(8);
+               fContentAssistColorList.setLayoutData(gd);
+
+               Composite stylesComposite = new Composite(editorComposite, SWT.NONE);
+               layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               stylesComposite.setLayout(layout);
+               stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+               l = new Label(stylesComposite, SWT.LEFT);
+               l.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.codeAssist.color")); //$NON-NLS-1$
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.BEGINNING;
+               l.setLayoutData(gd);
+
+               fContentAssistColorEditor = new ColorEditor(stylesComposite);
+               Button colorButton = fContentAssistColorEditor.getButton();
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalAlignment = GridData.BEGINNING;
+               colorButton.setLayoutData(gd);
+
+               fContentAssistColorList.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               handleContentAssistColorListSelection();
+                       }
+               });
+               colorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fContentAssistColorList.getSelectionIndex();
+                               String key = fContentAssistColorListModel[i][1];
+
+                               PreferenceConverter.setValue(fStore, key,
+                                               fContentAssistColorEditor.getColorValue());
+                       }
+               });
+
+               return contentAssistComposite;
+       }
+
+       private void createDependency(final Button master, String masterKey,
+                       final Control slave) {
+               indent(slave);
+               boolean masterState = fStore.getBoolean(masterKey);
+               slave.setEnabled(masterState);
+               SelectionListener listener = new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               slave.setEnabled(master.getSelection());
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               };
+               master.addSelectionListener(listener);
+               fMasterSlaveListeners.add(listener);
+       }
+
+       private static void indent(Control control) {
+               GridData gridData = new GridData();
+               gridData.horizontalIndent = 20;
+               control.setLayoutData(gridData);
+       }
+
+       private static Text getTextControl(Control[] labelledTextField) {
+               return (Text) labelledTextField[1];
+       }
+
+       private static Label getLabelControl(Control[] labelledTextField) {
+               return (Label) labelledTextField[0];
+       }
+
+       /**
+        * Returns an array of size 2: - first element is of type <code>Label</code> -
+        * second element is of type <code>Text</code> Use
+        * <code>getLabelControl</code> and <code>getTextControl</code> to get
+        * the 2 controls.
+        * 
+        * @param composite
+        *            the parent composite
+        * @param label
+        *            the text field's label
+        * @param key
+        *            the preference key
+        * @param textLimit
+        *            the text limit
+        * @param indentation
+        *            the field's indentation
+        * @param isNumber
+        *            <code>true</code> iff this text field is used to e4dit a
+        *            number
+        * @return
+        */
+       private Control[] addLabelledTextField(Composite composite, String label,
+                       String key, int textLimit, int indentation, boolean isNumber) {
+
+               PixelConverter pixelConverter = new PixelConverter(composite);
+
+               Label labelControl = new Label(composite, SWT.NONE);
+               labelControl.setText(label);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indentation;
+               labelControl.setLayoutData(gd);
+
+               Text textControl = new Text(composite, SWT.BORDER | SWT.SINGLE);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.widthHint = pixelConverter
+                               .convertWidthInCharsToPixels(textLimit + 1);
+               textControl.setLayoutData(gd);
+               textControl.setTextLimit(textLimit);
+               fTextFields.put(textControl, key);
+               if (isNumber) {
+                       fNumberFields.add(textControl);
+                       textControl.addModifyListener(fNumberFieldListener);
+               } else {
+                       textControl.addModifyListener(fTextFieldListener);
+               }
+
+               return new Control[] { labelControl, textControl };
+       }
+
+       private void addCompletionRadioButtons(Composite contentAssistComposite) {
+               Composite completionComposite = new Composite(contentAssistComposite,
+                               SWT.NONE);
+               GridData ccgd = new GridData();
+               ccgd.horizontalSpan = 2;
+               completionComposite.setLayoutData(ccgd);
+               GridLayout ccgl = new GridLayout();
+               ccgl.marginWidth = 0;
+               ccgl.numColumns = 2;
+               completionComposite.setLayout(ccgl);
+
+               // SelectionListener completionSelectionListener= new SelectionAdapter()
+               // {
+               // public void widgetSelected(SelectionEvent e) {
+               // boolean insert= fCompletionInsertsRadioButton.getSelection();
+               // fStore.setValue(PreferenceConstants.CODEASSIST_INSERT_COMPLETION,
+               // insert);
+               // }
+               // };
+               //              
+               // fCompletionInsertsRadioButton= new Button(completionComposite,
+               // SWT.RADIO | SWT.LEFT);
+               // fCompletionInsertsRadioButton.setText(PreferencesMessages.getString("JavaEditorPreferencePage.completionInserts"));
+               // //$NON-NLS-1$
+               // fCompletionInsertsRadioButton.setLayoutData(new GridData());
+               // fCompletionInsertsRadioButton.addSelectionListener(completionSelectionListener);
+               //              
+               // fCompletionOverwritesRadioButton= new Button(completionComposite,
+               // SWT.RADIO | SWT.LEFT);
+               // fCompletionOverwritesRadioButton.setText(PreferencesMessages.getString("JavaEditorPreferencePage.completionOverwrites"));
+               // //$NON-NLS-1$
+               // fCompletionOverwritesRadioButton.setLayoutData(new GridData());
+               // fCompletionOverwritesRadioButton.addSelectionListener(completionSelectionListener);
+       }
+
+       public void initialize() {
+               initializeFields();
+
+               for (int i = 0; i < fContentAssistColorListModel.length; i++)
+                       fContentAssistColorList.add(fContentAssistColorListModel[i][0]);
+               fContentAssistColorList.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if (fContentAssistColorList != null
+                                               && !fContentAssistColorList.isDisposed()) {
+                                       fContentAssistColorList.select(0);
+                                       handleContentAssistColorListSelection();
+                               }
+                       }
+               });
+
+       }
+
+       void initializeFields() {
+               Iterator e = fCheckBoxes.keySet().iterator();
+               while (e.hasNext()) {
+                       Button b = (Button) e.next();
+                       String key = (String) fCheckBoxes.get(b);
+                       b.setSelection(fStore.getBoolean(key));
+               }
+
+               e = fTextFields.keySet().iterator();
+               while (e.hasNext()) {
+                       Text t = (Text) e.next();
+                       String key = (String) fTextFields.get(t);
+                       t.setText(fStore.getString(key));
+               }
+
+               // boolean completionInserts=
+               // fStore.getBoolean(PreferenceConstants.CODEASSIST_INSERT_COMPLETION);
+               // fCompletionInsertsRadioButton.setSelection(completionInserts);
+               // fCompletionOverwritesRadioButton.setSelection(! completionInserts);
+
+               updateAutoactivationControls();
+
+               updateStatus(validatePositiveNumber("0")); //$NON-NLS-1$
+
+               // Update slaves
+               Iterator iter = fMasterSlaveListeners.iterator();
+               while (iter.hasNext()) {
+                       SelectionListener listener = (SelectionListener) iter.next();
+                       listener.widgetSelected(null);
+               }
+       }
+
+       private void updateAutoactivationControls() {
+               boolean autoactivation = fStore
+                               .getBoolean(PreferenceConstants.CODEASSIST_AUTOACTIVATION);
+               fAutoInsertDelayText.setEnabled(autoactivation);
+               fAutoInsertDelayLabel.setEnabled(autoactivation);
+
+               fAutoInsertJavaTriggerText.setEnabled(autoactivation);
+               fAutoInsertJavaTriggerLabel.setEnabled(autoactivation);
+
+               fAutoInsertJavaDocTriggerText.setEnabled(autoactivation);
+               fAutoInsertJavaDocTriggerLabel.setEnabled(autoactivation);
+
+               fAutoInsertHTMLTriggerText.setEnabled(autoactivation);
+               fAutoInsertHTMLTriggerLabel.setEnabled(autoactivation);
+       }
+
+       public void performOk() {
+       }
+
+       public void performDefaults() {
+               handleContentAssistColorListSelection();
+               initializeFields();
+       }
+
+       private void handleContentAssistColorListSelection() {
+               int i = fContentAssistColorList.getSelectionIndex();
+               String key = fContentAssistColorListModel[i][1];
+               RGB rgb = PreferenceConverter.getColor(fStore, key);
+               fContentAssistColorEditor.setColorValue(rgb);
+       }
+
+       private void numberFieldChanged(Text textControl) {
+               String number = textControl.getText();
+               IStatus status = validatePositiveNumber(number);
+               if (!status.matches(IStatus.ERROR))
+                       fStore.setValue((String) fTextFields.get(textControl), number);
+               updateStatus(status);
+       }
+
+       private IStatus validatePositiveNumber(String number) {
+               StatusInfo status = new StatusInfo();
+               if (number.length() == 0) {
+                       status.setError(PreferencesMessages
+                                       .getString("JavaEditorPreferencePage.empty_input")); //$NON-NLS-1$
+               } else {
+                       try {
+                               int value = Integer.parseInt(number);
+                               if (value < 0)
+                                       status.setError(PreferencesMessages.getFormattedString(
+                                                       "JavaEditorPreferencePage.invalid_input", number)); //$NON-NLS-1$
+                       } catch (NumberFormatException e) {
+                               status.setError(PreferencesMessages.getFormattedString(
+                                               "JavaEditorPreferencePage.invalid_input", number)); //$NON-NLS-1$
+                       }
+               }
+               return status;
+       }
+
+       private void updateStatus(IStatus status) {
+               fMainPreferencePage.setValid(status.isOK());
+               StatusUtil.applyToStatusLine(fMainPreferencePage, status);
+       }
+
+       private Button addCheckBox(Composite parent, String label, String key,
+                       int indentation) {
+               Button checkBox = new Button(parent, SWT.CHECK);
+               checkBox.setText(label);
+
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indentation;
+               gd.horizontalSpan = 2;
+               checkBox.setLayoutData(gd);
+               checkBox.addSelectionListener(fCheckBoxListener);
+
+               fCheckBoxes.put(checkBox, key);
+
+               return checkBox;
+       }
+
+       /*
+        * @see DialogPage#dispose()
+        */
+       public void dispose() {
+               // nothing to dispose
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeAssistPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeAssistPreferencePage.java
new file mode 100644 (file)
index 0000000..dca1e1f
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+/**
+ * Code Assist preference page.
+ * <p>
+ * Note: Must be public since it is referenced from plugin.xml
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class CodeAssistPreferencePage extends
+               AbstractConfigurationBlockPreferencePage {
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.AbstractConfigureationBlockPreferencePage#getHelpId()
+        */
+       protected String getHelpId() {
+               return IJavaHelpContextIds.JAVA_EDITOR_PREFERENCE_PAGE;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.AbstractConfigurationBlockPreferencePage#setDescription()
+        */
+       protected void setDescription() {
+               // This page has no description
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.AbstractConfigurationBlockPreferencePage#setPreferenceStore()
+        */
+       protected void setPreferenceStore() {
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.AbstractConfigureationBlockPreferencePage#createConfigurationBlock(net.sourceforge.phpdt.internal.ui.preferences.OverlayPreferenceStore)
+        */
+       protected IPreferenceConfigurationBlock createConfigurationBlock(
+                       OverlayPreferenceStore overlayPreferenceStore) {
+               return new CodeAssistConfigurationBlock(this, overlayPreferenceStore);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeFormatterPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeFormatterPreferencePage.java
new file mode 100644 (file)
index 0000000..8803804
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import net.sourceforge.phpdt.core.ICodeFormatter;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.ToolFactory;
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.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.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/*
+ * The page for setting code formatter options
+ */
+public class CodeFormatterPreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage {
+
+       // Preference store keys, see PHPCore.getOptions
+       private static final String PREF_NEWLINE_OPENING_BRACES = JavaCore.FORMATTER_NEWLINE_OPENING_BRACE;
+
+       private static final String PREF_NEWLINE_CONTROL_STATEMENT = JavaCore.FORMATTER_NEWLINE_CONTROL;
+
+       private static final String PREF_NEWLINE_CLEAR_ALL = JavaCore.FORMATTER_CLEAR_BLANK_LINES;
+
+       // private static final String PREF_NEWLINE_ELSE_IF=
+       // PHPCore.FORMATTER_NEWLINE_ELSE_IF;
+       private static final String PREF_NEWLINE_EMPTY_BLOCK = JavaCore.FORMATTER_NEWLINE_EMPTY_BLOCK;
+
+       private static final String PREF_LINE_SPLIT = JavaCore.FORMATTER_LINE_SPLIT;
+
+       private static final String PREF_STYLE_COMPACT_ASSIGNEMENT = JavaCore.FORMATTER_COMPACT_ASSIGNMENT;
+
+       private static final String PREF_STYLE_COMPACT_STRING_CONCATENATION = JavaCore.FORMATTER_COMPACT_STRING_CONCATENATION;
+
+       private static final String PREF_STYLE_COMPACT_ARRAYS = JavaCore.FORMATTER_COMPACT_ARRAYS;
+       
+       private static final String PREF_TAB_CHAR = JavaCore.FORMATTER_TAB_CHAR;
+
+       private static final String PREF_TAB_SIZE = JavaCore.FORMATTER_TAB_SIZE;
+
+       // values
+       private static final String INSERT = JavaCore.INSERT;
+
+       private static final String DO_NOT_INSERT = JavaCore.DO_NOT_INSERT;
+
+       private static final String COMPACT = JavaCore.COMPACT;
+
+       private static final String NORMAL = JavaCore.NORMAL;
+
+       private static final String TAB = JavaCore.TAB;
+
+       private static final String SPACE = JavaCore.SPACE;
+
+       private static final String CLEAR_ALL = JavaCore.CLEAR_ALL;
+
+       private static final String PRESERVE_ONE = JavaCore.PRESERVE_ONE;
+
+       private static String[] getAllKeys() {
+               return new String[] { PREF_NEWLINE_OPENING_BRACES,
+                               PREF_NEWLINE_CONTROL_STATEMENT, PREF_NEWLINE_CLEAR_ALL,
+                               // PREF_NEWLINE_ELSE_IF,
+                               PREF_NEWLINE_EMPTY_BLOCK, PREF_LINE_SPLIT,
+                               PREF_STYLE_COMPACT_ASSIGNEMENT, PREF_STYLE_COMPACT_STRING_CONCATENATION,
+                               PREF_STYLE_COMPACT_ARRAYS,
+                               PREF_TAB_CHAR, PREF_TAB_SIZE };
+       }
+
+       /**
+        * Gets the currently configured tab size
+        * 
+        * @deprecated Inline to avoid reference to preference page
+        */
+       public static int getTabSize() {
+               String string = (String) JavaCore.getOptions().get(PREF_TAB_SIZE);
+               return getPositiveIntValue(string, 4);
+       }
+
+       /**
+        * Gets the current compating assignement configuration
+        * 
+        * @deprecated Inline to avoid reference to preference page
+        */
+       public static boolean isCompactingAssignment() {
+               return COMPACT.equals(JavaCore.getOptions().get(
+                               PREF_STYLE_COMPACT_ASSIGNEMENT));
+       }
+
+       /**
+        * Gets the current compating assignement configuration
+        * 
+        * @deprecated Inline to avoid reference to preference page
+        */
+       public static boolean useSpaces() {
+               return SPACE.equals(JavaCore.getOptions().get(PREF_TAB_CHAR));
+       }
+
+       private static int getPositiveIntValue(String string, int dflt) {
+               try {
+                       int i = Integer.parseInt(string);
+                       if (i >= 0) {
+                               return i;
+                       }
+               } catch (NumberFormatException e) {
+               }
+               return dflt;
+       }
+
+       private static class ControlData {
+               private String fKey;
+
+               private String[] fValues;
+
+               public ControlData(String key, String[] values) {
+                       fKey = key;
+                       fValues = values;
+               }
+
+               public String getKey() {
+                       return fKey;
+               }
+
+               public String getValue(boolean selection) {
+                       int index = selection ? 0 : 1;
+                       return fValues[index];
+               }
+
+               public String getValue(int index) {
+                       return fValues[index];
+               }
+
+               public int getSelection(String value) {
+                       for (int i = 0; i < fValues.length; i++) {
+                               if (value.equals(fValues[i])) {
+                                       return i;
+                               }
+                       }
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       private Hashtable fWorkingValues;
+
+       private ArrayList fCheckBoxes;
+
+       private ArrayList fTextBoxes;
+
+       private SelectionListener fButtonSelectionListener;
+
+       private ModifyListener fTextModifyListener;
+
+       private String fPreviewText;
+
+       private IDocument fPreviewDocument;
+
+       private Text fTabSizeTextBox;
+
+       // private SourceViewer fSourceViewer;
+
+       public CodeFormatterPreferencePage() {
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+               setDescription(PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.description")); //$NON-NLS-1$
+
+               fWorkingValues = JavaCore.getOptions();
+               fCheckBoxes = new ArrayList();
+               fTextBoxes = new ArrayList();
+
+               fButtonSelectionListener = new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               if (!e.widget.isDisposed()) {
+                                       controlChanged((Button) e.widget);
+                               }
+                       }
+               };
+
+               fTextModifyListener = new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               if (!e.widget.isDisposed()) {
+                                       textChanged((Text) e.widget);
+                               }
+                       }
+               };
+
+               fPreviewDocument = new Document();
+               fPreviewText = loadPreviewFile("CodeFormatterPreviewCode.txt"); //$NON-NLS-1$   
+       }
+
+       /*
+        * @see IWorkbenchPreferencePage#init()
+        */
+       public void init(IWorkbench workbench) {
+       }
+
+       /*
+        * @see PreferencePage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               // WorkbenchHelp.setHelp(getControl(),
+               // IJavaHelpContextIds.CODEFORMATTER_PREFERENCE_PAGE);
+       }
+
+       /*
+        * @see PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               composite.setLayout(layout);
+
+               TabFolder folder = new TabFolder(composite, SWT.NONE);
+               folder.setLayout(new TabFolderLayout());
+               folder.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+               String[] insertNotInsert = new String[] { INSERT, DO_NOT_INSERT };
+
+               layout = new GridLayout();
+               layout.numColumns = 2;
+
+               Composite newlineComposite = new Composite(folder, SWT.NULL);
+               newlineComposite.setLayout(layout);
+
+               String label = PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.newline_opening_braces.label"); //$NON-NLS-1$
+               addCheckBox(newlineComposite, label, PREF_NEWLINE_OPENING_BRACES,
+                               insertNotInsert);
+
+               label = PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.newline_control_statement.label"); //$NON-NLS-1$
+               addCheckBox(newlineComposite, label, PREF_NEWLINE_CONTROL_STATEMENT,
+                               insertNotInsert);
+
+               label = PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.newline_clear_lines"); //$NON-NLS-1$
+               addCheckBox(newlineComposite, label, PREF_NEWLINE_CLEAR_ALL,
+                               new String[] { CLEAR_ALL, PRESERVE_ONE });
+
+               // label=
+               // PHPUIMessages.getString("CodeFormatterPreferencePage.newline_else_if.label");
+               // //$NON-NLS-1$
+               // addCheckBox(newlineComposite, label, PREF_NEWLINE_ELSE_IF,
+               // insertNotInsert);
+
+               label = PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.newline_empty_block.label"); //$NON-NLS-1$
+               addCheckBox(newlineComposite, label, PREF_NEWLINE_EMPTY_BLOCK,
+                               insertNotInsert);
+
+               layout = new GridLayout();
+               layout.numColumns = 2;
+
+               Composite lineSplittingComposite = new Composite(folder, SWT.NULL);
+               lineSplittingComposite.setLayout(layout);
+
+               label = PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.split_line.label"); //$NON-NLS-1$
+               addTextField(lineSplittingComposite, label, PREF_LINE_SPLIT);
+
+               layout = new GridLayout();
+               layout.numColumns = 2;
+
+               Composite styleComposite = new Composite(folder, SWT.NULL);
+               styleComposite.setLayout(layout);
+
+               label = PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.style_compact_assignement.label"); //$NON-NLS-1$
+               addCheckBox(styleComposite, label, PREF_STYLE_COMPACT_ASSIGNEMENT,
+                               new String[] { COMPACT, NORMAL });
+               
+               label = PHPUIMessages
+               .getString("CodeFormatterPreferencePage.style_compact_string_concatenation.label"); //$NON-NLS-1$
+               addCheckBox(styleComposite, label, PREF_STYLE_COMPACT_STRING_CONCATENATION,
+               new String[] { COMPACT, NORMAL });
+               
+               label = PHPUIMessages
+               .getString("CodeFormatterPreferencePage.style_compact_arrays.label"); //$NON-NLS-1$
+               addCheckBox(styleComposite, label, PREF_STYLE_COMPACT_ARRAYS,
+               new String[] { COMPACT, NORMAL });              
+
+               label = PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.tab_char.label"); //$NON-NLS-1$
+               addCheckBox(styleComposite, label, PREF_TAB_CHAR, new String[] { TAB,
+                               SPACE });
+
+               label = PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.tab_size.label"); //$NON-NLS-1$
+               fTabSizeTextBox = addTextField(styleComposite, label, PREF_TAB_SIZE);
+
+               TabItem item = new TabItem(folder, SWT.NONE);
+               item.setText(PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.tab.newline.tabtitle")); //$NON-NLS-1$
+               item.setControl(newlineComposite);
+
+               item = new TabItem(folder, SWT.NONE);
+               item
+                               .setText(PHPUIMessages
+                                               .getString("CodeFormatterPreferencePage.tab.linesplit.tabtitle")); //$NON-NLS-1$
+               item.setControl(lineSplittingComposite);
+
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(PHPUIMessages
+                               .getString("CodeFormatterPreferencePage.tab.style.tabtitle")); //$NON-NLS-1$
+               item.setControl(styleComposite);
+
+               // fSourceViewer= createPreview(parent);
+
+               updatePreview();
+
+               return composite;
+       }
+
+       // private SourceViewer createPreview(Composite parent) {
+       // SourceViewer previewViewer= new SourceViewer(parent, null, SWT.V_SCROLL |
+       // SWT.H_SCROLL | SWT.BORDER);
+       // JavaTextTools tools= JavaPlugin.getDefault().getJavaTextTools();
+       // previewViewer.configure(new PHPSourceViewerConfiguration(tools, null));
+       // previewViewer.getTextWidget().setFont(JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
+       // previewViewer.getTextWidget().setTabs(getPositiveIntValue((String)
+       // fWorkingValues.get(PREF_TAB_SIZE), 0));
+       // previewViewer.setEditable(false);
+       // previewViewer.setDocument(fPreviewDocument);
+       // Control control= previewViewer.getControl();
+       // GridData gdata= new GridData(GridData.FILL_BOTH);
+       // gdata.widthHint= convertWidthInCharsToPixels(30);
+       // gdata.heightHint= convertHeightInCharsToPixels(5);
+       // control.setLayoutData(gdata);
+       // return previewViewer;
+       // }
+
+       private Button addCheckBox(Composite parent, String label, String key,
+                       String[] values) {
+               ControlData data = new ControlData(key, values);
+
+               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalSpan = 2;
+
+               Button checkBox = new Button(parent, SWT.CHECK);
+               checkBox.setText(label);
+               checkBox.setData(data);
+               checkBox.setLayoutData(gd);
+
+               String currValue = (String) fWorkingValues.get(key);
+               checkBox.setSelection(data.getSelection(currValue) == 0);
+               checkBox.addSelectionListener(fButtonSelectionListener);
+
+               fCheckBoxes.add(checkBox);
+               return checkBox;
+       }
+
+       private Text addTextField(Composite parent, String label, String key) {
+               Label labelControl = new Label(parent, SWT.NONE);
+               labelControl.setText(label);
+               labelControl.setLayoutData(new GridData());
+
+               Text textBox = new Text(parent, SWT.BORDER | SWT.SINGLE);
+               textBox.setData(key);
+               textBox.setLayoutData(new GridData());
+
+               String currValue = (String) fWorkingValues.get(key);
+               textBox.setText(String.valueOf(getPositiveIntValue(currValue, 1)));
+               textBox.setTextLimit(3);
+               textBox.addModifyListener(fTextModifyListener);
+
+               GridData gd = new GridData();
+               gd.widthHint = convertWidthInCharsToPixels(5);
+               textBox.setLayoutData(gd);
+
+               fTextBoxes.add(textBox);
+               return textBox;
+       }
+
+       private void controlChanged(Button button) {
+               ControlData data = (ControlData) button.getData();
+               boolean selection = button.getSelection();
+               String newValue = data.getValue(selection);
+               fWorkingValues.put(data.getKey(), newValue);
+               updatePreview();
+
+               if (PREF_TAB_CHAR.equals(data.getKey())) {
+                       updateStatus(new StatusInfo());
+                       if (selection) {
+                               fTabSizeTextBox.setText((String) fWorkingValues
+                                               .get(PREF_TAB_SIZE));
+                       }
+               }
+       }
+
+       private void textChanged(Text textControl) {
+               String key = (String) textControl.getData();
+               String number = textControl.getText();
+               IStatus status = validatePositiveNumber(number);
+               if (!status.matches(IStatus.ERROR)) {
+                       fWorkingValues.put(key, number);
+               }
+               // if (PREF_TAB_SIZE.equals(key)) {
+               // fSourceViewer.getTextWidget().setTabs(getPositiveIntValue(number,
+               // 0));
+               // }
+               updateStatus(status);
+               updatePreview();
+       }
+
+       /*
+        * @see IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               String[] allKeys = getAllKeys();
+               // preserve other options
+               // store in JCore
+               Hashtable actualOptions = JavaCore.getOptions();
+               for (int i = 0; i < allKeys.length; i++) {
+                       String key = allKeys[i];
+                       String val = (String) fWorkingValues.get(key);
+                       actualOptions.put(key, val);
+               }
+               JavaCore.setOptions(actualOptions);
+               WebUI.getDefault().savePluginPreferences();
+               return super.performOk();
+       }
+
+       /*
+        * @see PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               fWorkingValues = JavaCore.getDefaultOptions();
+               updateControls();
+               super.performDefaults();
+       }
+
+       private String loadPreviewFile(String filename) {
+               String separator = System.getProperty("line.separator"); //$NON-NLS-1$
+               StringBuffer btxt = new StringBuffer(512);
+               BufferedReader rin = null;
+               try {
+                       rin = new BufferedReader(new InputStreamReader(getClass()
+                                       .getResourceAsStream(filename)));
+                       String line;
+                       while ((line = rin.readLine()) != null) {
+                               btxt.append(line);
+                               btxt.append(separator);
+                       }
+               } catch (IOException io) {
+                       WebUI.log(io);
+               } finally {
+                       if (rin != null) {
+                               try {
+                                       rin.close();
+                               } catch (IOException e) {
+                               }
+                       }
+               }
+               return btxt.toString();
+       }
+
+       private void updatePreview() {
+               ICodeFormatter formatter = ToolFactory
+                               .createDefaultCodeFormatter(fWorkingValues);
+               fPreviewDocument.set(formatter.format(fPreviewText, 0, null, "\n")); //$NON-NLS-1$
+       }
+
+       private void updateControls() {
+               // update the UI
+               for (int i = fCheckBoxes.size() - 1; i >= 0; i--) {
+                       Button curr = (Button) fCheckBoxes.get(i);
+                       ControlData data = (ControlData) curr.getData();
+
+                       String currValue = (String) fWorkingValues.get(data.getKey());
+                       curr.setSelection(data.getSelection(currValue) == 0);
+               }
+               for (int i = fTextBoxes.size() - 1; i >= 0; i--) {
+                       Text curr = (Text) fTextBoxes.get(i);
+                       String key = (String) curr.getData();
+                       String currValue = (String) fWorkingValues.get(key);
+                       curr.setText(currValue);
+               }
+       }
+
+       private IStatus validatePositiveNumber(String number) {
+               StatusInfo status = new StatusInfo();
+               if (number.length() == 0) {
+                       status.setError(PHPUIMessages
+                                       .getString("CodeFormatterPreferencePage.empty_input")); //$NON-NLS-1$
+               } else {
+                       try {
+                               int value = Integer.parseInt(number);
+                               if (value < 0) {
+                                       status
+                                                       .setError(PHPUIMessages
+                                                                       .getFormattedString(
+                                                                                       "CodeFormatterPreferencePage.invalid_input", number)); //$NON-NLS-1$
+                               }
+                       } catch (NumberFormatException e) {
+                               status.setError(PHPUIMessages.getFormattedString(
+                                               "CodeFormatterPreferencePage.invalid_input", number)); //$NON-NLS-1$
+                       }
+               }
+               return status;
+       }
+
+       private void updateStatus(IStatus status) {
+               if (!status.matches(IStatus.ERROR)) {
+                       // look if there are more severe errors
+                       for (int i = 0; i < fTextBoxes.size(); i++) {
+                               Text curr = (Text) fTextBoxes.get(i);
+                               if (!(curr == fTabSizeTextBox && usesTabs())) {
+                                       IStatus currStatus = validatePositiveNumber(curr.getText());
+                                       status = StatusUtil.getMoreSevere(currStatus, status);
+                               }
+                       }
+               }
+               setValid(!status.matches(IStatus.ERROR));
+               StatusUtil.applyToStatusLine(this, status);
+       }
+
+       private boolean usesTabs() {
+               return TAB.equals(fWorkingValues.get(PREF_TAB_CHAR));
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeFormatterPreviewCode.txt b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeFormatterPreviewCode.txt
new file mode 100644 (file)
index 0000000..6fcffee
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+{
+
+if (size < currentSize) {
+try {
+size = inStream.available();
+} catch (IOException e) {
+}
+}
+else if (size == currentSize) {
+++size;
+}
+else {
+--size;
+}
+
+}
+?>
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeTemplateBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeTemplateBlock.java
new file mode 100644 (file)
index 0000000..1625b05
--- /dev/null
@@ -0,0 +1,587 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ITreeListAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.TreeListDialogField;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
+import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ */
+public class CodeTemplateBlock {
+
+       private class CodeTemplateAdapter implements ITreeListAdapter,
+                       IDialogFieldListener {
+
+               private final Object[] NO_CHILDREN = new Object[0];
+
+               public void customButtonPressed(TreeListDialogField field, int index) {
+                       doButtonPressed(index, field.getSelectedElements());
+               }
+
+               public void selectionChanged(TreeListDialogField field) {
+                       List selected = field.getSelectedElements();
+                       field.enableButton(IDX_EDIT, canEdit(selected));
+                       field.enableButton(IDX_EXPORT, !selected.isEmpty());
+
+                       updateSourceViewerInput(selected);
+               }
+
+               public void doubleClicked(TreeListDialogField field) {
+                       List selected = field.getSelectedElements();
+                       if (canEdit(selected)) {
+                               doButtonPressed(IDX_EDIT, selected);
+                       }
+               }
+
+               public Object[] getChildren(TreeListDialogField field, Object element) {
+                       if (element == COMMENT_NODE || element == CODE_NODE) {
+                               return getTemplateOfCategory(element == COMMENT_NODE);
+                       }
+                       return NO_CHILDREN;
+               }
+
+               public Object getParent(TreeListDialogField field, Object element) {
+                       if (element instanceof TemplatePersistenceData) {
+                               TemplatePersistenceData data = (TemplatePersistenceData) element;
+                               if (data.getTemplate().getName().endsWith(
+                                               CodeTemplateContextType.COMMENT_SUFFIX)) {
+                                       return COMMENT_NODE;
+                               }
+                               return CODE_NODE;
+                       }
+                       return null;
+               }
+
+               public boolean hasChildren(TreeListDialogField field, Object element) {
+                       return (element == COMMENT_NODE || element == CODE_NODE);
+               }
+
+               public void dialogFieldChanged(DialogField field) {
+               }
+
+               public void keyPressed(TreeListDialogField field, KeyEvent event) {
+               }
+
+       }
+
+       private static class CodeTemplateLabelProvider extends LabelProvider {
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+                */
+               public Image getImage(Object element) {
+                       return null;
+
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+                */
+               public String getText(Object element) {
+                       if (element == COMMENT_NODE || element == CODE_NODE) {
+                               return (String) element;
+                       }
+                       TemplatePersistenceData data = (TemplatePersistenceData) element;
+                       Template template = data.getTemplate();
+                       String name = template.getName();
+                       if (CodeTemplateContextType.CATCHBLOCK.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.catchblock.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.METHODSTUB.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.methodstub.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.CONSTRUCTORSTUB.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.constructorstub.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.GETTERSTUB.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.getterstub.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.SETTERSTUB.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.setterstub.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.NEWTYPE.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.newtype.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.TYPECOMMENT.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.typecomment.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.FIELDCOMMENT.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.fieldcomment.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.METHODCOMMENT.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.methodcomment.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.OVERRIDECOMMENT.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.overridecomment.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.CONSTRUCTORCOMMENT.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.constructorcomment.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.GETTERCOMMENT.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.gettercomment.label"); //$NON-NLS-1$
+                       } else if (CodeTemplateContextType.SETTERCOMMENT.equals(name)) {
+                               return PreferencesMessages
+                                               .getString("CodeTemplateBlock.settercomment.label"); //$NON-NLS-1$
+                       }
+                       return template.getDescription();
+               }
+
+       }
+
+       private final static int IDX_EDIT = 0;
+
+       private final static int IDX_IMPORT = 2;
+
+       private final static int IDX_EXPORT = 3;
+
+       private final static int IDX_EXPORTALL = 4;
+
+       protected final static Object COMMENT_NODE = PreferencesMessages
+                       .getString("CodeTemplateBlock.templates.comment.node"); //$NON-NLS-1$
+
+       protected final static Object CODE_NODE = PreferencesMessages
+                       .getString("CodeTemplateBlock.templates.code.node"); //$NON-NLS-1$
+
+       private static final String PREF_JAVADOC_STUBS = PreferenceConstants.CODEGEN_ADD_COMMENTS;
+
+       private TreeListDialogField fCodeTemplateTree;
+
+       private SelectionButtonDialogField fCreateJavaDocComments;
+
+       protected TemplateStore fTemplates;
+
+       private PixelConverter fPixelConverter;
+
+       private SourceViewer fPatternViewer;
+
+       private Control fSWTWidget;
+
+       private TemplateVariableProcessor fTemplateProcessor;
+
+       public CodeTemplateBlock() {
+
+               fTemplates = WebUI.getDefault().getCodeTemplateStore();
+               fTemplateProcessor = new TemplateVariableProcessor();
+
+               CodeTemplateAdapter adapter = new CodeTemplateAdapter();
+
+               String[] buttonLabels = new String[] {
+                               /* IDX_EDIT */PreferencesMessages
+                                               .getString("CodeTemplateBlock.templates.edit.button"), //$NON-NLS-1$
+                               /* */null,
+                               /* IDX_IMPORT */PreferencesMessages
+                                               .getString("CodeTemplateBlock.templates.import.button"), //$NON-NLS-1$
+                               /* IDX_EXPORT */PreferencesMessages
+                                               .getString("CodeTemplateBlock.templates.export.button"), //$NON-NLS-1$
+                               /* IDX_EXPORTALL */PreferencesMessages
+                                               .getString("CodeTemplateBlock.templates.exportall.button") //$NON-NLS-1$
+
+               };
+               fCodeTemplateTree = new TreeListDialogField(adapter, buttonLabels,
+                               new CodeTemplateLabelProvider());
+               fCodeTemplateTree.setDialogFieldListener(adapter);
+               fCodeTemplateTree.setLabelText(PreferencesMessages
+                               .getString("CodeTemplateBlock.templates.label")); //$NON-NLS-1$
+
+               fCodeTemplateTree.enableButton(IDX_EXPORT, false);
+               fCodeTemplateTree.enableButton(IDX_EDIT, false);
+
+               fCodeTemplateTree.addElement(COMMENT_NODE);
+               fCodeTemplateTree.addElement(CODE_NODE);
+
+               fCreateJavaDocComments = new SelectionButtonDialogField(SWT.CHECK
+                               | SWT.WRAP);
+               fCreateJavaDocComments.setLabelText(PreferencesMessages
+                               .getString("CodeTemplateBlock.createcomment.label")); //$NON-NLS-1$
+               fCreateJavaDocComments.setSelection(PreferenceConstants
+                               .getPreferenceStore().getBoolean(PREF_JAVADOC_STUBS));
+
+               fCodeTemplateTree.selectFirstElement();
+       }
+
+       protected Control createContents(Composite parent) {
+               fPixelConverter = new PixelConverter(parent);
+               fSWTWidget = parent;
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               composite.setLayout(layout);
+
+               fCodeTemplateTree.doFillIntoGrid(composite, 3);
+               LayoutUtil
+                               .setHorizontalSpan(fCodeTemplateTree.getLabelControl(null), 2);
+               LayoutUtil
+                               .setHorizontalGrabbing(fCodeTemplateTree.getTreeControl(null));
+
+               fPatternViewer = createViewer(composite, 2);
+
+               fCreateJavaDocComments.doFillIntoGrid(composite, 2);
+
+               DialogField label = new DialogField();
+               label.setLabelText(PreferencesMessages
+                               .getString("CodeTemplateBlock.createcomment.description")); //$NON-NLS-1$
+               label.doFillIntoGrid(composite, 2);
+
+               return composite;
+
+       }
+
+       private Shell getShell() {
+               if (fSWTWidget != null) {
+                       return fSWTWidget.getShell();
+               }
+               return WebUI.getActiveWorkbenchShell();
+       }
+
+       private SourceViewer createViewer(Composite parent, int nColumns) {
+               Label label = new Label(parent, SWT.NONE);
+               label.setText(PreferencesMessages
+                               .getString("CodeTemplateBlock.preview")); //$NON-NLS-1$
+               GridData data = new GridData();
+               data.horizontalSpan = nColumns;
+               label.setLayoutData(data);
+
+               IDocument document = new Document();
+               JavaTextTools tools = WebUI.getDefault().getJavaTextTools();
+               tools.setupJavaDocumentPartitioner(document,
+                               IPHPPartitions.PHP_PARTITIONING);
+               IPreferenceStore store = WebUI.getDefault()
+                               .getCombinedPreferenceStore();
+               SourceViewer viewer = new JavaSourceViewer(parent, null, null, false,
+                               SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
+               TemplateEditorSourceViewerConfiguration configuration = new TemplateEditorSourceViewerConfiguration(
+                               tools.getColorManager(), store, null, fTemplateProcessor);
+               viewer.configure(configuration);
+               viewer.setEditable(false);
+               viewer.setDocument(document);
+
+               Font font = JFaceResources
+                               .getFont(PreferenceConstants.EDITOR_TEXT_FONT);
+               viewer.getTextWidget().setFont(font);
+               new JavaSourcePreviewerUpdater(viewer, configuration, store);
+
+               Control control = viewer.getControl();
+               data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.FILL_VERTICAL);
+               data.horizontalSpan = nColumns;
+               data.heightHint = fPixelConverter.convertHeightInCharsToPixels(5);
+               control.setLayoutData(data);
+
+               return viewer;
+       }
+
+       protected TemplatePersistenceData[] getTemplateOfCategory(boolean isComment) {
+               ArrayList res = new ArrayList();
+               TemplatePersistenceData[] templates = fTemplates.getTemplateData(false);
+               for (int i = 0; i < templates.length; i++) {
+                       TemplatePersistenceData curr = templates[i];
+                       if (isComment == curr.getTemplate().getName().endsWith(
+                                       CodeTemplateContextType.COMMENT_SUFFIX)) {
+                               res.add(curr);
+                       }
+               }
+               return (TemplatePersistenceData[]) res
+                               .toArray(new TemplatePersistenceData[res.size()]);
+       }
+
+       protected static boolean canEdit(List selected) {
+               return selected.size() == 1
+                               && (selected.get(0) instanceof TemplatePersistenceData);
+       }
+
+       protected void updateSourceViewerInput(List selection) {
+               if (fPatternViewer == null
+                               || fPatternViewer.getTextWidget().isDisposed()) {
+                       return;
+               }
+               if (selection.size() == 1
+                               && selection.get(0) instanceof TemplatePersistenceData) {
+                       TemplatePersistenceData data = (TemplatePersistenceData) selection
+                                       .get(0);
+                       Template template = data.getTemplate();
+                       TemplateContextType type = WebUI.getDefault()
+                                       .getCodeTemplateContextRegistry().getContextType(
+                                                       template.getContextTypeId());
+                       fTemplateProcessor.setContextType(type);
+                       fPatternViewer.getDocument().set(template.getPattern());
+               } else {
+                       fPatternViewer.getDocument().set(""); //$NON-NLS-1$
+               }
+       }
+
+       protected void doButtonPressed(int buttonIndex, List selected) {
+               if (buttonIndex == IDX_EDIT) {
+                       edit((TemplatePersistenceData) selected.get(0));
+               } else if (buttonIndex == IDX_EXPORT) {
+                       export(selected);
+               } else if (buttonIndex == IDX_EXPORTALL) {
+                       exportAll();
+               } else if (buttonIndex == IDX_IMPORT) {
+                       import_();
+               }
+       }
+
+       private void edit(TemplatePersistenceData data) {
+               Template newTemplate = new Template(data.getTemplate());
+               EditTemplateDialog dialog = new EditTemplateDialog(getShell(),
+                               newTemplate, true, false, WebUI.getDefault()
+                                               .getCodeTemplateContextRegistry());
+               if (dialog.open() == Window.OK) {
+                       // changed
+                       data.setTemplate(newTemplate);
+                       fCodeTemplateTree.refresh(data);
+                       fCodeTemplateTree.selectElements(new StructuredSelection(data));
+               }
+       }
+
+       private void import_() {
+               FileDialog dialog = new FileDialog(getShell());
+               dialog.setText(PreferencesMessages
+                               .getString("CodeTemplateBlock.import.title")); //$NON-NLS-1$
+               dialog.setFilterExtensions(new String[] { PreferencesMessages
+                               .getString("CodeTemplateBlock.import.extension") }); //$NON-NLS-1$
+               String path = dialog.open();
+
+               if (path == null)
+                       return;
+
+               try {
+                       TemplateReaderWriter reader = new TemplateReaderWriter();
+                       File file = new File(path);
+                       if (file.exists()) {
+                               InputStream input = new BufferedInputStream(
+                                               new FileInputStream(file));
+                               TemplatePersistenceData[] datas = reader.read(input, null);
+                               for (int i = 0; i < datas.length; i++) {
+                                       updateTemplate(datas[i]);
+                               }
+                       }
+
+                       fCodeTemplateTree.refresh();
+                       updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
+
+               } catch (FileNotFoundException e) {
+                       openReadErrorDialog(e);
+               } catch (IOException e) {
+                       openReadErrorDialog(e);
+               }
+
+       }
+
+       private void updateTemplate(TemplatePersistenceData data) {
+               TemplatePersistenceData[] datas = fTemplates.getTemplateData(true);
+               for (int i = 0; i < datas.length; i++) {
+                       String id = datas[i].getId();
+                       if (id != null && id.equals(data.getId())) {
+                               datas[i].setTemplate(data.getTemplate());
+                               break;
+                       }
+               }
+       }
+
+       private void exportAll() {
+               export(fTemplates.getTemplateData(false));
+       }
+
+       private void export(List selected) {
+               List datas = new ArrayList();
+               for (int i = 0; i < selected.size(); i++) {
+                       Object curr = selected.get(i);
+                       if (curr instanceof TemplatePersistenceData) {
+                               datas.add(curr);
+                       } else {
+                               TemplatePersistenceData[] cat = getTemplateOfCategory(curr == COMMENT_NODE);
+                               datas.addAll(Arrays.asList(cat));
+                       }
+               }
+               export((TemplatePersistenceData[]) datas
+                               .toArray(new TemplatePersistenceData[datas.size()]));
+       }
+
+       private void export(TemplatePersistenceData[] templates) {
+               FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
+               dialog
+                               .setText(PreferencesMessages
+                                               .getFormattedString(
+                                                               "CodeTemplateBlock.export.title", String.valueOf(templates.length))); //$NON-NLS-1$
+               dialog.setFilterExtensions(new String[] { PreferencesMessages
+                               .getString("CodeTemplateBlock.export.extension") }); //$NON-NLS-1$
+               dialog.setFileName(PreferencesMessages
+                               .getString("CodeTemplateBlock.export.filename")); //$NON-NLS-1$
+               String path = dialog.open();
+
+               if (path == null)
+                       return;
+
+               File file = new File(path);
+
+               if (file.isHidden()) {
+                       String title = PreferencesMessages
+                                       .getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$ 
+                       String message = PreferencesMessages
+                                       .getFormattedString(
+                                                       "CodeTemplateBlock.export.error.hidden", file.getAbsolutePath()); //$NON-NLS-1$
+                       MessageDialog.openError(getShell(), title, message);
+                       return;
+               }
+
+               if (file.exists() && !file.canWrite()) {
+                       String title = PreferencesMessages
+                                       .getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$
+                       String message = PreferencesMessages
+                                       .getFormattedString(
+                                                       "CodeTemplateBlock.export.error.canNotWrite", file.getAbsolutePath()); //$NON-NLS-1$
+                       MessageDialog.openError(getShell(), title, message);
+                       return;
+               }
+
+               if (!file.exists() || confirmOverwrite(file)) {
+                       try {
+                               OutputStream output = new BufferedOutputStream(
+                                               new FileOutputStream(file));
+                               TemplateReaderWriter writer = new TemplateReaderWriter();
+                               writer.save(templates, output);
+                       } catch (IOException e) {
+                               openWriteErrorDialog(e);
+                       }
+               }
+
+       }
+
+       private boolean confirmOverwrite(File file) {
+               return MessageDialog
+                               .openQuestion(
+                                               getShell(),
+                                               PreferencesMessages
+                                                               .getString("CodeTemplateBlock.export.exists.title"), //$NON-NLS-1$
+                                               PreferencesMessages
+                                                               .getFormattedString(
+                                                                               "CodeTemplateBlock.export.exists.message", file.getAbsolutePath())); //$NON-NLS-1$
+       }
+
+       public void performDefaults() {
+               IPreferenceStore prefs = WebUI.getDefault()
+                               .getPreferenceStore();
+               fCreateJavaDocComments.setSelection(prefs
+                               .getDefaultBoolean(PREF_JAVADOC_STUBS));
+
+               fTemplates.restoreDefaults();
+
+               // refresh
+               fCodeTemplateTree.refresh();
+               updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
+       }
+
+       public boolean performOk(boolean enabled) {
+               IPreferenceStore prefs = PreferenceConstants.getPreferenceStore();
+               prefs.setValue(PREF_JAVADOC_STUBS, fCreateJavaDocComments.isSelected());
+               WebUI.getDefault().savePluginPreferences();
+
+               try {
+                       fTemplates.save();
+               } catch (IOException e) {
+                       WebUI.log(e);
+                       openWriteErrorDialog(e);
+               }
+               return true;
+       }
+
+       public void performCancel() {
+               try {
+                       fTemplates.load();
+               } catch (IOException e) {
+                       openReadErrorDialog(e);
+               }
+       }
+
+       private void openReadErrorDialog(Exception e) {
+               String title = PreferencesMessages
+                               .getString("CodeTemplateBlock.error.read.title"); //$NON-NLS-1$
+
+               String message = e.getLocalizedMessage();
+               if (message != null)
+                       message = PreferencesMessages.getFormattedString(
+                                       "CodeTemplateBlock.error.parse.message", message); //$NON-NLS-1$
+               else
+                       message = PreferencesMessages
+                                       .getString("CodeTemplateBlock.error.read.message"); //$NON-NLS-1$
+               MessageDialog.openError(getShell(), title, message);
+       }
+
+       private void openWriteErrorDialog(Exception e) {
+               String title = PreferencesMessages
+                               .getString("CodeTemplateBlock.error.write.title"); //$NON-NLS-1$
+               String message = PreferencesMessages
+                               .getString("CodeTemplateBlock.error.write.message"); //$NON-NLS-1$
+               MessageDialog.openError(getShell(), title, message);
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeTemplatePreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CodeTemplatePreferencePage.java
new file mode 100644 (file)
index 0000000..baab7d9
--- /dev/null
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/*
+ * The page to configure the code formatter options.
+ */
+public class CodeTemplatePreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage, IStatusChangeListener {
+
+       private CodeTemplateBlock fCodeTemplateConfigurationBlock;
+
+       public CodeTemplatePreferencePage() {
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+               // setDescription(PreferencesMessages.getString("CodeTemplatesPreferencePage.description"));
+               // //$NON-NLS-1$
+
+               // only used when page is shown programatically
+               setTitle(PreferencesMessages
+                               .getString("CodeTemplatesPreferencePage.title")); //$NON-NLS-1$
+
+               fCodeTemplateConfigurationBlock = new CodeTemplateBlock();
+       }
+
+       /*
+        * @see IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+        */
+       public void init(IWorkbench workbench) {
+       }
+
+       /*
+        * @see PreferencePage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.CODE_MANIPULATION_PREFERENCE_PAGE);
+       }
+
+       /*
+        * @see PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+               Control composite = fCodeTemplateConfigurationBlock
+                               .createContents(parent);
+               Dialog.applyDialogFont(composite);
+               return composite;
+       }
+
+       /*
+        * @see IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               if (!fCodeTemplateConfigurationBlock.performOk(true)) {
+                       return false;
+               }
+               return super.performOk();
+       }
+
+       /*
+        * @see PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               fCodeTemplateConfigurationBlock.performDefaults();
+               super.performDefaults();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener#statusChanged(org.eclipse.core.runtime.IStatus)
+        */
+       public void statusChanged(IStatus status) {
+               setValid(!status.matches(IStatus.ERROR));
+               StatusUtil.applyToStatusLine(this, status);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.preference.IPreferencePage#performCancel()
+        */
+       public boolean performCancel() {
+               fCodeTemplateConfigurationBlock.performCancel();
+
+               return super.performCancel();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/ColorEditor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/ColorEditor.java
new file mode 100644 (file)
index 0000000..a4c4761
--- /dev/null
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+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.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.ColorDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A "button" of a certain color determined by the color picker.
+ */
+public class ColorEditor {
+
+       private Point fExtent;
+
+       private Image fImage;
+
+       private RGB fColorValue;
+
+       private Color fColor;
+
+       private Button fButton;
+
+       public ColorEditor(Composite parent) {
+
+               fButton = new Button(parent, SWT.PUSH);
+               fExtent = computeImageSize(parent);
+               fImage = new Image(parent.getDisplay(), fExtent.x, fExtent.y);
+
+               GC gc = new GC(fImage);
+               gc.setBackground(fButton.getBackground());
+               gc.fillRectangle(0, 0, fExtent.x, fExtent.y);
+               gc.dispose();
+
+               fButton.setImage(fImage);
+               fButton.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent event) {
+                               ColorDialog colorDialog = new ColorDialog(fButton.getShell());
+                               colorDialog.setRGB(fColorValue);
+                               RGB newColor = colorDialog.open();
+                               if (newColor != null) {
+                                       fColorValue = newColor;
+                                       updateColorImage();
+                               }
+                       }
+               });
+
+               fButton.addDisposeListener(new DisposeListener() {
+                       public void widgetDisposed(DisposeEvent event) {
+                               if (fImage != null) {
+                                       fImage.dispose();
+                                       fImage = null;
+                               }
+                               if (fColor != null) {
+                                       fColor.dispose();
+                                       fColor = null;
+                               }
+                       }
+               });
+       }
+
+       public RGB getColorValue() {
+               return fColorValue;
+       }
+
+       public void setColorValue(RGB rgb) {
+               fColorValue = rgb;
+               updateColorImage();
+       }
+
+       public Button getButton() {
+               return fButton;
+       }
+
+       protected void updateColorImage() {
+
+               Display display = fButton.getDisplay();
+
+               GC gc = new GC(fImage);
+               gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
+               gc.drawRectangle(0, 2, fExtent.x - 1, fExtent.y - 4);
+
+               if (fColor != null)
+                       fColor.dispose();
+
+               fColor = new Color(display, fColorValue);
+               gc.setBackground(fColor);
+               gc.fillRectangle(1, 3, fExtent.x - 2, fExtent.y - 5);
+               gc.dispose();
+
+               fButton.setImage(fImage);
+       }
+
+       protected Point computeImageSize(Control window) {
+               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;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/ColorSettingPreviewCode.txt b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/ColorSettingPreviewCode.txt
new file mode 100644 (file)
index 0000000..c89390a
--- /dev/null
@@ -0,0 +1,19 @@
+<?php 
+/**
+ * This is about <code>ClassName</code>.
+ * 
+ * @author author
+ */
+class ClassName extends SuperClass {
+       /* This comment may span multiple lines. */
+       private $integer = 0;
+       // This comment may span only this line
+       private $string = "zero";
+
+       public function info() {
+               # call a predefined php function
+               phpinfo();
+               return "test";
+       }
+}
+?>
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerConfigurationBlock.java
new file mode 100644 (file)
index 0000000..05e76f8
--- /dev/null
@@ -0,0 +1,772 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+
+import org.eclipse.core.runtime.IStatus;
+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.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ */
+public class CompilerConfigurationBlock extends OptionsConfigurationBlock {
+
+       // Preference store keys, see JavaCore.getOptions
+       private static final String PREF_PB_PHP_VAR_DEPRECATED = JavaCore.COMPILER_PB_PHP_VAR_DEPRECATED;
+
+       private static final String PREF_PB_PHP_KEYWORD = JavaCore.COMPILER_PB_PHP_KEYWORD;
+
+       private static final String PREF_PB_PHP_UPPERCASE_IDENTIFIER = JavaCore.COMPILER_PB_PHP_UPPERCASE_IDENTIFIER;
+
+       private static final String PREF_PB_PHP_FILE_NOT_EXIST = JavaCore.COMPILER_PB_PHP_FILE_NOT_EXIST;
+
+       private static final String PREF_PB_UNREACHABLE_CODE = JavaCore.COMPILER_PB_UNREACHABLE_CODE;
+
+       private static final String PREF_PB_UNINITIALIZED_LOCAL_VARIABLE = JavaCore.COMPILER_PB_UNINITIALIZED_LOCAL_VARIABLE;
+
+       // private static final String PREF_LOCAL_VARIABLE_ATTR=
+       // JavaCore.COMPILER_LOCAL_VARIABLE_ATTR;
+       // private static final String PREF_LINE_NUMBER_ATTR=
+       // JavaCore.COMPILER_LINE_NUMBER_ATTR;
+       // private static final String PREF_SOURCE_FILE_ATTR=
+       // JavaCore.COMPILER_SOURCE_FILE_ATTR;
+       // private static final String PREF_CODEGEN_UNUSED_LOCAL=
+       // JavaCore.COMPILER_CODEGEN_UNUSED_LOCAL;
+       // private static final String PREF_CODEGEN_TARGET_PLATFORM=
+       // JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM;
+       // private static final String PREF_PB_UNREACHABLE_CODE=
+       // JavaCore.COMPILER_PB_UNREACHABLE_CODE;
+       // private static final String PREF_PB_INVALID_IMPORT=
+       // JavaCore.COMPILER_PB_INVALID_IMPORT;
+       // private static final String PREF_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD=
+       // JavaCore.COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD;
+       // private static final String PREF_PB_METHOD_WITH_CONSTRUCTOR_NAME=
+       // JavaCore.COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME;
+       // private static final String PREF_PB_DEPRECATION=
+       // JavaCore.COMPILER_PB_DEPRECATION;
+       // private static final String PREF_PB_DEPRECATION_WHEN_OVERRIDING=
+       // JavaCore.COMPILER_PB_DEPRECATION_WHEN_OVERRIDING_DEPRECATED_METHOD;
+
+       // private static final String PREF_PB_HIDDEN_CATCH_BLOCK=
+       // JavaCore.COMPILER_PB_HIDDEN_CATCH_BLOCK;
+       // private static final String PREF_PB_UNUSED_LOCAL=
+       // JavaCore.COMPILER_PB_UNUSED_LOCAL;
+       // private static final String PREF_PB_UNUSED_PARAMETER=
+       // JavaCore.COMPILER_PB_UNUSED_PARAMETER;
+       // private static final String PREF_PB_SIGNAL_PARAMETER_IN_OVERRIDING=
+       // JavaCore.COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE;
+       // private static final String PREF_PB_SIGNAL_PARAMETER_IN_ABSTRACT=
+       // JavaCore.COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT;
+       // private static final String PREF_PB_SYNTHETIC_ACCESS_EMULATION=
+       // JavaCore.COMPILER_PB_SYNTHETIC_ACCESS_EMULATION;
+       // private static final String PREF_PB_NON_EXTERNALIZED_STRINGS=
+       // JavaCore.COMPILER_PB_NON_NLS_STRING_LITERAL;
+       // private static final String PREF_PB_ASSERT_AS_IDENTIFIER=
+       // JavaCore.COMPILER_PB_ASSERT_IDENTIFIER;
+       private static final String PREF_PB_MAX_PER_UNIT = JavaCore.COMPILER_PB_MAX_PER_UNIT;
+
+       // private static final String PREF_PB_UNUSED_IMPORT=
+       // JavaCore.COMPILER_PB_UNUSED_IMPORT;
+       // private static final String PREF_PB_UNUSED_PRIVATE=
+       // JavaCore.COMPILER_PB_UNUSED_PRIVATE_MEMBER;
+       // private static final String PREF_PB_STATIC_ACCESS_RECEIVER=
+       // JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER;
+       // private static final String PREF_PB_NO_EFFECT_ASSIGNMENT=
+       // JavaCore.COMPILER_PB_NO_EFFECT_ASSIGNMENT;
+       // private static final String PREF_PB_CHAR_ARRAY_IN_CONCAT=
+       // JavaCore.COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION;
+       // private static final String
+       // PREF_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT=
+       // JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT;
+       // private static final String PREF_PB_LOCAL_VARIABLE_HIDING=
+       // JavaCore.COMPILER_PB_LOCAL_VARIABLE_HIDING;
+       // private static final String PREF_PB_FIELD_HIDING=
+       // JavaCore.COMPILER_PB_FIELD_HIDING;
+       // private static final String PREF_PB_SPECIAL_PARAMETER_HIDING_FIELD=
+       // JavaCore.COMPILER_PB_SPECIAL_PARAMETER_HIDING_FIELD;
+       // private static final String PREF_PB_INDIRECT_STATIC_ACCESS=
+       // JavaCore.COMPILER_PB_INDIRECT_STATIC_ACCESS;
+       // private static final String PREF_PB_SUPERFLUOUS_SEMICOLON=
+       // JavaCore.COMPILER_PB_SUPERFLUOUS_SEMICOLON;
+       // private static final String PREF_PB_UNNECESSARY_TYPE_CHECK=
+       // JavaCore.COMPILER_PB_UNNECESSARY_TYPE_CHECK;
+
+       // private static final String PREF_PB_INVALID_JAVADOC=
+       // JavaCore.COMPILER_PB_INVALID_JAVADOC;
+       // private static final String PREF_PB_INVALID_JAVADOC_TAGS=
+       // JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS;
+       // private static final String PREF_PB_INVALID_JAVADOC_TAGS_VISIBILITY=
+       // JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS_VISIBILITY;
+       //
+       // private static final String PREF_PB_MISSING_JAVADOC_TAGS=
+       // JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS;
+       // private static final String PREF_PB_MISSING_JAVADOC_TAGS_VISIBILITY=
+       // JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_VISIBILITY;
+       // private static final String PREF_PB_MISSING_JAVADOC_TAGS_OVERRIDING=
+       // JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_OVERRIDING;
+       //
+       // private static final String PREF_PB_MISSING_JAVADOC_COMMENTS=
+       // JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS;
+       // private static final String PREF_PB_MISSING_JAVADOC_COMMENTS_VISIBILITY=
+       // JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS_VISIBILITY;
+       // private static final String PREF_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING=
+       // JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING;
+       //      
+       // private static final String PREF_SOURCE_COMPATIBILITY=
+       // JavaCore.COMPILER_SOURCE;
+       // private static final String PREF_COMPLIANCE=
+       // JavaCore.COMPILER_COMPLIANCE;
+       //
+       // private static final String PREF_RESOURCE_FILTER=
+       // JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER;
+       // private static final String PREF_BUILD_INVALID_CLASSPATH=
+       // JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH;
+       // private static final String PREF_BUILD_CLEAN_OUTPUT_FOLDER=
+       // JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER;
+       // private static final String PREF_ENABLE_EXCLUSION_PATTERNS=
+       // JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS;
+       // private static final String PREF_ENABLE_MULTIPLE_OUTPUT_LOCATIONS=
+       // JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS;
+       //
+       // private static final String PREF_PB_INCOMPLETE_BUILDPATH=
+       // JavaCore.CORE_INCOMPLETE_CLASSPATH;
+       // private static final String PREF_PB_CIRCULAR_BUILDPATH=
+       // JavaCore.CORE_CIRCULAR_CLASSPATH;
+       // // private static final String PREF_PB_INCOMPATIBLE_JDK_LEVEL=
+       // JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL;
+       // private static final String PREF_PB_DEPRECATION_IN_DEPRECATED_CODE=
+       // JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE;
+       // private static final String PREF_PB_DUPLICATE_RESOURCE=
+       // JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE;
+       // private static final String PREF_PB_INCOMPATIBLE_INTERFACE_METHOD=
+       // JavaCore.COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD;
+
+       // private static final String PREF_PB_UNDOCUMENTED_EMPTY_BLOCK=
+       // JavaCore.COMPILER_PB_UNDOCUMENTED_EMPTY_BLOCK;
+       // private static final String PREF_PB_FINALLY_BLOCK_NOT_COMPLETING=
+       // JavaCore.COMPILER_PB_FINALLY_BLOCK_NOT_COMPLETING;
+       // private static final String PREF_PB_UNUSED_DECLARED_THROWN_EXCEPTION=
+       // JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION;
+       // private static final String
+       // PREF_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING=
+       // JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING;
+       // private static final String PREF_PB_UNQUALIFIED_FIELD_ACCESS=
+       // JavaCore.COMPILER_PB_UNQUALIFIED_FIELD_ACCESS;
+
+       // private static final String INTR_DEFAULT_COMPLIANCE=
+       // "internal.default.compliance"; //$NON-NLS-1$
+
+       // values
+       private static final String GENERATE = JavaCore.GENERATE;
+
+       private static final String DO_NOT_GENERATE = JavaCore.DO_NOT_GENERATE;
+
+       private static final String PRESERVE = JavaCore.PRESERVE;
+
+       private static final String OPTIMIZE_OUT = JavaCore.OPTIMIZE_OUT;
+
+       private static final String VERSION_1_1 = JavaCore.VERSION_1_1;
+
+       private static final String VERSION_1_2 = JavaCore.VERSION_1_2;
+
+       private static final String VERSION_1_3 = JavaCore.VERSION_1_3;
+
+       private static final String VERSION_1_4 = JavaCore.VERSION_1_4;
+
+       private static final String ERROR = JavaCore.ERROR;
+
+       private static final String WARNING = JavaCore.WARNING;
+
+       private static final String IGNORE = JavaCore.IGNORE;
+
+       private static final String ABORT = JavaCore.ABORT;
+
+       private static final String CLEAN = JavaCore.CLEAN;
+
+       private static final String ENABLED = JavaCore.ENABLED;
+
+       private static final String DISABLED = JavaCore.DISABLED;
+
+       // private static final String PUBLIC= JavaCore.PUBLIC;
+       // private static final String PROTECTED= JavaCore.PROTECTED;
+       // private static final String DEFAULT= JavaCore.DEFAULT;
+       // private static final String PRIVATE= JavaCore.PRIVATE;
+
+       private static final String DEFAULT_CONF = "default"; //$NON-NLS-1$
+
+       private static final String USER_CONF = "user"; //$NON-NLS-1$
+
+       private ArrayList fComplianceControls;
+
+       private PixelConverter fPixelConverter;
+
+       private IStatus fMaxNumberProblemsStatus;
+
+       // private IStatus fComplianceStatus, fMaxNumberProblemsStatus,
+       // fResourceFilterStatus;
+
+       public CompilerConfigurationBlock(IStatusChangeListener context,
+                       IJavaProject project) {
+               super(context, project, getKeys());
+
+               fComplianceControls = new ArrayList();
+
+               // fComplianceStatus= new StatusInfo();
+               fMaxNumberProblemsStatus = new StatusInfo();
+               // fResourceFilterStatus= new StatusInfo();
+
+               // compatibilty code for the merge of the two option
+               // PB_SIGNAL_PARAMETER:
+               // if
+               // (ENABLED.equals(fWorkingValues.get(PREF_PB_SIGNAL_PARAMETER_IN_ABSTRACT)))
+               // {
+               // fWorkingValues.put(PREF_PB_SIGNAL_PARAMETER_IN_OVERRIDING, ENABLED);
+               // }
+
+       }
+
+       private final static String[] KEYS = new String[] {
+                       PREF_PB_PHP_FILE_NOT_EXIST, PREF_PB_PHP_VAR_DEPRECATED,
+                       PREF_PB_PHP_KEYWORD, PREF_PB_PHP_UPPERCASE_IDENTIFIER,
+                       PREF_PB_UNREACHABLE_CODE, PREF_PB_UNINITIALIZED_LOCAL_VARIABLE,
+                       // PREF_LOCAL_VARIABLE_ATTR,
+                       // PREF_LINE_NUMBER_ATTR, PREF_SOURCE_FILE_ATTR,
+                       // PREF_CODEGEN_UNUSED_LOCAL,
+                       // PREF_CODEGEN_TARGET_PLATFORM,
+                       // PREF_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD,
+                       // PREF_PB_METHOD_WITH_CONSTRUCTOR_NAME,
+                       // PREF_PB_DEPRECATION,
+                       // PREF_PB_HIDDEN_CATCH_BLOCK, PREF_PB_UNUSED_LOCAL,
+                       // PREF_PB_UNUSED_PARAMETER,
+                       // PREF_PB_SYNTHETIC_ACCESS_EMULATION,
+                       // PREF_PB_NON_EXTERNALIZED_STRINGS,
+                       // PREF_PB_ASSERT_AS_IDENTIFIER,
+                       // PREF_PB_UNUSED_IMPORT,
+                       PREF_PB_MAX_PER_UNIT,
+       // PREF_SOURCE_COMPATIBILITY,
+       // PREF_COMPLIANCE,
+       // PREF_RESOURCE_FILTER, PREF_BUILD_INVALID_CLASSPATH,
+       // PREF_PB_STATIC_ACCESS_RECEIVER, PREF_PB_INCOMPLETE_BUILDPATH,
+       // PREF_PB_CIRCULAR_BUILDPATH, PREF_PB_DEPRECATION_IN_DEPRECATED_CODE,
+       // PREF_BUILD_CLEAN_OUTPUT_FOLDER,
+       // PREF_PB_DUPLICATE_RESOURCE, PREF_PB_NO_EFFECT_ASSIGNMENT,
+       // PREF_PB_INCOMPATIBLE_INTERFACE_METHOD,
+       // PREF_PB_UNUSED_PRIVATE, PREF_PB_CHAR_ARRAY_IN_CONCAT,
+       // PREF_ENABLE_EXCLUSION_PATTERNS, PREF_ENABLE_MULTIPLE_OUTPUT_LOCATIONS,
+       // PREF_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT,
+       // PREF_PB_LOCAL_VARIABLE_HIDING,
+       // PREF_PB_FIELD_HIDING,
+       // PREF_PB_SPECIAL_PARAMETER_HIDING_FIELD,
+       // PREF_PB_INCOMPATIBLE_JDK_LEVEL,
+       // PREF_PB_INDIRECT_STATIC_ACCESS,
+       // PREF_PB_SUPERFLUOUS_SEMICOLON,
+       // PREF_PB_SIGNAL_PARAMETER_IN_OVERRIDING,
+       // PREF_PB_SIGNAL_PARAMETER_IN_ABSTRACT,
+       // PREF_PB_UNNECESSARY_TYPE_CHECK,
+       // PREF_PB_UNUSED_DECLARED_THROWN_EXCEPTION,
+       // PREF_PB_UNQUALIFIED_FIELD_ACCESS,
+       // PREF_PB_UNDOCUMENTED_EMPTY_BLOCK,
+       // PREF_PB_FINALLY_BLOCK_NOT_COMPLETING,
+       // PREF_PB_DEPRECATION_WHEN_OVERRIDING,
+       // PREF_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING,
+
+       // PREF_PB_INVALID_JAVADOC,
+       // PREF_PB_INVALID_JAVADOC_TAGS_VISIBILITY,
+       // PREF_PB_INVALID_JAVADOC_TAGS_VISIBILITY,
+       // PREF_PB_MISSING_JAVADOC_TAGS,
+       // PREF_PB_MISSING_JAVADOC_TAGS_VISIBILITY,
+       // PREF_PB_MISSING_JAVADOC_TAGS_OVERRIDING,
+       // PREF_PB_MISSING_JAVADOC_COMMENTS,
+       // PREF_PB_MISSING_JAVADOC_COMMENTS_VISIBILITY,
+       // PREF_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING
+       };
+
+       private static String[] getKeys() {
+               return KEYS;
+       }
+
+       protected final Map getOptions(boolean inheritJavaCoreOptions) {
+               Map map = super.getOptions(inheritJavaCoreOptions);
+               // map.put(INTR_DEFAULT_COMPLIANCE, getCurrentCompliance(map));
+               return map;
+       }
+
+       protected final Map getDefaultOptions() {
+               Map map = super.getDefaultOptions();
+               // map.put(INTR_DEFAULT_COMPLIANCE, getCurrentCompliance(map));
+               return map;
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+               fPixelConverter = new PixelConverter(parent);
+               setShell(parent.getShell());
+
+               TabFolder folder = new TabFolder(parent, SWT.NONE);
+               folder.setLayout(new TabFolderLayout());
+               folder.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+               Composite commonComposite = createStyleTabContent(folder);
+               // Composite unusedComposite= createUnusedCodeTabContent(folder);
+               Composite advancedComposite = createAdvancedTabContent(folder);
+               // Composite javadocComposite= createJavadocTabContent(folder);
+               // Composite complianceComposite= createComplianceTabContent(folder);
+               // Composite othersComposite= createBuildPathTabContent(folder);
+
+               TabItem item = new TabItem(folder, SWT.NONE);
+               item.setText(PreferencesMessages
+                               .getString("CompilerConfigurationBlock.common.tabtitle")); //$NON-NLS-1$
+               item.setControl(commonComposite);
+
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(PreferencesMessages
+                               .getString("CompilerConfigurationBlock.advanced.tabtitle")); //$NON-NLS-1$
+               item.setControl(advancedComposite);
+
+               // item= new TabItem(folder, SWT.NONE);
+               // item.setText(PreferencesMessages.getString("CompilerConfigurationBlock.unused.tabtitle"));
+               // //$NON-NLS-1$
+               // item.setControl(unusedComposite);
+
+               // item= new TabItem(folder, SWT.NONE);
+               // item.setText(PreferencesMessages.getString("CompilerConfigurationBlock.javadoc.tabtitle"));
+               // //$NON-NLS-1$
+               // item.setControl(javadocComposite);
+
+               // item= new TabItem(folder, SWT.NONE);
+               // item.setText(PreferencesMessages.getString("CompilerConfigurationBlock.compliance.tabtitle"));
+               // //$NON-NLS-1$
+               // item.setControl(complianceComposite);
+
+               // item= new TabItem(folder, SWT.NONE);
+               // item.setText(PreferencesMessages.getString("CompilerConfigurationBlock.others.tabtitle"));
+               // //$NON-NLS-1$
+               // item.setControl(othersComposite);
+
+               validateSettings(null, null);
+
+               return folder;
+       }
+
+       private Composite createStyleTabContent(Composite folder) {
+               String[] errorWarningIgnore = new String[] { ERROR, WARNING, IGNORE };
+
+               String[] errorWarningIgnoreLabels = new String[] {
+                               PreferencesMessages
+                                               .getString("CompilerConfigurationBlock.error"), //$NON-NLS-1$
+                               PreferencesMessages
+                                               .getString("CompilerConfigurationBlock.warning"), //$NON-NLS-1$
+                               PreferencesMessages
+                                               .getString("CompilerConfigurationBlock.ignore") //$NON-NLS-1$
+               };
+
+               int nColumns = 3;
+
+               GridLayout layout = new GridLayout();
+               layout.numColumns = nColumns;
+
+               Composite composite = new Composite(folder, SWT.NULL);
+               composite.setLayout(layout);
+
+               Label description = new Label(composite, SWT.WRAP);
+               description.setText(PreferencesMessages
+                               .getString("CompilerConfigurationBlock.common.description")); //$NON-NLS-1$
+               GridData gd = new GridData();
+               gd.horizontalSpan = nColumns;
+               gd.widthHint = fPixelConverter.convertWidthInCharsToPixels(50);
+               description.setLayoutData(gd);
+
+               String label = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.pb_file_not_exist.label"); //$NON-NLS-1$
+               addComboBox(composite, label, PREF_PB_PHP_FILE_NOT_EXIST,
+                               errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               label = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.pb_var_deprecated.label"); //$NON-NLS-1$
+               addComboBox(composite, label, PREF_PB_PHP_VAR_DEPRECATED,
+                               errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               label = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.pb_keyword.label"); //$NON-NLS-1$
+               addComboBox(composite, label, PREF_PB_PHP_KEYWORD, errorWarningIgnore,
+                               errorWarningIgnoreLabels, 0);
+
+               label = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.pb_uppercase_identifier.label"); //$NON-NLS-1$
+               addComboBox(composite, label, PREF_PB_PHP_UPPERCASE_IDENTIFIER,
+                               errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               label = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.pb_unreachable_code.label"); //$NON-NLS-1$
+               addComboBox(composite, label, PREF_PB_UNREACHABLE_CODE,
+                               errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               label = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.pb_unitialized_local_variable.label"); //$NON-NLS-1$
+               addComboBox(composite, label, PREF_PB_UNINITIALIZED_LOCAL_VARIABLE,
+                               errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               label = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.pb_overriding_pkg_dflt.label"); //$NON-NLS-1$
+               // addComboBox(composite, label,
+               // PREF_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD, errorWarningIgnore,
+               // errorWarningIgnoreLabels, 0);
+
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_method_naming.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_METHOD_WITH_CONSTRUCTOR_NAME,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+               //
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_hidden_catchblock.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_HIDDEN_CATCH_BLOCK,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+               //              
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_static_access_receiver.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_STATIC_ACCESS_RECEIVER,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+               //              
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_no_effect_assignment.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_NO_EFFECT_ASSIGNMENT,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_indirect_access_to_static.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_INDIRECT_STATIC_ACCESS,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+               //
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_accidential_assignement.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label,
+               // PREF_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT, errorWarningIgnore,
+               // errorWarningIgnoreLabels, 0);
+               //
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_finally_block_not_completing.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_FINALLY_BLOCK_NOT_COMPLETING,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+               //
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_undocumented_empty_block.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_UNDOCUMENTED_EMPTY_BLOCK,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               return composite;
+       }
+
+       private Composite createAdvancedTabContent(TabFolder folder) {
+               String[] errorWarningIgnore = new String[] { ERROR, WARNING, IGNORE };
+
+               String[] errorWarningIgnoreLabels = new String[] {
+                               PreferencesMessages
+                                               .getString("CompilerConfigurationBlock.error"), //$NON-NLS-1$
+                               PreferencesMessages
+                                               .getString("CompilerConfigurationBlock.warning"), //$NON-NLS-1$
+                               PreferencesMessages
+                                               .getString("CompilerConfigurationBlock.ignore") //$NON-NLS-1$
+               };
+
+               String[] enabledDisabled = new String[] { ENABLED, DISABLED };
+
+               int nColumns = 3;
+
+               GridLayout layout = new GridLayout();
+               layout.numColumns = nColumns;
+
+               Composite composite = new Composite(folder, SWT.NULL);
+               composite.setLayout(layout);
+
+               Label description = new Label(composite, SWT.WRAP);
+               description.setText(PreferencesMessages
+                               .getString("CompilerConfigurationBlock.advanced.description")); //$NON-NLS-1$
+               GridData gd = new GridData();
+               gd.horizontalSpan = nColumns;
+               gd.widthHint = fPixelConverter.convertWidthInCharsToPixels(50);
+               description.setLayoutData(gd);
+
+               // String label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_synth_access_emul.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_SYNTHETIC_ACCESS_EMULATION,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_local_variable_hiding.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_LOCAL_VARIABLE_HIDING,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               // int indent= fPixelConverter.convertWidthInCharsToPixels(2);
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_special_param_hiding.label");
+               // //$NON-NLS-1$
+               // addCheckBox(composite, label, PREF_PB_SPECIAL_PARAMETER_HIDING_FIELD,
+               // enabledDisabled, indent);
+
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_field_hiding.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_FIELD_HIDING,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_non_externalized_strings.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_NON_EXTERNALIZED_STRINGS,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+               //
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_incompatible_interface_method.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_INCOMPATIBLE_INTERFACE_METHOD,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+               //
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_char_array_in_concat.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_CHAR_ARRAY_IN_CONCAT,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               // label=
+               // PreferencesMessages.getString("CompilerConfigurationBlock.pb_unqualified_field_access.label");
+               // //$NON-NLS-1$
+               // addComboBox(composite, label, PREF_PB_UNQUALIFIED_FIELD_ACCESS,
+               // errorWarningIgnore, errorWarningIgnoreLabels, 0);
+
+               gd = new GridData();
+               gd.widthHint = fPixelConverter.convertWidthInCharsToPixels(6);
+
+               String label = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.pb_max_per_unit.label"); //$NON-NLS-1$
+               Text text = addTextField(composite, label, PREF_PB_MAX_PER_UNIT, 0, 0);
+               text.setTextLimit(6);
+               text.setLayoutData(gd);
+
+               return composite;
+       }
+
+       /*
+        * (non-javadoc) Update fields and validate. @param changedKey Key that
+        * changed, or null, if all changed.
+        */
+       protected void validateSettings(String changedKey, String newValue) {
+
+               if (changedKey != null) {
+                       // if (INTR_DEFAULT_COMPLIANCE.equals(changedKey)) {
+                       // updateComplianceEnableState();
+                       // if (DEFAULT_CONF.equals(newValue)) {
+                       // updateComplianceDefaultSettings();
+                       // }
+                       // fComplianceStatus= validateCompliance();
+                       // } else if (PREF_COMPLIANCE.equals(changedKey)) {
+                       // if (checkValue(INTR_DEFAULT_COMPLIANCE, DEFAULT_CONF)) {
+                       // updateComplianceDefaultSettings();
+                       // }
+                       // fComplianceStatus= validateCompliance();
+                       // } else if (PREF_SOURCE_COMPATIBILITY.equals(changedKey) ||
+                       // PREF_CODEGEN_TARGET_PLATFORM.equals(changedKey) ||
+                       // PREF_PB_ASSERT_AS_IDENTIFIER.equals(changedKey)) {
+                       // fComplianceStatus= validateCompliance();
+                       // } else
+                       if (PREF_PB_MAX_PER_UNIT.equals(changedKey)) {
+                               fMaxNumberProblemsStatus = validateMaxNumberProblems();
+                               // } else if (PREF_RESOURCE_FILTER.equals(changedKey)) {
+                               // fResourceFilterStatus= validateResourceFilters();
+                               // } else if (S.equals(changedKey) ||
+                               // PREF_PB_DEPRECATION.equals(changedKey) ) { // ||
+                               // // PREF_PB_INVALID_JAVADOC.equals(changedKey) ||
+                               // // PREF_PB_MISSING_JAVADOC_TAGS.equals(changedKey) ||
+                               // // PREF_PB_MISSING_JAVADOC_COMMENTS.equals(changedKey) ||
+                               // // PREF_PB_MISSING_JAVADOC_COMMENTS.equals(changedKey) ||
+                               // //
+                               // PREF_PB_UNUSED_DECLARED_THROWN_EXCEPTION.equals(changedKey))
+                               // {
+                               // updateEnableStates();
+                               // } else if
+                               // (PREF_PB_SIGNAL_PARAMETER_IN_OVERRIDING.equals(changedKey)) {
+                               // // merging the two options
+                               // fWorkingValues.put(PREF_PB_SIGNAL_PARAMETER_IN_ABSTRACT,
+                               // newValue);
+                       } else {
+                               return;
+                       }
+               } else {
+                       // updateEnableStates();
+                       // updateComplianceEnableState();
+                       // fComplianceStatus= validateCompliance();
+                       fMaxNumberProblemsStatus = validateMaxNumberProblems();
+                       // fResourceFilterStatus= validateResourceFilters();
+               }
+               // IStatus status= StatusUtil.getMostSevere(new IStatus[] {
+               // fComplianceStatus, fMaxNumberProblemsStatus, fResourceFilterStatus
+               // });
+               IStatus status = StatusUtil
+                               .getMostSevere(new IStatus[] { fMaxNumberProblemsStatus });
+               fContext.statusChanged(status);
+       }
+
+       // private void updateEnableStates() {
+       // boolean enableUnusedParams= !checkValue(PREF_PB_UNUSED_PARAMETER,
+       // IGNORE);
+       // getCheckBox(PREF_PB_SIGNAL_PARAMETER_IN_OVERRIDING).setEnabled(enableUnusedParams);
+
+       // boolean enableDeprecation= !checkValue(PREF_PB_DEPRECATION, IGNORE);
+       // getCheckBox(PREF_PB_DEPRECATION_IN_DEPRECATED_CODE).setEnabled(enableDeprecation);
+       // getCheckBox(PREF_PB_DEPRECATION_WHEN_OVERRIDING).setEnabled(enableDeprecation);
+       //              
+       // boolean enableThrownExceptions=
+       // !checkValue(PREF_PB_UNUSED_DECLARED_THROWN_EXCEPTION, IGNORE);
+       // getCheckBox(PREF_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING).setEnabled(enableThrownExceptions);
+       //
+       // boolean enableHiding= !checkValue(PREF_PB_LOCAL_VARIABLE_HIDING, IGNORE);
+       // getCheckBox(PREF_PB_SPECIAL_PARAMETER_HIDING_FIELD).setEnabled(enableHiding);
+       //
+       // boolean enableInvalidTagsErrors= !checkValue(PREF_PB_INVALID_JAVADOC,
+       // IGNORE);
+       // getCheckBox(PREF_PB_INVALID_JAVADOC_TAGS).setEnabled(enableInvalidTagsErrors);
+       // setComboEnabled(PREF_PB_INVALID_JAVADOC_TAGS_VISIBILITY,
+       // enableInvalidTagsErrors);
+       //              
+       // boolean enableMissingTagsErrors=
+       // !checkValue(PREF_PB_MISSING_JAVADOC_TAGS, IGNORE);
+       // getCheckBox(PREF_PB_MISSING_JAVADOC_TAGS_OVERRIDING).setEnabled(enableMissingTagsErrors);
+       // setComboEnabled(PREF_PB_MISSING_JAVADOC_TAGS_VISIBILITY,
+       // enableMissingTagsErrors);
+       //              
+       // boolean enableMissingCommentsErrors=
+       // !checkValue(PREF_PB_MISSING_JAVADOC_COMMENTS, IGNORE);
+       // getCheckBox(PREF_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING).setEnabled(enableMissingCommentsErrors);
+       // setComboEnabled(PREF_PB_MISSING_JAVADOC_COMMENTS_VISIBILITY,
+       // enableMissingCommentsErrors);
+       // }
+
+       // private IStatus validateCompliance() {
+       // StatusInfo status= new StatusInfo();
+       // if (checkValue(PREF_COMPLIANCE, VERSION_1_3)) {
+       // if (checkValue(PREF_SOURCE_COMPATIBILITY, VERSION_1_4)) {
+       // status.setError(PreferencesMessages.getString("CompilerConfigurationBlock.cpl13src14.error"));
+       // //$NON-NLS-1$
+       // return status;
+       // } else if (checkValue(PREF_CODEGEN_TARGET_PLATFORM, VERSION_1_4)) {
+       // status.setError(PreferencesMessages.getString("CompilerConfigurationBlock.cpl13trg14.error"));
+       // //$NON-NLS-1$
+       // return status;
+       // }
+       // }
+       // if (checkValue(PREF_SOURCE_COMPATIBILITY, VERSION_1_4)) {
+       // if (!checkValue(PREF_PB_ASSERT_AS_IDENTIFIER, ERROR)) {
+       // status.setError(PreferencesMessages.getString("CompilerConfigurationBlock.src14asrterr.error"));
+       // //$NON-NLS-1$
+       // return status;
+       // }
+       // }
+       // if (checkValue(PREF_SOURCE_COMPATIBILITY, VERSION_1_4)) {
+       // if (!checkValue(PREF_CODEGEN_TARGET_PLATFORM, VERSION_1_4)) {
+       // status.setError(PreferencesMessages.getString("CompilerConfigurationBlock.src14tgt14.error"));
+       // //$NON-NLS-1$
+       // return status;
+       // }
+       // }
+       // return status;
+       // }
+
+       private IStatus validateMaxNumberProblems() {
+               String number = (String) fWorkingValues.get(PREF_PB_MAX_PER_UNIT);
+               StatusInfo status = new StatusInfo();
+               if (number.length() == 0) {
+                       status.setError(PreferencesMessages
+                                       .getString("CompilerConfigurationBlock.empty_input")); //$NON-NLS-1$
+               } else {
+                       try {
+                               int value = Integer.parseInt(number);
+                               if (value <= 0) {
+                                       status
+                                                       .setError(PreferencesMessages
+                                                                       .getFormattedString(
+                                                                                       "CompilerConfigurationBlock.invalid_input", number)); //$NON-NLS-1$
+                               }
+                       } catch (NumberFormatException e) {
+                               status.setError(PreferencesMessages.getFormattedString(
+                                               "CompilerConfigurationBlock.invalid_input", number)); //$NON-NLS-1$
+                       }
+               }
+               return status;
+       }
+
+       // private IStatus validateResourceFilters() {
+       // String text= (String) fWorkingValues.get(PREF_RESOURCE_FILTER);
+       //              
+       // IWorkspace workspace= ResourcesPlugin.getWorkspace();
+       //
+       // String[] filters= getTokens(text, ","); //$NON-NLS-1$
+       // for (int i= 0; i < filters.length; i++) {
+       // String fileName= filters[i].replace('*', 'x');
+       // int resourceType= IResource.FILE;
+       // int lastCharacter= fileName.length() - 1;
+       // if (lastCharacter >= 0 && fileName.charAt(lastCharacter) == '/') {
+       // fileName= fileName.substring(0, lastCharacter);
+       // resourceType= IResource.FOLDER;
+       // }
+       // IStatus status= workspace.validateName(fileName, resourceType);
+       // if (status.matches(IStatus.ERROR)) {
+       // String message=
+       // PreferencesMessages.getFormattedString("CompilerConfigurationBlock.filter.invalidsegment.error",
+       // status.getMessage()); //$NON-NLS-1$
+       // return new StatusInfo(IStatus.ERROR, message);
+       // }
+       // }
+       // return new StatusInfo();
+       // }
+
+       protected String[] getFullBuildDialogStrings(boolean workspaceSettings) {
+               String title = PreferencesMessages
+                               .getString("CompilerConfigurationBlock.needsbuild.title"); //$NON-NLS-1$
+               String message;
+               if (workspaceSettings) {
+                       message = PreferencesMessages
+                                       .getString("CompilerConfigurationBlock.needsfullbuild.message"); //$NON-NLS-1$
+               } else {
+                       message = PreferencesMessages
+                                       .getString("CompilerConfigurationBlock.needsprojectbuild.message"); //$NON-NLS-1$
+               }
+               return new String[] { title, message };
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerPreferencePage.java
new file mode 100644 (file)
index 0000000..5137ae2
--- /dev/null
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/*
+ * The page to configure the compiler options.
+ */
+public class CompilerPreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage, IStatusChangeListener {
+
+       private CompilerConfigurationBlock fConfigurationBlock;
+
+       public CompilerPreferencePage() {
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+               setDescription(PreferencesMessages
+                               .getString("CompilerPreferencePage.description")); //$NON-NLS-1$
+
+               // only used when page is shown programatically
+               setTitle(PreferencesMessages.getString("CompilerPreferencePage.title")); //$NON-NLS-1$
+
+               fConfigurationBlock = new CompilerConfigurationBlock(this, null);
+       }
+
+       /*
+        * @see IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+        */
+       public void init(IWorkbench workbench) {
+       }
+
+       /*
+        * @see PreferencePage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.COMPILER_PREFERENCE_PAGE);
+       }
+
+       /*
+        * @see PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+               Control result = fConfigurationBlock.createContents(parent);
+               Dialog.applyDialogFont(result);
+               return result;
+       }
+
+       /*
+        * @see IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               if (!fConfigurationBlock.performOk(true)) {
+                       return false;
+               }
+               return super.performOk();
+       }
+
+       /*
+        * @see PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               fConfigurationBlock.performDefaults();
+               super.performDefaults();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener#statusChanged(org.eclipse.core.runtime.IStatus)
+        */
+       public void statusChanged(IStatus status) {
+               setValid(!status.matches(IStatus.ERROR));
+               StatusUtil.applyToStatusLine(this, status);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerPropertyPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/CompilerPropertyPage.java
new file mode 100644 (file)
index 0000000..377710b
--- /dev/null
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ControlEnableState;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.preference.PreferenceNode;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+/**
+ * Property page used to configure project specific compiler settings
+ */
+public class CompilerPropertyPage extends PropertyPage {
+
+       private CompilerConfigurationBlock fConfigurationBlock;
+
+       private Control fConfigurationBlockControl;
+
+       private ControlEnableState fBlockEnableState;
+
+       private SelectionButtonDialogField fUseWorkspaceSettings;
+
+       private SelectionButtonDialogField fChangeWorkspaceSettings;
+
+       private SelectionButtonDialogField fUseProjectSettings;
+
+       private IStatus fBlockStatus;
+
+       public CompilerPropertyPage() {
+               fBlockStatus = new StatusInfo();
+               fBlockEnableState = null;
+
+               IDialogFieldListener listener = new IDialogFieldListener() {
+                       public void dialogFieldChanged(DialogField field) {
+                               doDialogFieldChanged(field);
+                       }
+               };
+
+               fUseWorkspaceSettings = new SelectionButtonDialogField(SWT.RADIO);
+               fUseWorkspaceSettings.setDialogFieldListener(listener);
+               fUseWorkspaceSettings.setLabelText(PreferencesMessages
+                               .getString("CompilerPropertyPage.useworkspacesettings.label")); //$NON-NLS-1$
+
+               fChangeWorkspaceSettings = new SelectionButtonDialogField(SWT.PUSH);
+               fChangeWorkspaceSettings.setLabelText(PreferencesMessages
+                               .getString("CompilerPropertyPage.useworkspacesettings.change")); //$NON-NLS-1$
+               fChangeWorkspaceSettings.setDialogFieldListener(listener);
+
+               fUseWorkspaceSettings.attachDialogField(fChangeWorkspaceSettings);
+
+               fUseProjectSettings = new SelectionButtonDialogField(SWT.RADIO);
+               fUseProjectSettings.setDialogFieldListener(listener);
+               fUseProjectSettings.setLabelText(PreferencesMessages
+                               .getString("CompilerPropertyPage.useprojectsettings.label")); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.COMPILER_PROPERTY_PAGE);
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+               IStatusChangeListener listener = new IStatusChangeListener() {
+                       public void statusChanged(IStatus status) {
+                               fBlockStatus = status;
+                               doStatusChanged();
+                       }
+               };
+               fConfigurationBlock = new CompilerConfigurationBlock(listener,
+                               getProject());
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               composite.setLayout(layout);
+
+               fUseWorkspaceSettings.doFillIntoGrid(composite, 1);
+               LayoutUtil.setHorizontalGrabbing(fUseWorkspaceSettings
+                               .getSelectionButton(null));
+
+               fChangeWorkspaceSettings.doFillIntoGrid(composite, 1);
+
+               fUseProjectSettings.doFillIntoGrid(composite, 2);
+
+               GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.VERTICAL_ALIGN_FILL);
+               data.horizontalSpan = 2;
+
+               fConfigurationBlockControl = fConfigurationBlock
+                               .createContents(composite);
+               fConfigurationBlockControl.setLayoutData(data);
+
+               boolean useProjectSettings = fConfigurationBlock
+                               .hasProjectSpecificOptions();
+
+               fUseProjectSettings.setSelection(useProjectSettings);
+               fUseWorkspaceSettings.setSelection(!useProjectSettings);
+
+               updateEnableState();
+               Dialog.applyDialogFont(composite);
+               return composite;
+       }
+
+       private boolean useProjectSettings() {
+               return fUseProjectSettings.isSelected();
+       }
+
+       private void doDialogFieldChanged(DialogField field) {
+               if (field == fChangeWorkspaceSettings) {
+                       String id = "net.sourceforge.phpdt.ui.preferences.CompilerPreferencePage"; //$NON-NLS-1$
+                       CompilerPreferencePage page = new CompilerPreferencePage();
+                       showPreferencePage(id, page);
+               } else {
+                       updateEnableState();
+                       doStatusChanged();
+               }
+       }
+
+       /**
+        * Method statusChanged.
+        */
+       private void doStatusChanged() {
+               updateStatus(useProjectSettings() ? fBlockStatus : new StatusInfo());
+       }
+
+       /**
+        * Method getProject.
+        */
+       private IJavaProject getProject() {
+               return (IJavaProject) getElement().getAdapter(IJavaElement.class);
+       }
+
+       private void updateEnableState() {
+               if (useProjectSettings()) {
+                       if (fBlockEnableState != null) {
+                               fBlockEnableState.restore();
+                               fBlockEnableState = null;
+                       }
+               } else {
+                       if (fBlockEnableState == null) {
+                               fBlockEnableState = ControlEnableState
+                                               .disable(fConfigurationBlockControl);
+                       }
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               if (useProjectSettings()) {
+                       fUseProjectSettings.setSelection(false);
+                       fUseWorkspaceSettings.setSelection(true);
+                       fConfigurationBlock.performDefaults();
+               }
+               super.performDefaults();
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               return fConfigurationBlock.performOk(useProjectSettings());
+       }
+
+       private void updateStatus(IStatus status) {
+               setValid(!status.matches(IStatus.ERROR));
+               StatusUtil.applyToStatusLine(this, status);
+       }
+
+       private boolean showPreferencePage(String id, IPreferencePage page) {
+               final IPreferenceNode targetNode = new PreferenceNode(id, page);
+
+               PreferenceManager manager = new PreferenceManager();
+               manager.addToRoot(targetNode);
+               final PreferenceDialog dialog = new PreferenceDialog(getControl()
+                               .getShell(), manager);
+               final boolean[] result = new boolean[] { false };
+               BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
+                       public void run() {
+                               dialog.create();
+                               dialog.setMessage(targetNode.getLabelText());
+                               result[0] = (dialog.open() == Window.OK);
+                       }
+               });
+               return result[0];
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditTemplateDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditTemplateDialog.java
new file mode 100644 (file)
index 0000000..e0b3d24
--- /dev/null
@@ -0,0 +1,638 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusDialog;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextEvent;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.templates.ContextTypeRegistry;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyEvent;
+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.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * Dialog to edit a template.
+ */
+public class EditTemplateDialog extends StatusDialog {
+
+       private static class TextViewerAction extends Action implements IUpdate {
+
+               private int fOperationCode = -1;
+
+               private ITextOperationTarget fOperationTarget;
+
+               /**
+                * Creates a new action.
+                * 
+                * @param viewer
+                *            the viewer
+                * @param operationCode
+                *            the opcode
+                */
+               public TextViewerAction(ITextViewer viewer, int operationCode) {
+                       fOperationCode = operationCode;
+                       fOperationTarget = viewer.getTextOperationTarget();
+                       update();
+               }
+
+               /**
+                * Updates the enabled state of the action. Fires a property change if
+                * the enabled state changes.
+                * 
+                * @see Action#firePropertyChange(String, Object, Object)
+                */
+               public void update() {
+
+                       boolean wasEnabled = isEnabled();
+                       boolean isEnabled = (fOperationTarget != null && fOperationTarget
+                                       .canDoOperation(fOperationCode));
+                       setEnabled(isEnabled);
+
+                       if (wasEnabled != isEnabled) {
+                               firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE
+                                               : Boolean.FALSE, isEnabled ? Boolean.TRUE
+                                               : Boolean.FALSE);
+                       }
+               }
+
+               /**
+                * @see Action#run()
+                */
+               public void run() {
+                       if (fOperationCode != -1 && fOperationTarget != null) {
+                               fOperationTarget.doOperation(fOperationCode);
+                       }
+               }
+       }
+
+       private final Template fTemplate;
+
+       private Text fNameText;
+
+       private Text fDescriptionText;
+
+       private Combo fContextCombo;
+
+       private SourceViewer fPatternEditor;
+
+       private Button fInsertVariableButton;
+
+       private boolean fIsNameModifiable;
+
+       private StatusInfo fValidationStatus;
+
+       private boolean fSuppressError = true; // #4354
+
+       private Map fGlobalActions = new HashMap(10);
+
+       private List fSelectionActions = new ArrayList(3);
+
+       private String[][] fContextTypes;
+
+       private ContextTypeRegistry fContextTypeRegistry;
+
+       private final TemplateVariableProcessor fTemplateProcessor = new TemplateVariableProcessor();
+
+       /**
+        * Creates a new dialog.
+        * 
+        * @param parent
+        *            the shell parent of the dialog
+        * @param template
+        *            the template to edit
+        * @param edit
+        *            whether this is a new template or an existing being edited
+        * @param isNameModifiable
+        *            whether the name of the template may be modified
+        * @param registry
+        *            the context type registry to use
+        */
+       public EditTemplateDialog(Shell parent, Template template, boolean edit,
+                       boolean isNameModifiable, ContextTypeRegistry registry) {
+               super(parent);
+
+               setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
+
+               String title = edit ? PreferencesMessages
+                               .getString("EditTemplateDialog.title.edit") //$NON-NLS-1$
+                               : PreferencesMessages.getString("EditTemplateDialog.title.new"); //$NON-NLS-1$
+               setTitle(title);
+
+               fTemplate = template;
+               fIsNameModifiable = isNameModifiable;
+
+               // XXX workaround for bug 63313 - disabling prefix until fixed.
+               // String delim= new Document().getLegalLineDelimiters()[0];
+
+               List contexts = new ArrayList();
+               for (Iterator it = registry.contextTypes(); it.hasNext();) {
+                       TemplateContextType type = (TemplateContextType) it.next();
+                       // if (type.getId().equals("javadoc")) //$NON-NLS-1$
+                       // contexts.add(new String[] { type.getId(), type.getName(), "/**" +
+                       // delim }); //$NON-NLS-1$
+                       // else
+                       contexts.add(new String[] { type.getId(), type.getName(), "" }); //$NON-NLS-1$
+               }
+               fContextTypes = (String[][]) contexts.toArray(new String[contexts
+                               .size()][]);
+
+               fValidationStatus = new StatusInfo();
+
+               fContextTypeRegistry = registry;
+
+               TemplateContextType type = fContextTypeRegistry.getContextType(template
+                               .getContextTypeId());
+               fTemplateProcessor.setContextType(type);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.dialogs.StatusDialog#create()
+        */
+       public void create() {
+               super.create();
+               // update initial ok button to be disabled for new templates
+               boolean valid = fNameText == null
+                               || fNameText.getText().trim().length() != 0;
+               if (!valid) {
+                       StatusInfo status = new StatusInfo();
+                       status.setError(PreferencesMessages
+                                       .getString("EditTemplateDialog.error.noname")); //$NON-NLS-1$
+                       updateButtonsEnableState(status);
+               }
+       }
+
+       /*
+        * @see Dialog#createDialogArea(Composite)
+        */
+       protected Control createDialogArea(Composite ancestor) {
+               Composite parent = new Composite(ancestor, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               parent.setLayout(layout);
+               parent.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+               ModifyListener listener = new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               doTextWidgetChanged(e.widget);
+                       }
+               };
+
+               if (fIsNameModifiable) {
+                       createLabel(parent, PreferencesMessages
+                                       .getString("EditTemplateDialog.name")); //$NON-NLS-1$
+
+                       Composite composite = new Composite(parent, SWT.NONE);
+                       composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+                       layout = new GridLayout();
+                       layout.numColumns = 3;
+                       layout.marginWidth = 0;
+                       layout.marginHeight = 0;
+                       composite.setLayout(layout);
+
+                       fNameText = createText(composite);
+                       fNameText.addFocusListener(new FocusListener() {
+
+                               public void focusGained(FocusEvent e) {
+                               }
+
+                               public void focusLost(FocusEvent e) {
+                                       if (fSuppressError) {
+                                               fSuppressError = false;
+                                               updateButtons();
+                                       }
+                               }
+                       });
+
+                       createLabel(composite, PreferencesMessages
+                                       .getString("EditTemplateDialog.context")); //$NON-NLS-1$
+                       fContextCombo = new Combo(composite, SWT.READ_ONLY);
+
+                       for (int i = 0; i < fContextTypes.length; i++) {
+                               fContextCombo.add(fContextTypes[i][1]);
+                       }
+
+                       fContextCombo.addModifyListener(listener);
+               }
+
+               createLabel(parent, PreferencesMessages
+                               .getString("EditTemplateDialog.description")); //$NON-NLS-1$
+
+               int descFlags = fIsNameModifiable ? SWT.BORDER : SWT.BORDER
+                               | SWT.READ_ONLY;
+               fDescriptionText = new Text(parent, descFlags);
+               fDescriptionText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               fDescriptionText.addModifyListener(listener);
+
+               Label patternLabel = createLabel(parent, PreferencesMessages
+                               .getString("EditTemplateDialog.pattern")); //$NON-NLS-1$
+               patternLabel.setLayoutData(new GridData(
+                               GridData.VERTICAL_ALIGN_BEGINNING));
+               fPatternEditor = createEditor(parent);
+
+               Label filler = new Label(parent, SWT.NONE);
+               filler.setLayoutData(new GridData());
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               layout = new GridLayout();
+               layout.marginWidth = 0;
+               layout.marginHeight = 0;
+               composite.setLayout(layout);
+               composite.setLayoutData(new GridData());
+
+               fInsertVariableButton = new Button(composite, SWT.NONE);
+               fInsertVariableButton
+                               .setLayoutData(getButtonGridData(fInsertVariableButton));
+               fInsertVariableButton.setText(PreferencesMessages
+                               .getString("EditTemplateDialog.insert.variable")); //$NON-NLS-1$
+               fInsertVariableButton.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               fPatternEditor.getTextWidget().setFocus();
+                               fPatternEditor
+                                               .doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+
+               fDescriptionText.setText(fTemplate.getDescription());
+               if (fIsNameModifiable) {
+                       fNameText.setText(fTemplate.getName());
+                       fNameText.addModifyListener(listener);
+                       fContextCombo.select(getIndex(fTemplate.getContextTypeId()));
+               } else {
+                       fPatternEditor.getControl().setFocus();
+               }
+               initializeActions();
+
+               applyDialogFont(parent);
+               return composite;
+       }
+
+       protected void doTextWidgetChanged(Widget w) {
+               if (w == fNameText) {
+                       fSuppressError = false;
+                       String name = fNameText.getText();
+                       fTemplate.setName(name);
+                       updateButtons();
+               } else if (w == fContextCombo) {
+                       String name = fContextCombo.getText();
+                       String contextId = getContextId(name);
+                       fTemplate.setContextTypeId(contextId);
+                       fTemplateProcessor.setContextType(fContextTypeRegistry
+                                       .getContextType(contextId));
+               } else if (w == fDescriptionText) {
+                       String desc = fDescriptionText.getText();
+                       fTemplate.setDescription(desc);
+               }
+       }
+
+       private String getContextId(String name) {
+               if (name == null)
+                       return name;
+
+               for (int i = 0; i < fContextTypes.length; i++) {
+                       if (name.equals(fContextTypes[i][1])) {
+                               return fContextTypes[i][0];
+                       }
+               }
+               return name;
+       }
+
+       protected void doSourceChanged(IDocument document) {
+               String text = document.get();
+               String prefix = getPrefix();
+               fTemplate.setPattern(text.substring(prefix.length(), text.length()));
+               fValidationStatus.setOK();
+               TemplateContextType contextType = fContextTypeRegistry
+                               .getContextType(fTemplate.getContextTypeId());
+               if (contextType != null) {
+                       try {
+                               contextType.validate(text);
+                       } catch (TemplateException e) {
+                               fValidationStatus.setError(e.getLocalizedMessage());
+                       }
+               }
+
+               updateUndoAction();
+               updateButtons();
+       }
+
+       private static GridData getButtonGridData(Button button) {
+               GridData data = new GridData(GridData.FILL_HORIZONTAL);
+               data.heightHint = SWTUtil.getButtonHeightHint(button);
+
+               return data;
+       }
+
+       private static Label createLabel(Composite parent, String name) {
+               Label label = new Label(parent, SWT.NULL);
+               label.setText(name);
+               label.setLayoutData(new GridData());
+
+               return label;
+       }
+
+       private static Text createText(Composite parent) {
+               Text text = new Text(parent, SWT.BORDER);
+               text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               return text;
+       }
+
+       private SourceViewer createEditor(Composite parent) {
+               String prefix = getPrefix();
+               IDocument document = new Document(prefix + fTemplate.getPattern());
+               JavaTextTools tools = WebUI.getDefault().getJavaTextTools();
+               tools.setupJavaDocumentPartitioner(document,
+                               IPHPPartitions.PHP_PARTITIONING);
+               IPreferenceStore store = WebUI.getDefault()
+                               .getCombinedPreferenceStore();
+               SourceViewer viewer = new JavaSourceViewer(parent, null, null, false,
+                               SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
+               TemplateEditorSourceViewerConfiguration configuration = new TemplateEditorSourceViewerConfiguration(
+                               tools.getColorManager(), store, null, fTemplateProcessor);
+               viewer.configure(configuration);
+               viewer.setEditable(true);
+               // XXX workaround for bug 63313 - disabling prefix until fixed.
+               // viewer.setDocument(document, prefix.length(), document.getLength() -
+               // prefix.length());
+               viewer.setDocument(document);
+
+               Font font = JFaceResources
+                               .getFont(PreferenceConstants.EDITOR_TEXT_FONT);
+               viewer.getTextWidget().setFont(font);
+               new JavaSourcePreviewerUpdater(viewer, configuration, store);
+
+               int nLines = document.getNumberOfLines();
+               if (nLines < 5) {
+                       nLines = 5;
+               } else if (nLines > 12) {
+                       nLines = 12;
+               }
+
+               Control control = viewer.getControl();
+               GridData data = new GridData(GridData.FILL_BOTH);
+               data.widthHint = convertWidthInCharsToPixels(80);
+               data.heightHint = convertHeightInCharsToPixels(nLines);
+               control.setLayoutData(data);
+
+               viewer.addTextListener(new ITextListener() {
+                       public void textChanged(TextEvent event) {
+                               if (event.getDocumentEvent() != null)
+                                       doSourceChanged(event.getDocumentEvent().getDocument());
+                       }
+               });
+
+               viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+                       public void selectionChanged(SelectionChangedEvent event) {
+                               updateSelectionDependentActions();
+                       }
+               });
+
+               viewer.prependVerifyKeyListener(new VerifyKeyListener() {
+                       public void verifyKey(VerifyEvent event) {
+                               handleVerifyKeyPressed(event);
+                       }
+               });
+
+               return viewer;
+       }
+
+       private String getPrefix() {
+               String prefix;
+               int idx = getIndex(fTemplate.getContextTypeId());
+               if (idx != -1)
+                       prefix = fContextTypes[idx][2];
+               else
+                       prefix = ""; //$NON-NLS-1$
+
+               return prefix;
+       }
+
+       private void handleVerifyKeyPressed(VerifyEvent event) {
+               if (!event.doit)
+                       return;
+
+               if (event.stateMask != SWT.MOD1)
+                       return;
+
+               switch (event.character) {
+               case ' ':
+                       fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
+                       event.doit = false;
+                       break;
+
+               // CTRL-Z
+               case 'z' - 'a' + 1:
+                       fPatternEditor.doOperation(ITextOperationTarget.UNDO);
+                       event.doit = false;
+                       break;
+               }
+       }
+
+       private void initializeActions() {
+               TextViewerAction action = new TextViewerAction(fPatternEditor,
+                               SourceViewer.UNDO);
+               action
+                               .setText(PreferencesMessages
+                                               .getString("EditTemplateDialog.undo")); //$NON-NLS-1$
+               fGlobalActions.put(ITextEditorActionConstants.UNDO, action);
+
+               action = new TextViewerAction(fPatternEditor, SourceViewer.CUT);
+               action.setText(PreferencesMessages.getString("EditTemplateDialog.cut")); //$NON-NLS-1$
+               fGlobalActions.put(ITextEditorActionConstants.CUT, action);
+
+               action = new TextViewerAction(fPatternEditor, SourceViewer.COPY);
+               action
+                               .setText(PreferencesMessages
+                                               .getString("EditTemplateDialog.copy")); //$NON-NLS-1$
+               fGlobalActions.put(ITextEditorActionConstants.COPY, action);
+
+               action = new TextViewerAction(fPatternEditor, SourceViewer.PASTE);
+               action.setText(PreferencesMessages
+                               .getString("EditTemplateDialog.paste")); //$NON-NLS-1$
+               fGlobalActions.put(ITextEditorActionConstants.PASTE, action);
+
+               action = new TextViewerAction(fPatternEditor, SourceViewer.SELECT_ALL);
+               action.setText(PreferencesMessages
+                               .getString("EditTemplateDialog.select.all")); //$NON-NLS-1$
+               fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action);
+
+               action = new TextViewerAction(fPatternEditor,
+                               SourceViewer.CONTENTASSIST_PROPOSALS);
+               action.setText(PreferencesMessages
+                               .getString("EditTemplateDialog.content.assist")); //$NON-NLS-1$
+               fGlobalActions.put("ContentAssistProposal", action); //$NON-NLS-1$
+
+               fSelectionActions.add(ITextEditorActionConstants.CUT);
+               fSelectionActions.add(ITextEditorActionConstants.COPY);
+               fSelectionActions.add(ITextEditorActionConstants.PASTE);
+
+               // create context menu
+               MenuManager manager = new MenuManager(null, null);
+               manager.setRemoveAllWhenShown(true);
+               manager.addMenuListener(new IMenuListener() {
+                       public void menuAboutToShow(IMenuManager mgr) {
+                               fillContextMenu(mgr);
+                       }
+               });
+
+               StyledText text = fPatternEditor.getTextWidget();
+               Menu menu = manager.createContextMenu(text);
+               text.setMenu(menu);
+       }
+
+       private void fillContextMenu(IMenuManager menu) {
+               menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_UNDO));
+               menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO,
+                               (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO));
+
+               menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
+               menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT,
+                               (IAction) fGlobalActions.get(ITextEditorActionConstants.CUT));
+               menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT,
+                               (IAction) fGlobalActions.get(ITextEditorActionConstants.COPY));
+               menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT,
+                               (IAction) fGlobalActions.get(ITextEditorActionConstants.PASTE));
+               menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT,
+                               (IAction) fGlobalActions
+                                               .get(ITextEditorActionConstants.SELECT_ALL));
+
+               menu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
+               menu.appendToGroup(IContextMenuConstants.GROUP_GENERATE,
+                               (IAction) fGlobalActions.get("ContentAssistProposal")); //$NON-NLS-1$
+       }
+
+       protected void updateSelectionDependentActions() {
+               Iterator iterator = fSelectionActions.iterator();
+               while (iterator.hasNext())
+                       updateAction((String) iterator.next());
+       }
+
+       protected void updateUndoAction() {
+               IAction action = (IAction) fGlobalActions
+                               .get(ITextEditorActionConstants.UNDO);
+               if (action instanceof IUpdate)
+                       ((IUpdate) action).update();
+       }
+
+       protected void updateAction(String actionId) {
+               IAction action = (IAction) fGlobalActions.get(actionId);
+               if (action instanceof IUpdate)
+                       ((IUpdate) action).update();
+       }
+
+       private int getIndex(String contextid) {
+
+               if (contextid == null)
+                       return -1;
+
+               for (int i = 0; i < fContextTypes.length; i++) {
+                       if (contextid.equals(fContextTypes[i][0])) {
+                               return i;
+                       }
+               }
+               return -1;
+       }
+
+       protected void okPressed() {
+               super.okPressed();
+       }
+
+       private void updateButtons() {
+               StatusInfo status;
+
+               boolean valid = fNameText == null
+                               || fNameText.getText().trim().length() != 0;
+               if (!valid) {
+                       status = new StatusInfo();
+                       if (!fSuppressError) {
+                               status.setError(PreferencesMessages
+                                               .getString("EditTemplateDialog.error.noname")); //$NON-NLS-1$
+                       }
+               } else {
+                       status = fValidationStatus;
+               }
+               updateStatus(status);
+       }
+
+       /*
+        * @see org.eclipse.jface.window.Window#configureShell(Shell)
+        */
+       protected void configureShell(Shell newShell) {
+               super.configureShell(newShell);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
+                               IJavaHelpContextIds.EDIT_TEMPLATE_DIALOG);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditorConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditorConfigurationBlock.java
new file mode 100644 (file)
index 0000000..53482fd
--- /dev/null
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+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.Control;
+import org.eclipse.swt.widgets.Group;
+
+/**
+ * Options configuration block for editor related settings.
+ * 
+ * @since 3.0
+ */
+public class EditorConfigurationBlock extends OptionsConfigurationBlock {
+
+       /** Preference keys for the preferences in this block */
+       private static final String PREF_EDITOR_SAVE_ON_BLUR = PreferenceConstants.EDITOR_SAVE_ON_BLUR;
+
+       private static final String PREF_EDITOR_P_RTRIM_ON_SAVE = PreferenceConstants.EDITOR_P_RTRIM_ON_SAVE;
+       
+       /**
+        * Creates a new editor configuration block.
+        * 
+        * @param context
+        *            The status change listener
+        * @param project
+        *            The Java project
+        */
+       public EditorConfigurationBlock(final IStatusChangeListener context,
+                       final IJavaProject project) {
+               super(context, project, getAllKeys());
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite)
+        */
+       protected Control createContents(final Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               composite.setLayout(layout);
+
+               final String[] trueFalse = new String[] { IPreferenceStore.TRUE,
+                               IPreferenceStore.FALSE };
+
+               Group user = new Group(composite, SWT.NONE);
+               user.setText(PreferencesMessages
+                               .getString("EditorPreferencePage.file.title")); //$NON-NLS-1$
+               user.setLayout(new GridLayout());
+               user.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               String label = PreferencesMessages
+                               .getString("EditorPreferencePage.save_on_blur"); //$NON-NLS-1$
+               addCheckBox(user, label, PREF_EDITOR_SAVE_ON_BLUR, trueFalse, 0);
+
+               label = PreferencesMessages
+                               .getString("EditorPreferencePage.p_rtrim_on_save"); //$NON-NLS-1$
+               addCheckBox(user, label, PREF_EDITOR_P_RTRIM_ON_SAVE, trueFalse, 0);
+
+               return composite;
+       }
+
+       private static String[] getAllKeys() {
+               return new String[] { PREF_EDITOR_SAVE_ON_BLUR,
+                               PREF_EDITOR_P_RTRIM_ON_SAVE };
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getDefaultOptions()
+        */
+       protected Map getDefaultOptions() {
+
+               final String[] keys = fAllKeys;
+               final Map options = new HashMap();
+               final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+
+               for (int index = 0; index < keys.length; index++)
+                       options.put(keys[index], store.getDefaultString(keys[index]));
+
+               return options;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean)
+        */
+       protected final String[] getFullBuildDialogStrings(final boolean workspace) {
+               return null;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getOptions(boolean)
+        */
+       protected Map getOptions(final boolean inherit) {
+
+               final String[] keys = fAllKeys;
+               final Map options = new HashMap();
+               final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+
+               for (int index = 0; index < keys.length; index++)
+                       options.put(keys[index], store.getString(keys[index]));
+
+               return options;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#setOptions(java.util.Map)
+        */
+       protected void setOptions(final Map options) {
+
+               final String[] keys = fAllKeys;
+               final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+
+               for (int index = 0; index < keys.length; index++)
+                       store.setValue(keys[index], (String) fWorkingValues
+                                       .get(keys[index]));
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(java.lang.String,java.lang.String)
+        */
+       protected void validateSettings(final String key, final String value) {
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditorPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/EditorPreferencePage.java
new file mode 100644 (file)
index 0000000..5890cd0
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Preference page for spell checking preferences.
+ * 
+ * @since 3.0
+ */
+public class EditorPreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage, IStatusChangeListener {
+
+       /** The spelling configuration block */
+       private final EditorConfigurationBlock fBlock = new EditorConfigurationBlock(
+                       this, null);
+
+       /**
+        * Creates a new spelling preference page.
+        */
+       public EditorPreferencePage() {
+
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+               setDescription(PreferencesMessages
+                               .getString("EditorPreferencePage.description")); //$NON-NLS-1$
+               setTitle(PreferencesMessages.getString("EditorPreferencePage.title")); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+        */
+       protected Control createContents(final Composite parent) {
+
+               final Control control = fBlock.createContents(parent);
+               Dialog.applyDialogFont(control);
+
+               return control;
+       }
+
+       /*
+        * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+        */
+       public void createControl(final Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.JAVA_EDITOR_PREFERENCE_PAGE);
+       }
+
+       /*
+        * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+        */
+       public void init(final IWorkbench workbench) {
+               // Do nothing
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               fBlock.performDefaults();
+
+               super.performDefaults();
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+
+               if (!fBlock.performOk(true))
+                       return false;
+
+               return super.performOk();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener#statusChanged(org.eclipse.core.runtime.IStatus)
+        */
+       public void statusChanged(final IStatus status) {
+               setValid(!status.matches(IStatus.ERROR));
+
+               StatusUtil.applyToStatusLine(this, status);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/FoldingConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/FoldingConfigurationBlock.java
new file mode 100644 (file)
index 0000000..242d87f
--- /dev/null
@@ -0,0 +1,398 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.text.folding.JavaFoldingStructureProviderDescriptor;
+import net.sourceforge.phpdt.internal.ui.text.folding.JavaFoldingStructureProviderRegistry;
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingPreferenceBlock;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Configures Java Editor folding preferences.
+ * 
+ * @since 3.0
+ */
+class FoldingConfigurationBlock {
+
+       private static class ErrorPreferences implements
+                       IJavaFoldingPreferenceBlock {
+               private String fMessage;
+
+               protected ErrorPreferences(String message) {
+                       fMessage = message;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.folding.IJavaFoldingPreferences#createControl(org.eclipse.swt.widgets.Group)
+                */
+               public Control createControl(Composite composite) {
+                       Composite inner = new Composite(composite, SWT.NONE);
+                       inner.setLayout(new FillLayout(SWT.VERTICAL));
+
+                       Label label = new Label(inner, SWT.CENTER);
+                       label.setText(fMessage);
+
+                       return inner;
+               }
+
+               public void initialize() {
+               }
+
+               public void performOk() {
+               }
+
+               public void performDefaults() {
+               }
+
+               public void dispose() {
+               }
+
+       }
+
+       /** The overlay preference store. */
+       private final OverlayPreferenceStore fStore;
+
+       /* The controls */
+       private Combo fProviderCombo;
+
+       private Button fFoldingCheckbox;
+
+       private ComboViewer fProviderViewer;
+
+       private Map fProviderDescriptors;
+
+       private Composite fGroup;
+
+       private Map fProviderPreferences;
+
+       private Map fProviderControls;
+
+       private StackLayout fStackLayout;
+
+       public FoldingConfigurationBlock(OverlayPreferenceStore store) {
+               Assert.isNotNull(store);
+               fStore = store;
+               fStore.addKeys(createOverlayStoreKeys());
+               fProviderDescriptors = createListModel();
+               fProviderPreferences = new HashMap();
+               fProviderControls = new HashMap();
+       }
+
+       private Map createListModel() {
+               JavaFoldingStructureProviderRegistry reg = WebUI
+                               .getDefault().getFoldingStructureProviderRegistry();
+               reg.reloadExtensions();
+               JavaFoldingStructureProviderDescriptor[] descs = reg
+                               .getFoldingProviderDescriptors();
+               Map map = new HashMap();
+               for (int i = 0; i < descs.length; i++) {
+                       map.put(descs[i].getId(), descs[i]);
+               }
+               return map;
+       }
+
+       private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() {
+
+               ArrayList overlayKeys = new ArrayList();
+
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_FOLDING_ENABLED));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_FOLDING_PROVIDER));
+
+               OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys
+                               .size()];
+               overlayKeys.toArray(keys);
+               return keys;
+       }
+
+       /**
+        * Creates page for folding preferences.
+        * 
+        * @param parent
+        *            the parent composite
+        * @return the control for the preference page
+        */
+       Control createControl(Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NULL);
+               // assume parent page uses griddata
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER
+                               | GridData.VERTICAL_ALIGN_FILL);
+               composite.setLayoutData(gd);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               PixelConverter pc = new PixelConverter(composite);
+               layout.verticalSpacing = pc.convertHeightInCharsToPixels(1) / 2;
+               composite.setLayout(layout);
+
+               /* check box for new editors */
+               fFoldingCheckbox = new Button(composite, SWT.CHECK);
+               fFoldingCheckbox.setText(PreferencesMessages
+                               .getString("FoldingConfigurationBlock.enable")); //$NON-NLS-1$
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
+                               | GridData.VERTICAL_ALIGN_BEGINNING);
+               fFoldingCheckbox.setLayoutData(gd);
+               fFoldingCheckbox.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               boolean enabled = fFoldingCheckbox.getSelection();
+                               fStore.setValue(PreferenceConstants.EDITOR_FOLDING_ENABLED,
+                                               enabled);
+                               updateCheckboxDependencies();
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+
+               Label label = new Label(composite, SWT.CENTER);
+               gd = new GridData(GridData.FILL_HORIZONTAL
+                               | GridData.VERTICAL_ALIGN_BEGINNING);
+               label.setLayoutData(gd);
+
+               /* list */
+               Composite comboComp = new Composite(composite, SWT.NONE);
+               gd = new GridData(GridData.FILL_HORIZONTAL
+                               | GridData.VERTICAL_ALIGN_BEGINNING);
+               GridLayout gridLayout = new GridLayout(2, false);
+               gridLayout.marginWidth = 0;
+               comboComp.setLayout(gridLayout);
+
+               Label comboLabel = new Label(comboComp, SWT.CENTER);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
+                               | GridData.VERTICAL_ALIGN_CENTER);
+               comboLabel.setLayoutData(gd);
+               comboLabel.setText(PreferencesMessages
+                               .getString("FoldingConfigurationBlock.combo_caption")); //$NON-NLS-1$
+
+               label = new Label(composite, SWT.CENTER);
+               gd = new GridData(GridData.FILL_HORIZONTAL
+                               | GridData.VERTICAL_ALIGN_BEGINNING);
+               label.setLayoutData(gd);
+
+               fProviderCombo = new Combo(comboComp, SWT.READ_ONLY | SWT.DROP_DOWN);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_END
+                               | GridData.VERTICAL_ALIGN_CENTER);
+               fProviderCombo.setLayoutData(gd);
+
+               /* list viewer */
+               fProviderViewer = new ComboViewer(fProviderCombo);
+               fProviderViewer.setContentProvider(new IStructuredContentProvider() {
+
+                       /*
+                        * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+                        */
+                       public void dispose() {
+                       }
+
+                       /*
+                        * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
+                        *      java.lang.Object, java.lang.Object)
+                        */
+                       public void inputChanged(Viewer viewer, Object oldInput,
+                                       Object newInput) {
+                       }
+
+                       /*
+                        * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+                        */
+                       public Object[] getElements(Object inputElement) {
+                               return fProviderDescriptors.values().toArray();
+                       }
+               });
+               fProviderViewer.setLabelProvider(new LabelProvider() {
+                       /*
+                        * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+                        */
+                       public Image getImage(Object element) {
+                               return null;
+                       }
+
+                       /*
+                        * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+                        */
+                       public String getText(Object element) {
+                               return ((JavaFoldingStructureProviderDescriptor) element)
+                                               .getName();
+                       }
+               });
+               fProviderViewer
+                               .addSelectionChangedListener(new ISelectionChangedListener() {
+
+                                       public void selectionChanged(SelectionChangedEvent event) {
+                                               IStructuredSelection sel = (IStructuredSelection) event
+                                                               .getSelection();
+                                               if (!sel.isEmpty()) {
+                                                       fStore
+                                                                       .setValue(
+                                                                                       PreferenceConstants.EDITOR_FOLDING_PROVIDER,
+                                                                                       ((JavaFoldingStructureProviderDescriptor) sel
+                                                                                                       .getFirstElement()).getId());
+                                                       updateListDependencies();
+                                               }
+                                       }
+                               });
+               fProviderViewer.setInput(fProviderDescriptors);
+               fProviderViewer.refresh();
+
+               Composite groupComp = new Composite(composite, SWT.NONE);
+               gd = new GridData(GridData.FILL_BOTH);
+               gd.horizontalSpan = 2;
+               groupComp.setLayoutData(gd);
+               gridLayout = new GridLayout(1, false);
+               gridLayout.marginWidth = 0;
+               groupComp.setLayout(gridLayout);
+
+               /* contributed provider preferences. */
+               fGroup = new Composite(groupComp, SWT.NONE);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
+                               | GridData.VERTICAL_ALIGN_BEGINNING);
+               fGroup.setLayoutData(gd);
+               fStackLayout = new StackLayout();
+               fGroup.setLayout(fStackLayout);
+
+               return composite;
+       }
+
+       private void updateCheckboxDependencies() {
+       }
+
+       void updateListDependencies() {
+               String id = fStore
+                               .getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
+               JavaFoldingStructureProviderDescriptor desc = (JavaFoldingStructureProviderDescriptor) fProviderDescriptors
+                               .get(id);
+               IJavaFoldingPreferenceBlock prefs;
+
+               if (desc == null) {
+                       // safety in case there is no such descriptor
+                       String message = PreferencesMessages
+                                       .getString("FoldingConfigurationBlock.error.not_exist"); //$NON-NLS-1$
+                       WebUI.log(new Status(IStatus.WARNING, WebUI
+                                       .getPluginId(), IStatus.OK, message, null));
+                       prefs = new ErrorPreferences(message);
+               } else {
+                       prefs = (IJavaFoldingPreferenceBlock) fProviderPreferences.get(id);
+                       if (prefs == null) {
+                               try {
+                                       prefs = desc.createPreferences();
+                                       fProviderPreferences.put(id, prefs);
+                               } catch (CoreException e) {
+                                       WebUI.log(e);
+                                       prefs = new ErrorPreferences(e.getLocalizedMessage());
+                               }
+                       }
+               }
+
+               Control control = (Control) fProviderControls.get(id);
+               if (control == null) {
+                       control = prefs.createControl(fGroup);
+                       if (control == null) {
+                               String message = PreferencesMessages
+                                               .getString("FoldingConfigurationBlock.info.no_preferences"); //$NON-NLS-1$
+                               control = new ErrorPreferences(message).createControl(fGroup);
+                       } else {
+                               fProviderControls.put(id, control);
+                       }
+               }
+               fStackLayout.topControl = control;
+               control.pack();
+               fGroup.layout();
+               fGroup.getParent().layout();
+
+               prefs.initialize();
+       }
+
+       void initialize() {
+               restoreFromPreferences();
+       }
+
+       void performOk() {
+               for (Iterator it = fProviderPreferences.values().iterator(); it
+                               .hasNext();) {
+                       IJavaFoldingPreferenceBlock prefs = (IJavaFoldingPreferenceBlock) it
+                                       .next();
+                       prefs.performOk();
+               }
+       }
+
+       void performDefaults() {
+               restoreFromPreferences();
+               for (Iterator it = fProviderPreferences.values().iterator(); it
+                               .hasNext();) {
+                       IJavaFoldingPreferenceBlock prefs = (IJavaFoldingPreferenceBlock) it
+                                       .next();
+                       prefs.performDefaults();
+               }
+       }
+
+       void dispose() {
+               for (Iterator it = fProviderPreferences.values().iterator(); it
+                               .hasNext();) {
+                       IJavaFoldingPreferenceBlock prefs = (IJavaFoldingPreferenceBlock) it
+                                       .next();
+                       prefs.dispose();
+               }
+       }
+
+       private void restoreFromPreferences() {
+               boolean enabled = fStore
+                               .getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
+               fFoldingCheckbox.setSelection(enabled);
+               updateCheckboxDependencies();
+
+               String id = fStore
+                               .getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
+               Object provider = fProviderDescriptors.get(id);
+               if (provider != null) {
+                       fProviderViewer.setSelection(new StructuredSelection(provider),
+                                       true);
+                       updateListDependencies();
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/IPreferenceConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/IPreferenceConfigurationBlock.java
new file mode 100644 (file)
index 0000000..10f856d
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Interface for preference configuration blocks which can either be wrapped by
+ * a
+ * {@link net.sourceforge.phpdt.internal.ui.preferences.AbstractConfigurationBlockPreferencePage}
+ * or be included some preference page.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public interface IPreferenceConfigurationBlock {
+
+       /**
+        * Creates the preference control.
+        * 
+        * @param parent
+        *            the parent composite to which to add the preferences control
+        * @return the control that was added to <code>parent</code>
+        */
+       Control createControl(Composite parent);
+
+       /**
+        * Called after creating the control. Implementations should load the
+        * preferences values and update the controls accordingly.
+        */
+       void initialize();
+
+       /**
+        * Called when the <code>OK</code> button is pressed on the preference
+        * page. Implementations should commit the configured preference settings
+        * into their form of preference storage.
+        */
+       void performOk();
+
+       /**
+        * Called when the <code>Defaults</code> button is pressed on the
+        * preference page. Implementation should reset any preference settings to
+        * their default values and adjust the controls accordingly.
+        */
+       void performDefaults();
+
+       /**
+        * Called when the preference page is being disposed. Implementations should
+        * free any resources they are holding on to.
+        */
+       void dispose();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorHoverConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorHoverConfigurationBlock.java
new file mode 100644 (file)
index 0000000..cbaaae7
--- /dev/null
@@ -0,0 +1,480 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.swt.SWT;
+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.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Configures Java Editor hover preferences.
+ * 
+ * @since 2.1
+ */
+class JavaEditorHoverConfigurationBlock {
+
+       private static final String DELIMITER = PreferencesMessages
+                       .getString("JavaEditorHoverConfigurationBlock.delimiter"); //$NON-NLS-1$
+
+       // Data structure to hold the values which are edited by the user
+       private static class HoverConfig {
+
+               private String fModifierString;
+
+               private boolean fIsEnabled;
+
+               private int fStateMask;
+
+               private HoverConfig(String modifier, int stateMask, boolean enabled) {
+                       fModifierString = modifier;
+                       fIsEnabled = enabled;
+                       fStateMask = stateMask;
+               }
+       }
+
+       private IPreferenceStore fStore;
+
+       private HoverConfig[] fHoverConfigs;
+
+       private Text fModifierEditor;
+
+       private Button fEnableField;
+
+       private List fHoverList;
+
+       private Text fDescription;
+
+       private Button fShowHoverAffordanceCheckbox;
+
+       private JavaEditorPreferencePage fMainPreferencePage;
+
+       private StatusInfo fStatus;
+
+       public JavaEditorHoverConfigurationBlock(
+                       JavaEditorPreferencePage mainPreferencePage, IPreferenceStore store) {
+               Assert.isNotNull(mainPreferencePage);
+               Assert.isNotNull(store);
+               fMainPreferencePage = mainPreferencePage;
+               fStore = store;
+       }
+
+       /**
+        * Creates page for hover preferences.
+        */
+       public Control createControl(Composite parent) {
+
+               PixelConverter pixelConverter = new PixelConverter(parent);
+
+               Composite hoverComposite = new Composite(parent, SWT.NULL);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               hoverComposite.setLayout(layout);
+               GridData gd = new GridData(GridData.GRAB_HORIZONTAL
+                               | GridData.VERTICAL_ALIGN_FILL);
+               hoverComposite.setLayoutData(gd);
+
+               Label label = new Label(hoverComposite, SWT.NONE);
+               label
+                               .setText(PreferencesMessages
+                                               .getString("JavaEditorHoverConfigurationBlock.hoverPreferences")); //$NON-NLS-1$
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalAlignment = GridData.BEGINNING;
+               gd.horizontalSpan = 2;
+               label.setLayoutData(gd);
+               gd = new GridData(GridData.GRAB_HORIZONTAL
+                               | GridData.VERTICAL_ALIGN_FILL);
+
+               // Hover list
+               fHoverList = new List(hoverComposite, SWT.SINGLE | SWT.V_SCROLL
+                               | SWT.BORDER);
+               gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+                               | GridData.FILL_HORIZONTAL);
+               int listHeight = 10 * fHoverList.getItemHeight();
+               gd.heightHint = listHeight;
+               fHoverList.setLayoutData(gd);
+               fHoverList.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               handleHoverListSelection();
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+
+               Composite stylesComposite = new Composite(hoverComposite, SWT.NONE);
+               layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               stylesComposite.setLayout(layout);
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.heightHint = listHeight + (2 * fHoverList.getBorderWidth());
+               stylesComposite.setLayoutData(gd);
+
+               // Enabled checkbox
+               fEnableField = new Button(stylesComposite, SWT.CHECK);
+               fEnableField.setText(PreferencesMessages
+                               .getString("JavaEditorHoverConfigurationBlock.enabled")); //$NON-NLS-1$
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalAlignment = GridData.BEGINNING;
+               gd.horizontalSpan = 2;
+               fEnableField.setLayoutData(gd);
+               fEnableField.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fHoverList.getSelectionIndex();
+                               boolean state = fEnableField.getSelection();
+                               fModifierEditor.setEnabled(state);
+                               fHoverConfigs[i].fIsEnabled = state;
+                               handleModifierModified();
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+
+               // Text field for modifier string
+               label = new Label(stylesComposite, SWT.LEFT);
+               label.setText(PreferencesMessages
+                               .getString("JavaEditorHoverConfigurationBlock.keyModifier")); //$NON-NLS-1$
+               fModifierEditor = new Text(stylesComposite, SWT.BORDER);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               fModifierEditor.setLayoutData(gd);
+
+               fModifierEditor.addKeyListener(new KeyListener() {
+                       private boolean isModifierCandidate;
+
+                       public void keyPressed(KeyEvent e) {
+                               isModifierCandidate = e.keyCode > 0 && e.character == 0
+                                               && e.stateMask == 0;
+                       }
+
+                       public void keyReleased(KeyEvent e) {
+                               if (isModifierCandidate && e.stateMask > 0
+                                               && e.stateMask == e.stateMask && e.character == 0) {// &&
+                                                                                                                                                       // e.time
+                                                                                                                                                       // -time
+                                                                                                                                                       // <
+                                                                                                                                                       // 1000)
+                                                                                                                                                       // {
+                                       String text = fModifierEditor.getText();
+                                       Point selection = fModifierEditor.getSelection();
+                                       int i = selection.x - 1;
+                                       while (i > -1 && Character.isWhitespace(text.charAt(i))) {
+                                               i--;
+                                       }
+                                       boolean needsPrefixDelimiter = i > -1
+                                                       && !String.valueOf(text.charAt(i))
+                                                                       .equals(DELIMITER);
+
+                                       i = selection.y;
+                                       while (i < text.length()
+                                                       && Character.isWhitespace(text.charAt(i))) {
+                                               i++;
+                                       }
+                                       boolean needsPostfixDelimiter = i < text.length()
+                                                       && !String.valueOf(text.charAt(i))
+                                                                       .equals(DELIMITER);
+
+                                       String insertString;
+
+                                       if (needsPrefixDelimiter && needsPostfixDelimiter)
+                                               insertString = PreferencesMessages
+                                                               .getFormattedString(
+                                                                               "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
+                                       else if (needsPrefixDelimiter)
+                                               insertString = PreferencesMessages
+                                                               .getFormattedString(
+                                                                               "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifier", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
+                                       else if (needsPostfixDelimiter)
+                                               insertString = PreferencesMessages
+                                                               .getFormattedString(
+                                                                               "JavaEditorHoverConfigurationBlock.insertModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
+                                       else
+                                               insertString = Action.findModifierString(e.stateMask);
+
+                                       if (insertString != null)
+                                               fModifierEditor.insert(insertString);
+                               }
+                       }
+               });
+
+               fModifierEditor.addModifyListener(new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               handleModifierModified();
+                       }
+               });
+
+               // Description
+               Label descriptionLabel = new Label(stylesComposite, SWT.LEFT);
+               descriptionLabel.setText(PreferencesMessages
+                               .getString("JavaEditorHoverConfigurationBlock.description")); //$NON-NLS-1$
+               gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
+               gd.horizontalSpan = 2;
+               descriptionLabel.setLayoutData(gd);
+               fDescription = new Text(stylesComposite, SWT.LEFT | SWT.WRAP
+                               | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER);
+               gd = new GridData(GridData.FILL_BOTH);
+               gd.horizontalSpan = 2;
+               fDescription.setLayoutData(gd);
+
+               // Vertical filler
+               Label filler = new Label(hoverComposite, SWT.LEFT);
+               gd = new GridData(GridData.BEGINNING | GridData.VERTICAL_ALIGN_FILL);
+               gd.heightHint = pixelConverter.convertHeightInCharsToPixels(1) / 3;
+               filler.setLayoutData(gd);
+
+               // Affordance checkbox
+               fShowHoverAffordanceCheckbox = new Button(hoverComposite, SWT.CHECK);
+               fShowHoverAffordanceCheckbox.setText(PreferencesMessages
+                               .getString("JavaEditorHoverConfigurationBlock.showAffordance")); //$NON-NLS-1$
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = 0;
+               gd.horizontalSpan = 2;
+               fShowHoverAffordanceCheckbox.setLayoutData(gd);
+
+               initialize();
+
+               Dialog.applyDialogFont(hoverComposite);
+               return hoverComposite;
+       }
+
+       private JavaEditorTextHoverDescriptor[] getContributedHovers() {
+               return WebUI.getDefault()
+                               .getJavaEditorTextHoverDescriptors();
+       }
+
+       void initialize() {
+               JavaEditorTextHoverDescriptor[] hoverDescs = getContributedHovers();
+               fHoverConfigs = new HoverConfig[hoverDescs.length];
+               for (int i = 0; i < hoverDescs.length; i++) {
+                       fHoverConfigs[i] = new HoverConfig(hoverDescs[i]
+                                       .getModifierString(), hoverDescs[i].getStateMask(),
+                                       hoverDescs[i].isEnabled());
+                       fHoverList.add(hoverDescs[i].getLabel());
+               }
+               initializeFields();
+       }
+
+       void initializeFields() {
+               fHoverList.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if (fHoverList != null && !fHoverList.isDisposed()) {
+                                       fHoverList.select(0);
+                                       handleHoverListSelection();
+                               }
+                       }
+               });
+               fShowHoverAffordanceCheckbox
+                               .setSelection(fStore
+                                               .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
+       }
+
+       void performOk() {
+               StringBuffer buf = new StringBuffer();
+               StringBuffer maskBuf = new StringBuffer();
+               for (int i = 0; i < fHoverConfigs.length; i++) {
+                       buf.append(getContributedHovers()[i].getId());
+                       buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
+                       if (!fHoverConfigs[i].fIsEnabled)
+                               buf.append(JavaEditorTextHoverDescriptor.DISABLED_TAG);
+                       String modifier = fHoverConfigs[i].fModifierString;
+                       if (modifier == null || modifier.length() == 0)
+                               modifier = JavaEditorTextHoverDescriptor.NO_MODIFIER;
+                       buf.append(modifier);
+                       buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
+
+                       maskBuf.append(getContributedHovers()[i].getId());
+                       maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
+                       maskBuf.append(fHoverConfigs[i].fStateMask);
+                       maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
+               }
+               fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, buf
+                               .toString());
+               fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS,
+                               maskBuf.toString());
+
+               fStore.setValue(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE,
+                               fShowHoverAffordanceCheckbox.getSelection());
+
+               WebUI.getDefault().resetJavaEditorTextHoverDescriptors();
+       }
+
+       void performDefaults() {
+               restoreFromPreferences();
+               initializeFields();
+       }
+
+       private void restoreFromPreferences() {
+
+               fShowHoverAffordanceCheckbox
+                               .setSelection(fStore
+                                               .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
+
+               String compiledTextHoverModifiers = fStore
+                               .getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
+
+               StringTokenizer tokenizer = new StringTokenizer(
+                               compiledTextHoverModifiers,
+                               JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
+               HashMap idToModifier = new HashMap(tokenizer.countTokens() / 2);
+
+               while (tokenizer.hasMoreTokens()) {
+                       String id = tokenizer.nextToken();
+                       if (tokenizer.hasMoreTokens())
+                               idToModifier.put(id, tokenizer.nextToken());
+               }
+
+               String compiledTextHoverModifierMasks = WebUI.getDefault()
+                               .getPreferenceStore().getString(
+                                               PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
+
+               tokenizer = new StringTokenizer(compiledTextHoverModifierMasks,
+                               JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
+               HashMap idToModifierMask = new HashMap(tokenizer.countTokens() / 2);
+
+               while (tokenizer.hasMoreTokens()) {
+                       String id = tokenizer.nextToken();
+                       if (tokenizer.hasMoreTokens())
+                               idToModifierMask.put(id, tokenizer.nextToken());
+               }
+
+               for (int i = 0; i < fHoverConfigs.length; i++) {
+                       String modifierString = (String) idToModifier
+                                       .get(getContributedHovers()[i].getId());
+                       boolean enabled = true;
+                       if (modifierString == null)
+                               modifierString = JavaEditorTextHoverDescriptor.DISABLED_TAG;
+
+                       if (modifierString
+                                       .startsWith(JavaEditorTextHoverDescriptor.DISABLED_TAG)) {
+                               enabled = false;
+                               modifierString = modifierString.substring(1);
+                       }
+
+                       if (modifierString
+                                       .equals(JavaEditorTextHoverDescriptor.NO_MODIFIER))
+                               modifierString = ""; //$NON-NLS-1$
+
+                       fHoverConfigs[i].fModifierString = modifierString;
+                       fHoverConfigs[i].fIsEnabled = enabled;
+                       fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
+                                       .computeStateMask(modifierString);
+
+                       if (fHoverConfigs[i].fStateMask == -1) {
+                               try {
+                                       fHoverConfigs[i].fStateMask = Integer
+                                                       .parseInt((String) idToModifierMask
+                                                                       .get(getContributedHovers()[i].getId()));
+                               } catch (NumberFormatException ex) {
+                                       fHoverConfigs[i].fStateMask = -1;
+                               }
+                       }
+               }
+       }
+
+       private void handleModifierModified() {
+               int i = fHoverList.getSelectionIndex();
+               String modifiers = fModifierEditor.getText();
+               fHoverConfigs[i].fModifierString = modifiers;
+               fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
+                               .computeStateMask(modifiers);
+               if (fHoverConfigs[i].fIsEnabled && fHoverConfigs[i].fStateMask == -1)
+                       fStatus = new StatusInfo(
+                                       IStatus.ERROR,
+                                       PreferencesMessages
+                                                       .getFormattedString(
+                                                                       "JavaEditorHoverConfigurationBlock.modifierIsNotValid", fHoverConfigs[i].fModifierString)); //$NON-NLS-1$
+               else
+                       fStatus = new StatusInfo();
+               updateStatus();
+       }
+
+       private void handleHoverListSelection() {
+               int i = fHoverList.getSelectionIndex();
+               boolean enabled = fHoverConfigs[i].fIsEnabled;
+               fEnableField.setSelection(enabled);
+               fModifierEditor.setEnabled(enabled);
+               fModifierEditor.setText(fHoverConfigs[i].fModifierString);
+               String description = getContributedHovers()[i].getDescription();
+               if (description == null)
+                       description = ""; //$NON-NLS-1$
+               fDescription.setText(description);
+       }
+
+       IStatus getStatus() {
+               if (fStatus == null)
+                       fStatus = new StatusInfo();
+               return fStatus;
+       }
+
+       private void updateStatus() {
+               int i = 0;
+               HashMap stateMasks = new HashMap(fHoverConfigs.length);
+               while (fStatus.isOK() && i < fHoverConfigs.length) {
+                       if (fHoverConfigs[i].fIsEnabled) {
+                               String label = getContributedHovers()[i].getLabel();
+                               Integer stateMask = new Integer(fHoverConfigs[i].fStateMask);
+                               if (fHoverConfigs[i].fStateMask == -1)
+                                       fStatus = new StatusInfo(
+                                                       IStatus.ERROR,
+                                                       PreferencesMessages
+                                                                       .getFormattedString(
+                                                                                       "JavaEditorHoverConfigurationBlock.modifierIsNotValidForHover", new String[] { fHoverConfigs[i].fModifierString, label })); //$NON-NLS-1$
+                               else if (stateMasks.containsKey(stateMask))
+                                       fStatus = new StatusInfo(
+                                                       IStatus.ERROR,
+                                                       PreferencesMessages
+                                                                       .getFormattedString(
+                                                                                       "JavaEditorHoverConfigurationBlock.duplicateModifier", new String[] { label, (String) stateMasks.get(stateMask) })); //$NON-NLS-1$
+                               else
+                                       stateMasks.put(stateMask, label);
+                       }
+                       i++;
+               }
+
+               if (fStatus.isOK())
+                       fMainPreferencePage.updateStatus(fStatus);
+               else {
+                       fMainPreferencePage.setValid(false);
+                       StatusUtil.applyToStatusLine(fMainPreferencePage, fStatus);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java
new file mode 100644 (file)
index 0000000..baa56e2
--- /dev/null
@@ -0,0 +1,2050 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
+import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.EditorUtility;
+import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
+import net.sourceforge.phpeclipse.preferences.ColorEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.swt.SWT;
+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.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
+
+
+/**
+ * The page for setting the editor options.
+ */
+public class JavaEditorPreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage {
+       private static final String BOLD = PreferenceConstants.EDITOR_BOLD_SUFFIX;
+
+       private static final String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;
+
+       private static final String DELIMITER = PreferencesMessages
+                       .getString("JavaEditorPreferencePage.navigation.delimiter"); //$NON-NLS-1$
+
+       /** The keys of the overlay store. */
+       public final OverlayPreferenceStore.OverlayKey[] fKeys;
+
+       private final String[][] fSyntaxColorListModel = new String[][] {
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.multiLineComment"),
+                                       PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.singleLineComment"),
+                                       PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR },
+                       //$NON-NLS-1$
+                       { PreferencesMessages.getString("JavaEditorPreferencePage.tags"),
+                                       PreferenceConstants.EDITOR_PHP_TAG_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.keywords"),
+                                       PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR },
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.functionNames"),
+                                       PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.variables"),
+                                       PreferenceConstants.EDITOR_PHP_VARIABLE_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.variables_dollar"),
+                                       PreferenceConstants.EDITOR_PHP_VARIABLE_DOLLAR_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.constants"),
+                                       PreferenceConstants.EDITOR_PHP_CONSTANT_COLOR },
+                       //$NON-NLS-1$
+                       { PreferencesMessages.getString("JavaEditorPreferencePage.types"),
+                                       PreferenceConstants.EDITOR_PHP_TYPE_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.strings_dq"),
+                                       PreferenceConstants.EDITOR_STRING_COLOR_DQ },
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.strings_sq"),
+                                       PreferenceConstants.EDITOR_STRING_COLOR_SQ },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.others"), PreferenceConstants.EDITOR_JAVA_DEFAULT_COLOR }, //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.operators"),
+                                       PreferenceConstants.EDITOR_PHP_OPERATOR_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.returnKeyword"),
+                                       PreferenceConstants.EDITOR_PHP_KEYWORD_RETURN_COLOR },
+                       { PreferencesMessages.getString("JavaEditorPreferencePage.braces"),
+                                       PreferenceConstants.EDITOR_PHP_BRACE_OPERATOR_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.phpDocKeywords"),
+                                       PreferenceConstants.EDITOR_JAVADOC_KEYWORD_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.phpDocHtmlTags"),
+                                       PreferenceConstants.EDITOR_JAVADOC_TAG_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.phpDocLinks"),
+                                       PreferenceConstants.EDITOR_JAVADOC_LINKS_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.phpDocOthers"), PreferenceConstants.EDITOR_JAVADOC_DEFAULT_COLOR } //$NON-NLS-1$
+       };
+
+       private final String[][] fAppearanceColorListModel = new String[][] {
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.matchingBracketsHighlightColor2"),
+                                       PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.currentLineHighlighColor"),
+                                       AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.printMarginColor2"),
+                                       AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.findScopeColor2"),
+                                       PreferenceConstants.EDITOR_FIND_SCOPE_COLOR },
+                       //$NON-NLS-1$
+                       {
+                                       PreferencesMessages
+                                                       .getString("JavaEditorPreferencePage.linkColor2"), PreferenceConstants.EDITOR_LINK_COLOR }, //$NON-NLS-1$
+       };
+
+       // private final String[][] fAnnotationColorListModel;
+
+       // private final String[][] fAnnotationDecorationListModel = new String[][]{
+       // {
+       // PreferencesMessages
+       // .getString("JavaEditorPreferencePage.AnnotationDecoration.NONE"),
+       // AnnotationPreference.STYLE_NONE},
+       // //$NON-NLS-1$
+       // {
+       // PreferencesMessages
+       // .getString("JavaEditorPreferencePage.AnnotationDecoration.SQUIGGLIES"),
+       // AnnotationPreference.STYLE_SQUIGGLIES},
+       // //$NON-NLS-1$
+       // {
+       // PreferencesMessages
+       // .getString("JavaEditorPreferencePage.AnnotationDecoration.UNDERLINE"),
+       // AnnotationPreference.STYLE_UNDERLINE},
+       // //$NON-NLS-1$
+       // {
+       // PreferencesMessages
+       // .getString("JavaEditorPreferencePage.AnnotationDecoration.BOX"),
+       // AnnotationPreference.STYLE_BOX},
+       // //$NON-NLS-1$
+       // {
+       // PreferencesMessages
+       // .getString("JavaEditorPreferencePage.AnnotationDecoration.IBEAM"),
+       // AnnotationPreference.STYLE_IBEAM} //$NON-NLS-1$
+       // };
+       private OverlayPreferenceStore fOverlayStore;
+
+       private JavaTextTools fJavaTextTools;
+
+       private JavaEditorHoverConfigurationBlock fJavaEditorHoverConfigurationBlock;
+
+       private FoldingConfigurationBlock fFoldingConfigurationBlock;
+
+       private Map fColorButtons = new HashMap();
+
+       private Map fCheckBoxes = new HashMap();
+
+       private SelectionListener fCheckBoxListener = new SelectionListener() {
+               public void widgetDefaultSelected(SelectionEvent e) {
+               }
+
+               public void widgetSelected(SelectionEvent e) {
+                       Button button = (Button) e.widget;
+                       fOverlayStore.setValue((String) fCheckBoxes.get(button), button
+                                       .getSelection());
+               }
+       };
+
+       private Map fTextFields = new HashMap();
+
+       private ModifyListener fTextFieldListener = new ModifyListener() {
+               public void modifyText(ModifyEvent e) {
+                       Text text = (Text) e.widget;
+                       fOverlayStore.setValue((String) fTextFields.get(text), text
+                                       .getText());
+               }
+       };
+
+       private ArrayList fNumberFields = new ArrayList();
+
+       private ModifyListener fNumberFieldListener = new ModifyListener() {
+               public void modifyText(ModifyEvent e) {
+                       numberFieldChanged((Text) e.widget);
+               }
+       };
+
+       private List fSyntaxColorList;
+
+       private List fAppearanceColorList;
+
+       // private List fContentAssistColorList;
+       private List fAnnotationList;
+
+       private ColorEditor fSyntaxForegroundColorEditor;
+
+       private ColorEditor fAppearanceColorEditor;
+
+       private ColorEditor fAnnotationForegroundColorEditor;
+
+       private ColorEditor fContentAssistColorEditor;
+
+       private ColorEditor fBackgroundColorEditor;
+
+       private Button fBackgroundDefaultRadioButton;
+
+       private Button fBackgroundCustomRadioButton;
+
+       private Button fBackgroundColorButton;
+
+       private Button fBoldCheckBox;
+
+       // private Button fAddJavaDocTagsButton;
+
+       private Button fEscapeStringsButtonDQ;
+
+       private Button fEscapeStringsButtonSQ;
+
+       // private Button fGuessMethodArgumentsButton;
+       private SourceViewer fPreviewViewer;
+
+       private Color fBackgroundColor;
+
+       private Control fAutoInsertDelayText;
+
+       private Control fAutoInsertJavaTriggerText;
+
+       private Control fAutoInsertJavaDocTriggerText;
+
+       private Label fAutoInsertDelayLabel;
+
+       private Label fAutoInsertJavaTriggerLabel;
+
+       private Label fAutoInsertJavaDocTriggerLabel;
+
+       private Button fShowInTextCheckBox;
+
+       private Combo fDecorationStyleCombo;
+
+       private Button fHighlightInTextCheckBox;
+
+       private Button fShowInOverviewRulerCheckBox;
+
+       private Button fShowInVerticalRulerCheckBox;
+
+       private Text fBrowserLikeLinksKeyModifierText;
+
+       private Button fBrowserLikeLinksCheckBox;
+
+       private StatusInfo fBrowserLikeLinksKeyModifierStatus;
+
+       // private Button fCompletionInsertsRadioButton;
+       // private Button fCompletionOverwritesRadioButton;
+       // private Button fStickyOccurrencesButton;
+       /**
+        * Creates a new preference page.
+        */
+       public JavaEditorPreferencePage() {
+               setDescription(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.description")); //$NON-NLS-1$
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+               MarkerAnnotationPreferences markerAnnotationPreferences = new MarkerAnnotationPreferences();
+               fKeys = createOverlayStoreKeys(markerAnnotationPreferences);
+               fOverlayStore = new OverlayPreferenceStore(getPreferenceStore(), fKeys);
+               // fAnnotationColorListModel =
+               // createAnnotationTypeListModel(markerAnnotationPreferences);
+       }
+
+       private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys(
+                       MarkerAnnotationPreferences preferences) {
+               ArrayList overlayKeys = new ArrayList();
+               Iterator e = preferences.getAnnotationPreferences().iterator();
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_FOREGROUND_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_FOREGROUND_DEFAULT_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_BACKGROUND_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.INT,
+                               PreferenceConstants.EDITOR_TAB_WIDTH));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD));
+
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_TAG_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_TAG_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_VARIABLE_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_VARIABLE_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_VARIABLE_DOLLAR_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_VARIABLE_DOLLAR_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_CONSTANT_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_CONSTANT_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_TYPE_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_TYPE_BOLD));
+
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_STRING_COLOR_DQ));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_STRING_BOLD_DQ));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_STRING_COLOR_SQ));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_STRING_BOLD_SQ));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_JAVA_DEFAULT_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_JAVA_DEFAULT_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_TASK_TAG_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_TASK_TAG_BOLD));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING_DQ,
+               // PreferenceConstants.EDITOR_JAVA_METHOD_NAME_COLOR));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_JAVA_METHOD_NAME_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_OPERATOR_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_OPERATOR_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_KEYWORD_RETURN_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_KEYWORD_RETURN_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_PHP_BRACE_OPERATOR_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_PHP_BRACE_OPERATOR_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_JAVADOC_KEYWORD_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_JAVADOC_KEYWORD_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_JAVADOC_TAG_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_JAVADOC_TAG_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_JAVADOC_LINKS_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_JAVADOC_LINKS_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_JAVADOC_DEFAULT_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_JAVADOC_DEFAULT_BOLD));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_MATCHING_BRACKETS));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.STRING,
+                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.BOOLEAN,
+                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.STRING,
+                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLOR));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.INT,
+                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.BOOLEAN,
+                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_OCCURRENCES));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_STICKY_OCCURRENCES));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_FIND_SCOPE_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_LINK_COLOR));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_CORRECTION_INDICATION));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.BOOLEAN,
+                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_OVERVIEW_RULER));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_SPACES_FOR_TABS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.INT,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_AUTOINSERT));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_PARAMETERS_BACKGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_PARAMETERS_FOREGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVA));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.STRING,
+                                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVADOC));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_SHOW_VISIBLE_PROPOSALS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_ORDER_PROPOSALS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_CASE_SENSITIVITY));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_ADDIMPORT));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_INSERT_COMPLETION));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_SMART_PASTE));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_CLOSE_STRINGS_DQ_PHP));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_CLOSE_STRINGS_SQ_PHP));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP));
+               // overlayKeys
+               // .add(new OverlayPreferenceStore.OverlayKey(
+               // OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_CLOSE_BRACES));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_CLOSE_JAVADOCS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_WRAP_WORDS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_WRAP_STRINGS_DQ));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_ESCAPE_STRINGS_DQ));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_WRAP_STRINGS_SQ));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_ESCAPE_STRINGS_SQ));
+
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_FORMAT_JAVADOCS));
+
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_SMART_HOME_END));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.STRING,
+                               PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER));
+               overlayKeys
+                               .add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.STRING,
+                                               PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK));
+               while (e.hasNext()) {
+                       AnnotationPreference info = (AnnotationPreference) e.next();
+                       overlayKeys
+                                       .add(new OverlayPreferenceStore.OverlayKey(
+                                                       OverlayPreferenceStore.STRING, info
+                                                                       .getColorPreferenceKey()));
+                       overlayKeys
+                                       .add(new OverlayPreferenceStore.OverlayKey(
+                                                       OverlayPreferenceStore.BOOLEAN, info
+                                                                       .getTextPreferenceKey()));
+                       if (info.getHighlightPreferenceKey() != null)
+                               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.BOOLEAN, info
+                                                               .getHighlightPreferenceKey()));
+                       overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                                       OverlayPreferenceStore.BOOLEAN, info
+                                                       .getOverviewRulerPreferenceKey()));
+                       if (info.getVerticalRulerPreferenceKey() != null)
+                               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.BOOLEAN, info
+                                                               .getVerticalRulerPreferenceKey()));
+                       if (info.getTextStylePreferenceKey() != null)
+                               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                                               OverlayPreferenceStore.STRING, info
+                                                               .getTextStylePreferenceKey()));
+               }
+               OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys
+                               .size()];
+               overlayKeys.toArray(keys);
+               return keys;
+       } /*
+                * @see IWorkbenchPreferencePage#init()
+                */
+
+       public void init(IWorkbench workbench) {
+       }
+
+       /*
+        * @see PreferencePage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.JAVA_EDITOR_PREFERENCE_PAGE);
+       }
+
+       private void handleSyntaxColorListSelection() {
+               int i = fSyntaxColorList.getSelectionIndex();
+               String key = fSyntaxColorListModel[i][1];
+               RGB rgb = PreferenceConverter.getColor(fOverlayStore, key);
+               fSyntaxForegroundColorEditor.setColorValue(rgb);
+               fBoldCheckBox.setSelection(fOverlayStore.getBoolean(key + BOLD));
+       }
+
+       private void handleAppearanceColorListSelection() {
+               int i = fAppearanceColorList.getSelectionIndex();
+               String key = fAppearanceColorListModel[i][1];
+               RGB rgb = PreferenceConverter.getColor(fOverlayStore, key);
+               fAppearanceColorEditor.setColorValue(rgb);
+       }
+
+       // private void handleAnnotationListSelection() {
+       // int i = fAnnotationList.getSelectionIndex();
+       // String key = fAnnotationColorListModel[i][1];
+       // RGB rgb = PreferenceConverter.getColor(fOverlayStore, key);
+       // fAnnotationForegroundColorEditor.setColorValue(rgb);
+       // key = fAnnotationColorListModel[i][2];
+       // boolean showInText = fOverlayStore.getBoolean(key);
+       // fShowInTextCheckBox.setSelection(showInText);
+       // key = fAnnotationColorListModel[i][6];
+       // if (key != null) {
+       // fDecorationStyleCombo.setEnabled(showInText);
+       // for (int j = 0; j < fAnnotationDecorationListModel.length; j++) {
+       // String value = fOverlayStore.getString(key);
+       // if (fAnnotationDecorationListModel[j][1].equals(value)) {
+       // fDecorationStyleCombo.setText(fAnnotationDecorationListModel[j][0]);
+       // break;
+       // }
+       // }
+       // } else {
+       // fDecorationStyleCombo.setEnabled(false);
+       // fDecorationStyleCombo.setText(fAnnotationDecorationListModel[1][0]); //
+       // set
+       // // selection
+       // // to
+       // // squigglies
+       // // if
+       // // the
+       // // key
+       // // is
+       // // not
+       // // there
+       // // (legacy
+       // // support)
+       // }
+       // key = fAnnotationColorListModel[i][3];
+       // fShowInOverviewRulerCheckBox.setSelection(fOverlayStore.getBoolean(key));
+       // key = fAnnotationColorListModel[i][4];
+       // if (key != null) {
+       // fHighlightInTextCheckBox.setSelection(fOverlayStore.getBoolean(key));
+       // fHighlightInTextCheckBox.setEnabled(true);
+       // } else
+       // fHighlightInTextCheckBox.setEnabled(false);
+       // key = fAnnotationColorListModel[i][5];
+       // if (key != null) {
+       // fShowInVerticalRulerCheckBox.setSelection(fOverlayStore.getBoolean(key));
+       // fShowInVerticalRulerCheckBox.setEnabled(true);
+       // } else {
+       // fShowInVerticalRulerCheckBox.setSelection(true);
+       // fShowInVerticalRulerCheckBox.setEnabled(false);
+       // }
+       // }
+       private Control createSyntaxPage(Composite parent) {
+               Composite colorComposite = new Composite(parent, SWT.NULL);
+               colorComposite.setLayout(new GridLayout());
+               Group backgroundComposite = new Group(colorComposite,
+                               SWT.SHADOW_ETCHED_IN);
+               backgroundComposite.setLayout(new RowLayout());
+               backgroundComposite.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.backgroundColor"));//$NON-NLS-1$
+               SelectionListener backgroundSelectionListener = new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               boolean custom = fBackgroundCustomRadioButton.getSelection();
+                               fBackgroundColorButton.setEnabled(custom);
+                               fOverlayStore.setValue(
+                                               PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR,
+                                               !custom);
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               };
+               fBackgroundDefaultRadioButton = new Button(backgroundComposite,
+                               SWT.RADIO | SWT.LEFT);
+               fBackgroundDefaultRadioButton.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.systemDefault")); //$NON-NLS-1$
+               fBackgroundDefaultRadioButton
+                               .addSelectionListener(backgroundSelectionListener);
+               fBackgroundCustomRadioButton = new Button(backgroundComposite,
+                               SWT.RADIO | SWT.LEFT);
+               fBackgroundCustomRadioButton.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.custom")); //$NON-NLS-1$
+               fBackgroundCustomRadioButton
+                               .addSelectionListener(backgroundSelectionListener);
+               fBackgroundColorEditor = new ColorEditor(backgroundComposite);
+               fBackgroundColorButton = fBackgroundColorEditor.getButton();
+               Label label = new Label(colorComposite, SWT.LEFT);
+               label.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.foreground")); //$NON-NLS-1$
+               label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               Composite editorComposite = new Composite(colorComposite, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               editorComposite.setLayout(layout);
+               GridData gd = new GridData(GridData.FILL_BOTH);
+               editorComposite.setLayoutData(gd);
+               fSyntaxColorList = new List(editorComposite, SWT.SINGLE | SWT.V_SCROLL
+                               | SWT.BORDER);
+               gd = new GridData(GridData.FILL_BOTH);
+               gd.heightHint = convertHeightInCharsToPixels(5);
+               fSyntaxColorList.setLayoutData(gd);
+               Composite stylesComposite = new Composite(editorComposite, SWT.NONE);
+               layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               stylesComposite.setLayout(layout);
+               stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+               label = new Label(stylesComposite, SWT.LEFT);
+               label.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.color")); //$NON-NLS-1$
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gd);
+               fSyntaxForegroundColorEditor = new ColorEditor(stylesComposite);
+               Button foregroundColorButton = fSyntaxForegroundColorEditor.getButton();
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalAlignment = GridData.BEGINNING;
+               foregroundColorButton.setLayoutData(gd);
+               fBoldCheckBox = new Button(stylesComposite, SWT.CHECK);
+               fBoldCheckBox.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.bold")); //$NON-NLS-1$
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalAlignment = GridData.BEGINNING;
+               gd.horizontalSpan = 2;
+               fBoldCheckBox.setLayoutData(gd);
+               label = new Label(colorComposite, SWT.LEFT);
+               label.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.preview")); //$NON-NLS-1$
+               label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               Control previewer = createPreviewer(colorComposite);
+               gd = new GridData(GridData.FILL_BOTH);
+               gd.widthHint = convertWidthInCharsToPixels(20);
+               gd.heightHint = convertHeightInCharsToPixels(5);
+               previewer.setLayoutData(gd);
+               fSyntaxColorList.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               handleSyntaxColorListSelection();
+                       }
+               });
+               foregroundColorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fSyntaxColorList.getSelectionIndex();
+                               String key = fSyntaxColorListModel[i][1];
+                               PreferenceConverter.setValue(fOverlayStore, key,
+                                               fSyntaxForegroundColorEditor.getColorValue());
+                       }
+               });
+               fBackgroundColorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               PreferenceConverter.setValue(fOverlayStore,
+                                               PreferenceConstants.EDITOR_BACKGROUND_COLOR,
+                                               fBackgroundColorEditor.getColorValue());
+                       }
+               });
+               fBoldCheckBox.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fSyntaxColorList.getSelectionIndex();
+                               String key = fSyntaxColorListModel[i][1];
+                               fOverlayStore
+                                               .setValue(key + BOLD, fBoldCheckBox.getSelection());
+                       }
+               });
+               return colorComposite;
+       }
+
+       private Control createPreviewer(Composite parent) {
+               Preferences coreStore = createTemporaryCorePreferenceStore();
+               fJavaTextTools = new JavaTextTools(fOverlayStore, coreStore, false);
+               IPreferenceStore generalTextStore = EditorsUI.getPreferenceStore();
+               IPreferenceStore store = new ChainedPreferenceStore(
+                               new IPreferenceStore[] {
+                                               fOverlayStore,
+                                               new PreferencesAdapter(
+                                                               createTemporaryCorePreferenceStore()),
+                                               generalTextStore });
+
+               fPreviewViewer = new JavaSourceViewer(parent, null, null, false,
+                               SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER, store);
+               JavaTextTools tools = WebUI.getDefault().getJavaTextTools();
+               PHPSourceViewerConfiguration configuration = new PHPSourceViewerConfiguration(
+                               tools.getColorManager(), store, null,
+                               IPHPPartitions.PHP_PARTITIONING);
+               // PHPSourceViewerConfiguration configuration =new
+               // PHPSourceViewerConfiguration(fJavaTextTools, null,
+               // IPHPPartitions.PHP_PARTITIONING);
+               fPreviewViewer.configure(configuration);
+
+               Font font = JFaceResources
+                               .getFont(PreferenceConstants.EDITOR_TEXT_FONT);
+               fPreviewViewer.getTextWidget().setFont(font);
+               new JavaSourcePreviewerUpdater(fPreviewViewer, configuration, store);
+               fPreviewViewer.setEditable(false);
+               String content = loadPreviewContentFromFile("ColorSettingPreviewCode.txt"); //$NON-NLS-1$
+               IDocument document = new Document(content);
+               fJavaTextTools.setupJavaDocumentPartitioner(document,
+                               IPHPPartitions.PHP_PARTITIONING);
+               fPreviewViewer.setDocument(document);
+               return fPreviewViewer.getControl();
+       }
+
+       private Preferences createTemporaryCorePreferenceStore() {
+               Preferences result = new Preferences();
+               result.setValue(COMPILER_TASK_TAGS, "TASK"); //$NON-NLS-1$
+               return result;
+       }
+
+       private Control createAppearancePage(Composite parent) {
+               Composite appearanceComposite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               appearanceComposite.setLayout(layout);
+               
+               // Inserts a hyper-link to the General Editor preferences page
+               // TODO Can probably be removed post 1.5.0?
+               String label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.appearanceTabLink");
+               Link link = new Link(appearanceComposite, SWT.NONE);
+               GridData gridPosition = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gridPosition.horizontalSpan = 2;
+               link.setLayoutData(gridPosition);
+               
+               link.setText(label);
+               link.addListener(SWT.Selection, new Listener () {
+                       public void handleEvent(Event event) {
+                               String u = event.text;
+                               PreferencesUtil.createPreferenceDialogOn(getShell(), u, null, null);
+                       }
+               });
+               String tooltip = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.appearanceTabTooltip");
+               link.setToolTipText(tooltip);           
+                       
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.displayedTabWidth"); //$NON-NLS-1$
+               addTextField(appearanceComposite, label,
+                               PreferenceConstants.EDITOR_TAB_WIDTH, 3, 0, true);
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.printMarginColumn"); //$NON-NLS-1$
+               addTextField(
+                               appearanceComposite,
+                               label,
+                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN,
+                               3, 0, true);
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.showOverviewRuler"); //$NON-NLS-1$
+               addCheckBox(
+                               appearanceComposite,
+                               label,
+                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_OVERVIEW_RULER,
+                               0);
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.highlightMatchingBrackets"); //$NON-NLS-1$
+               addCheckBox(appearanceComposite, label,
+                               PreferenceConstants.EDITOR_MATCHING_BRACKETS, 0);
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.highlightCurrentLine"); //$NON-NLS-1$
+               addCheckBox(
+                               appearanceComposite,
+                               label,
+                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE,
+                               0);
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.showPrintMargin"); //$NON-NLS-1$
+               addCheckBox(
+                               appearanceComposite,
+                               label,
+                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN,
+                               0);
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.markOccurrences"); //$NON-NLS-1$
+               // Button master= addCheckBox(appearanceComposite, label,
+               // PreferenceConstants.EDITOR_MARK_OCCURRENCES, 0); //$NON-NLS-1$
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.stickyOccurrences"); //$NON-NLS-1$
+               // fStickyOccurrencesButton= addCheckBox(appearanceComposite, label,
+               // PreferenceConstants.EDITOR_STICKY_OCCURRENCES, 0); //$NON-NLS-1$
+               // createDependency(master, fStickyOccurrencesButton);
+               Label l = new Label(appearanceComposite, SWT.LEFT);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = 2;
+               gd.heightHint = convertHeightInCharsToPixels(1) / 2;
+               l.setLayoutData(gd);
+               l = new Label(appearanceComposite, SWT.LEFT);
+               l.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.appearanceOptions")); //$NON-NLS-1$
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = 2;
+               l.setLayoutData(gd);
+               Composite editorComposite = new Composite(appearanceComposite, SWT.NONE);
+               layout = new GridLayout();
+               layout.numColumns = 2;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               editorComposite.setLayout(layout);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.FILL_VERTICAL);
+               gd.horizontalSpan = 2;
+               editorComposite.setLayoutData(gd);
+               fAppearanceColorList = new List(editorComposite, SWT.SINGLE
+                               | SWT.V_SCROLL | SWT.BORDER);
+               gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+                               | GridData.FILL_HORIZONTAL);
+               gd.heightHint = convertHeightInCharsToPixels(8);
+               fAppearanceColorList.setLayoutData(gd);
+               Composite stylesComposite = new Composite(editorComposite, SWT.NONE);
+               layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               stylesComposite.setLayout(layout);
+               stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+               l = new Label(stylesComposite, SWT.LEFT);
+               l.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.color")); //$NON-NLS-1$
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.BEGINNING;
+               l.setLayoutData(gd);
+               fAppearanceColorEditor = new ColorEditor(stylesComposite);
+               Button foregroundColorButton = fAppearanceColorEditor.getButton();
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalAlignment = GridData.BEGINNING;
+               foregroundColorButton.setLayoutData(gd);
+               fAppearanceColorList.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               handleAppearanceColorListSelection();
+                       }
+               });
+               foregroundColorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fAppearanceColorList.getSelectionIndex();
+                               String key = fAppearanceColorListModel[i][1];
+                               PreferenceConverter.setValue(fOverlayStore, key,
+                                               fAppearanceColorEditor.getColorValue());
+                       }
+               });
+               return appearanceComposite;
+       }
+
+       // private Control createAnnotationsPage(Composite parent) {
+       // Composite composite = new Composite(parent, SWT.NULL);
+       // GridLayout layout = new GridLayout();
+       // layout.numColumns = 2;
+       // composite.setLayout(layout);
+       // String text = PreferencesMessages
+       // .getString("JavaEditorPreferencePage.analyseAnnotationsWhileTyping");
+       // //$NON-NLS-1$
+       // addCheckBox(composite, text,
+       // PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS, 0);
+       // text = PreferencesMessages
+       // .getString("JavaEditorPreferencePage.showQuickFixables"); //$NON-NLS-1$
+       // addCheckBox(composite, text,
+       // PreferenceConstants.EDITOR_CORRECTION_INDICATION, 0);
+       // addFiller(composite);
+       // Label label = new Label(composite, SWT.LEFT);
+       // label.setText(PreferencesMessages
+       // .getString("JavaEditorPreferencePage.annotationPresentationOptions"));
+       // //$NON-NLS-1$
+       // GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+       // gd.horizontalSpan = 2;
+       // label.setLayoutData(gd);
+       // Composite editorComposite = new Composite(composite, SWT.NONE);
+       // layout = new GridLayout();
+       // layout.numColumns = 2;
+       // layout.marginHeight = 0;
+       // layout.marginWidth = 0;
+       // editorComposite.setLayout(layout);
+       // gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL |
+       // GridData.FILL_VERTICAL);
+       // gd.horizontalSpan = 2;
+       // editorComposite.setLayoutData(gd);
+       // fAnnotationList = new List(editorComposite, SWT.SINGLE | SWT.V_SCROLL
+       // | SWT.BORDER);
+       // gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+       // | GridData.FILL_HORIZONTAL);
+       // gd.heightHint = convertHeightInCharsToPixels(10);
+       // fAnnotationList.setLayoutData(gd);
+       // Composite optionsComposite = new Composite(editorComposite, SWT.NONE);
+       // layout = new GridLayout();
+       // layout.marginHeight = 0;
+       // layout.marginWidth = 0;
+       // layout.numColumns = 2;
+       // optionsComposite.setLayout(layout);
+       // optionsComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+       // fShowInTextCheckBox = new Button(optionsComposite, SWT.CHECK);
+       // fShowInTextCheckBox.setText(PreferencesMessages
+       // .getString("JavaEditorPreferencePage.annotations.showInText"));
+       // //$NON-NLS-1$
+       // gd = new GridData(GridData.FILL_HORIZONTAL);
+       // gd.horizontalAlignment = GridData.BEGINNING;
+       // gd.horizontalSpan = 2;
+       // fShowInTextCheckBox.setLayoutData(gd);
+       // fDecorationStyleCombo = new Combo(optionsComposite, SWT.READ_ONLY);
+       // for (int i = 0; i < fAnnotationDecorationListModel.length; i++)
+       // fDecorationStyleCombo.add(fAnnotationDecorationListModel[i][0]);
+       // gd = new GridData(GridData.FILL_HORIZONTAL);
+       // gd.horizontalAlignment = GridData.BEGINNING;
+       // gd.horizontalSpan = 2;
+       // gd.horizontalIndent = 20;
+       // fDecorationStyleCombo.setLayoutData(gd);
+       // fHighlightInTextCheckBox = new Button(optionsComposite, SWT.CHECK);
+       // fHighlightInTextCheckBox.setText(PreferencesMessages
+       // .getString("TextEditorPreferencePage.annotations.highlightInText"));
+       // //$NON-NLS-1$
+       // gd = new GridData(GridData.FILL_HORIZONTAL);
+       // gd.horizontalAlignment = GridData.BEGINNING;
+       // gd.horizontalSpan = 2;
+       // fHighlightInTextCheckBox.setLayoutData(gd);
+       // fShowInOverviewRulerCheckBox = new Button(optionsComposite, SWT.CHECK);
+       // fShowInOverviewRulerCheckBox.setText(PreferencesMessages
+       // .getString("JavaEditorPreferencePage.annotations.showInOverviewRuler"));
+       // //$NON-NLS-1$
+       // gd = new GridData(GridData.FILL_HORIZONTAL);
+       // gd.horizontalAlignment = GridData.BEGINNING;
+       // gd.horizontalSpan = 2;
+       // fShowInOverviewRulerCheckBox.setLayoutData(gd);
+       // fShowInVerticalRulerCheckBox = new Button(optionsComposite, SWT.CHECK);
+       // fShowInVerticalRulerCheckBox.setText(PreferencesMessages
+       // .getString("JavaEditorPreferencePage.annotations.showInVerticalRuler"));
+       // //$NON-NLS-1$
+       // gd = new GridData(GridData.FILL_HORIZONTAL);
+       // gd.horizontalAlignment = GridData.BEGINNING;
+       // gd.horizontalSpan = 2;
+       // fShowInVerticalRulerCheckBox.setLayoutData(gd);
+       // label = new Label(optionsComposite, SWT.LEFT);
+       // label.setText(PreferencesMessages
+       // .getString("JavaEditorPreferencePage.annotations.color")); //$NON-NLS-1$
+       // gd = new GridData();
+       // gd.horizontalAlignment = GridData.BEGINNING;
+       // label.setLayoutData(gd);
+       // fAnnotationForegroundColorEditor = new ColorEditor(optionsComposite);
+       // Button foregroundColorButton =
+       // fAnnotationForegroundColorEditor.getButton();
+       // gd = new GridData(GridData.FILL_HORIZONTAL);
+       // gd.horizontalAlignment = GridData.BEGINNING;
+       // foregroundColorButton.setLayoutData(gd);
+       // fAnnotationList.addSelectionListener(new SelectionListener() {
+       // public void widgetDefaultSelected(SelectionEvent e) {
+       // // do nothing
+       // }
+       // public void widgetSelected(SelectionEvent e) {
+       // handleAnnotationListSelection();
+       // }
+       // });
+       // fShowInTextCheckBox.addSelectionListener(new SelectionListener() {
+       // public void widgetDefaultSelected(SelectionEvent e) {
+       // // do nothing
+       // }
+       // public void widgetSelected(SelectionEvent e) {
+       // int i = fAnnotationList.getSelectionIndex();
+       // String key = fAnnotationColorListModel[i][2];
+       // fOverlayStore.setValue(key, fShowInTextCheckBox.getSelection());
+       // String decorationKey = fAnnotationColorListModel[i][6];
+       // fDecorationStyleCombo.setEnabled(decorationKey != null
+       // && fShowInTextCheckBox.getSelection());
+       // }
+       // });
+       // fHighlightInTextCheckBox.addSelectionListener(new SelectionListener() {
+       // public void widgetDefaultSelected(SelectionEvent e) {
+       // // do nothing
+       // }
+       // public void widgetSelected(SelectionEvent e) {
+       // int i = fAnnotationList.getSelectionIndex();
+       // String key = fAnnotationColorListModel[i][4];
+       // fOverlayStore.setValue(key, fHighlightInTextCheckBox.getSelection());
+       // }
+       // });
+       // fShowInOverviewRulerCheckBox.addSelectionListener(new SelectionListener()
+       // {
+       // public void widgetDefaultSelected(SelectionEvent e) {
+       // // do nothing
+       // }
+       // public void widgetSelected(SelectionEvent e) {
+       // int i = fAnnotationList.getSelectionIndex();
+       // String key = fAnnotationColorListModel[i][3];
+       // fOverlayStore
+       // .setValue(key, fShowInOverviewRulerCheckBox.getSelection());
+       // }
+       // });
+       // fShowInVerticalRulerCheckBox.addSelectionListener(new SelectionListener()
+       // {
+       // public void widgetDefaultSelected(SelectionEvent e) {
+       // // do nothing
+       // }
+       // public void widgetSelected(SelectionEvent e) {
+       // int i = fAnnotationList.getSelectionIndex();
+       // String key = fAnnotationColorListModel[i][5];
+       // fOverlayStore
+       // .setValue(key, fShowInVerticalRulerCheckBox.getSelection());
+       // }
+       // });
+       // foregroundColorButton.addSelectionListener(new SelectionListener() {
+       // public void widgetDefaultSelected(SelectionEvent e) {
+       // // do nothing
+       // }
+       // public void widgetSelected(SelectionEvent e) {
+       // int i = fAnnotationList.getSelectionIndex();
+       // String key = fAnnotationColorListModel[i][1];
+       // PreferenceConverter.setValue(fOverlayStore, key,
+       // fAnnotationForegroundColorEditor.getColorValue());
+       // }
+       // });
+       // fDecorationStyleCombo.addSelectionListener(new SelectionListener() {
+       // /**
+       // * {@inheritdoc}
+       // */
+       // public void widgetDefaultSelected(SelectionEvent e) {
+       // // do nothing
+       // }
+       // /**
+       // * {@inheritdoc}
+       // */
+       // public void widgetSelected(SelectionEvent e) {
+       // int i = fAnnotationList.getSelectionIndex();
+       // String key = fAnnotationColorListModel[i][6];
+       // if (key != null) {
+       // for (int j = 0; j < fAnnotationDecorationListModel.length; j++) {
+       // if (fAnnotationDecorationListModel[j][0]
+       // .equals(fDecorationStyleCombo.getText())) {
+       // fOverlayStore.setValue(key, fAnnotationDecorationListModel[j][1]);
+       // break;
+       // }
+       // }
+       // }
+       // }
+       // });
+       // return composite;
+       // }
+       private String[][] createAnnotationTypeListModel(
+                       MarkerAnnotationPreferences preferences) {
+               ArrayList listModelItems = new ArrayList();
+               SortedSet sortedPreferences = new TreeSet(new Comparator() {
+                       /*
+                        * @see java.util.Comparator#compare(java.lang.Object,
+                        *      java.lang.Object)
+                        */
+                       public int compare(Object o1, Object o2) {
+                               if (!(o2 instanceof AnnotationPreference))
+                                       return -1;
+                               if (!(o1 instanceof AnnotationPreference))
+                                       return 1;
+                               AnnotationPreference a1 = (AnnotationPreference) o1;
+                               AnnotationPreference a2 = (AnnotationPreference) o2;
+                               return Collator.getInstance().compare(a1.getPreferenceLabel(),
+                                               a2.getPreferenceLabel());
+                       }
+               });
+               sortedPreferences.addAll(preferences.getAnnotationPreferences());
+               Iterator e = sortedPreferences.iterator();
+               while (e.hasNext()) {
+                       AnnotationPreference info = (AnnotationPreference) e.next();
+                       listModelItems.add(new String[] { info.getPreferenceLabel(),
+                                       info.getColorPreferenceKey(), info.getTextPreferenceKey(),
+                                       info.getOverviewRulerPreferenceKey(),
+                                       info.getHighlightPreferenceKey(),
+                                       info.getVerticalRulerPreferenceKey(),
+                                       info.getTextStylePreferenceKey() });
+               }
+               String[][] items = new String[listModelItems.size()][];
+               listModelItems.toArray(items);
+               return items;
+       }
+
+       private Control createTypingPage(Composite parent) {
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               composite.setLayout(layout);
+               String label;
+               // label = PreferencesMessages
+               // .getString("JavaEditorPreferencePage.overwriteMode");
+               // //$NON-NLS-1$
+               // addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE, 1);
+               // addFiller(composite);
+               //
+               // label = PreferencesMessages
+               // .getString("JavaEditorPreferencePage.smartHomeEnd");
+               // //$NON-NLS-1$
+               // addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_SMART_HOME_END, 1);
+               //
+               // label = PreferencesMessages
+               // .getString("JavaEditorPreferencePage.subWordNavigation");
+               // //$NON-NLS-1$
+               // addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION, 1);
+               // addFiller(composite);
+               Group group = new Group(composite, SWT.NONE);
+               layout = new GridLayout();
+               layout.numColumns = 2;
+               group.setLayout(layout);
+               group.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.typing.description")); //$NON-NLS-1$
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.wrapWords");//$NON-NLS-1$
+               addCheckBox(group, label, PreferenceConstants.EDITOR_WRAP_WORDS, 1);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.wrapStringsDQ");//$NON-NLS-1$
+               Button button = addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_WRAP_STRINGS_DQ, 1);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.escapeStringsDQ");//$NON-NLS-1$
+               fEscapeStringsButtonDQ = addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_ESCAPE_STRINGS_DQ, 1);
+               createDependency(button, fEscapeStringsButtonDQ);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.wrapStringsSQ");//$NON-NLS-1$
+               button = addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_WRAP_STRINGS_SQ, 1);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.escapeStringsSQ");
+               //$NON-NLS-1$
+               fEscapeStringsButtonSQ = addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_ESCAPE_STRINGS_SQ, 1);
+               createDependency(button, fEscapeStringsButtonSQ);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.smartPaste");
+               //$NON-NLS-1$
+               addCheckBox(group, label, PreferenceConstants.EDITOR_SMART_PASTE, 1);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.insertSpaceForTabs");
+               //$NON-NLS-1$
+               addCheckBox(group, label, PreferenceConstants.EDITOR_SPACES_FOR_TABS, 1);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.closeStringsDQ");
+               //$NON-NLS-1$
+               addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_CLOSE_STRINGS_DQ_PHP, 1);
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.closeStringsSQ");
+               //$NON-NLS-1$
+               addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_CLOSE_STRINGS_SQ_PHP, 1);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.closeBrackets");
+               //$NON-NLS-1$
+               addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP, 1);
+
+               // label = PreferencesMessages
+               // .getString("JavaEditorPreferencePage.closeBraces");
+               // //$NON-NLS-1$
+               // addCheckBox(group, label, PreferenceConstants.EDITOR_CLOSE_BRACES,
+               // 1);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.closeJavaDocs");
+               //$NON-NLS-1$
+               button = addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_CLOSE_JAVADOCS, 1);
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.formatJavaDocs");
+               //$NON-NLS-1$
+               button = addCheckBox(group, label,
+                               PreferenceConstants.EDITOR_FORMAT_JAVADOCS, 1);
+
+               //
+               // label = PreferencesMessages
+               // .getString("JavaEditorPreferencePage.addJavaDocTags");
+               // //$NON-NLS-1$
+               // fAddJavaDocTagsButton = addCheckBox(group, label,
+               // PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS, 1);
+               // createDependency(button, fAddJavaDocTagsButton);
+               return composite;
+       }
+
+       private void addFiller(Composite composite) {
+               Label filler = new Label(composite, SWT.LEFT);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = 2;
+               gd.heightHint = convertHeightInCharsToPixels(1) / 2;
+               filler.setLayoutData(gd);
+       }
+
+       private static void indent(Control control) {
+               GridData gridData = new GridData();
+               gridData.horizontalIndent = 20;
+               control.setLayoutData(gridData);
+       }
+
+       private static void createDependency(final Button master,
+                       final Control slave) {
+               indent(slave);
+               master.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               slave.setEnabled(master.getSelection());
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+       }
+
+       private void addCompletionRadioButtons(Composite contentAssistComposite) {
+               Composite completionComposite = new Composite(contentAssistComposite,
+                               SWT.NONE);
+               GridData ccgd = new GridData();
+               ccgd.horizontalSpan = 2;
+               completionComposite.setLayoutData(ccgd);
+               GridLayout ccgl = new GridLayout();
+               ccgl.marginWidth = 0;
+               ccgl.numColumns = 2;
+               completionComposite.setLayout(ccgl);
+               // SelectionListener completionSelectionListener= new SelectionAdapter()
+               // {
+               // public void widgetSelected(SelectionEvent e) {
+               // boolean insert= fCompletionInsertsRadioButton.getSelection();
+               // fOverlayStore.setValue(PreferenceConstants.CODEASSIST_INSERT_COMPLETION,
+               // insert);
+               // }
+               // };
+               //
+               // fCompletionInsertsRadioButton= new Button(completionComposite,
+               // SWT.RADIO
+               // | SWT.LEFT);
+               // fCompletionInsertsRadioButton.setText(PreferencesMessages.getString("JavaEditorPreferencePage.completionInserts"));
+               // //$NON-NLS-1$
+               // fCompletionInsertsRadioButton.setLayoutData(new GridData());
+               // fCompletionInsertsRadioButton.addSelectionListener(completionSelectionListener);
+               //
+               // fCompletionOverwritesRadioButton= new Button(completionComposite,
+               // SWT.RADIO | SWT.LEFT);
+               // fCompletionOverwritesRadioButton.setText(PreferencesMessages.getString("JavaEditorPreferencePage.completionOverwrites"));
+               // //$NON-NLS-1$
+               // fCompletionOverwritesRadioButton.setLayoutData(new GridData());
+               // fCompletionOverwritesRadioButton.addSelectionListener(completionSelectionListener);
+       }
+
+       private Control createNavigationPage(Composite parent) {
+               Composite composite = new Composite(parent, SWT.NULL);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               composite.setLayout(layout);
+               String text = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.navigation.browserLikeLinks");
+               //$NON-NLS-1$
+               fBrowserLikeLinksCheckBox = addCheckBox(composite, text,
+                               PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS, 0);
+               fBrowserLikeLinksCheckBox.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               boolean state = fBrowserLikeLinksCheckBox.getSelection();
+                               fBrowserLikeLinksKeyModifierText.setEnabled(state);
+                               handleBrowserLikeLinksKeyModifierModified();
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+               // Text field for modifier string
+               text = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.navigation.browserLikeLinksKeyModifier");
+               //$NON-NLS-1$
+               fBrowserLikeLinksKeyModifierText = addTextField(composite, text,
+                               PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER, 20,
+                               0, false);
+               fBrowserLikeLinksKeyModifierText.setTextLimit(Text.LIMIT);
+
+               if (computeStateMask(fOverlayStore
+                               .getString(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER)) == -1) {
+                       // Fix possible illegal modifier string
+                       int stateMask = fOverlayStore
+                                       .getInt(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK);
+                       if (stateMask == -1)
+                               fBrowserLikeLinksKeyModifierText.setText(""); //$NON-NLS-1$
+                       else
+                               fBrowserLikeLinksKeyModifierText.setText(EditorUtility
+                                               .getModifierString(stateMask));
+               }
+               fBrowserLikeLinksKeyModifierText.addKeyListener(new KeyListener() {
+                       private boolean isModifierCandidate;
+
+                       public void keyPressed(KeyEvent e) {
+                               isModifierCandidate = e.keyCode > 0 && e.character == 0
+                                               && e.stateMask == 0;
+                       }
+
+                       public void keyReleased(KeyEvent e) {
+                               if (isModifierCandidate && e.stateMask > 0
+                                               && e.stateMask == e.stateMask && e.character == 0) {// &&
+                                                                                                                                                       // e.time
+                                                                                                                                                       // -time
+                                                                                                                                                       // <
+                                                                                                                                                       // 1000)
+                                                                                                                                                       // {
+                                       String modifierString = fBrowserLikeLinksKeyModifierText
+                                                       .getText();
+                                       Point selection = fBrowserLikeLinksKeyModifierText
+                                                       .getSelection();
+                                       int i = selection.x - 1;
+                                       while (i > -1
+                                                       && Character.isWhitespace(modifierString.charAt(i))) {
+                                               i--;
+                                       }
+                                       boolean needsPrefixDelimiter = i > -1
+                                                       && !String.valueOf(modifierString.charAt(i))
+                                                                       .equals(DELIMITER);
+
+                                       i = selection.y;
+                                       while (i < modifierString.length()
+                                                       && Character.isWhitespace(modifierString.charAt(i))) {
+                                               i++;
+                                       }
+                                       boolean needsPostfixDelimiter = i < modifierString.length()
+                                                       && !String.valueOf(modifierString.charAt(i))
+                                                                       .equals(DELIMITER);
+
+                                       String insertString;
+
+                                       if (needsPrefixDelimiter && needsPostfixDelimiter)
+                                               insertString = PreferencesMessages
+                                                               .getFormattedString(
+                                                                               "JavaEditorPreferencePage.navigation.insertDelimiterAndModifierAndDelimiter",
+                                                                               new String[] { Action
+                                                                                               .findModifierString(e.stateMask) }); //$NON-NLS-1$
+                                       else if (needsPrefixDelimiter)
+                                               insertString = PreferencesMessages
+                                                               .getFormattedString(
+                                                                               "JavaEditorPreferencePage.navigation.insertDelimiterAndModifier",
+                                                                               new String[] { Action
+                                                                                               .findModifierString(e.stateMask) }); //$NON-NLS-1$
+                                       else if (needsPostfixDelimiter)
+                                               insertString = PreferencesMessages
+                                                               .getFormattedString(
+                                                                               "JavaEditorPreferencePage.navigation.insertModifierAndDelimiter",
+                                                                               new String[] { Action
+                                                                                               .findModifierString(e.stateMask) }); //$NON-NLS-1$
+                                       else
+                                               insertString = Action.findModifierString(e.stateMask);
+
+                                       fBrowserLikeLinksKeyModifierText.insert(insertString);
+                               }
+                       }
+               });
+
+               fBrowserLikeLinksKeyModifierText
+                               .addModifyListener(new ModifyListener() {
+                                       public void modifyText(ModifyEvent e) {
+                                               handleBrowserLikeLinksKeyModifierModified();
+                                       }
+                               });
+               return composite;
+       }
+
+       private void handleBrowserLikeLinksKeyModifierModified() {
+               String modifiers = fBrowserLikeLinksKeyModifierText.getText();
+               int stateMask = computeStateMask(modifiers);
+               if (fBrowserLikeLinksCheckBox.getSelection()
+                               && (stateMask == -1 || (stateMask & SWT.SHIFT) != 0)) {
+                       if (stateMask == -1)
+                               fBrowserLikeLinksKeyModifierStatus = new StatusInfo(
+                                               IStatus.ERROR,
+                                               PreferencesMessages
+                                                               .getFormattedString(
+                                                                               "JavaEditorPreferencePage.navigation.modifierIsNotValid", modifiers)); //$NON-NLS-1$
+                       else
+                               fBrowserLikeLinksKeyModifierStatus = new StatusInfo(
+                                               IStatus.ERROR,
+                                               PreferencesMessages
+                                                               .getString("JavaEditorPreferencePage.navigation.shiftIsDisabled"));
+                       //$NON-NLS-1$
+                       setValid(false);
+                       StatusUtil.applyToStatusLine(this,
+                                       fBrowserLikeLinksKeyModifierStatus);
+               } else {
+                       fBrowserLikeLinksKeyModifierStatus = new StatusInfo();
+                       updateStatus(fBrowserLikeLinksKeyModifierStatus);
+               }
+       }
+
+       private IStatus getBrowserLikeLinksKeyModifierStatus() {
+               if (fBrowserLikeLinksKeyModifierStatus == null)
+                       fBrowserLikeLinksKeyModifierStatus = new StatusInfo();
+               return fBrowserLikeLinksKeyModifierStatus;
+       }
+
+       /**
+        * Computes the state mask for the given modifier string.
+        * 
+        * @param modifiers
+        *            the string with the modifiers, separated by '+', '-', ';', ','
+        *            or '.'
+        * @return the state mask or -1 if the input is invalid
+        */
+       private int computeStateMask(String modifiers) {
+               if (modifiers == null)
+                       return -1;
+               if (modifiers.length() == 0)
+                       return SWT.NONE;
+               int stateMask = 0;
+               StringTokenizer modifierTokenizer = new StringTokenizer(modifiers,
+                               ",;.:+-* "); //$NON-NLS-1$
+               while (modifierTokenizer.hasMoreTokens()) {
+                       int modifier = EditorUtility
+                                       .findLocalizedModifier(modifierTokenizer.nextToken());
+                       if (modifier == 0 || (stateMask & modifier) == modifier)
+                               return -1;
+                       stateMask = stateMask | modifier;
+               }
+               return stateMask;
+       }
+
+       /*
+        * @see PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+               initializeDefaultColors();
+               fFoldingConfigurationBlock = new FoldingConfigurationBlock(
+                               fOverlayStore);
+               fOverlayStore.load();
+               fOverlayStore.start();
+               TabFolder folder = new TabFolder(parent, SWT.NONE);
+               folder.setLayout(new TabFolderLayout());
+               folder.setLayoutData(new GridData(GridData.FILL_BOTH));
+               TabItem item = new TabItem(folder, SWT.NONE);
+               item.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.general")); //$NON-NLS-1$
+               item.setControl(createAppearancePage(folder));
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.colors")); //$NON-NLS-1$
+               item.setControl(createSyntaxPage(folder));
+
+               // item = new TabItem(folder, SWT.NONE);
+               // item.setText(PreferencesMessages
+               // .getString("JavaEditorPreferencePage.annotationsTab.title"));
+               // //$NON-NLS-1$
+               // item.setControl(createAnnotationsPage(folder));
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.typing.tabTitle"));
+               //$NON-NLS-1$
+               item.setControl(createTypingPage(folder));
+
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.hoverTab.title"));
+               //$NON-NLS-1$
+               fJavaEditorHoverConfigurationBlock = new JavaEditorHoverConfigurationBlock(
+                               this, fOverlayStore);
+               item.setControl(fJavaEditorHoverConfigurationBlock
+                               .createControl(folder));
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.navigationTab.title"));
+               // //$NON-NLS-1$
+               item.setControl(createNavigationPage(folder));
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(PreferencesMessages
+                               .getString("JavaEditorPreferencePage.folding.title")); //$NON-NLS-1$
+               item.setControl(fFoldingConfigurationBlock.createControl(folder));
+
+               initialize();
+               Dialog.applyDialogFont(folder);
+               return folder;
+       }
+
+       private void initialize() {
+               initializeFields();
+               for (int i = 0; i < fSyntaxColorListModel.length; i++)
+                       fSyntaxColorList.add(fSyntaxColorListModel[i][0]);
+               fSyntaxColorList.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if (fSyntaxColorList != null && !fSyntaxColorList.isDisposed()) {
+                                       fSyntaxColorList.select(0);
+                                       handleSyntaxColorListSelection();
+                               }
+                       }
+               });
+               for (int i = 0; i < fAppearanceColorListModel.length; i++)
+                       fAppearanceColorList.add(fAppearanceColorListModel[i][0]);
+               fAppearanceColorList.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if (fAppearanceColorList != null
+                                               && !fAppearanceColorList.isDisposed()) {
+                                       fAppearanceColorList.select(0);
+                                       handleAppearanceColorListSelection();
+                               }
+                       }
+               });
+               // for (int i = 0; i < fAnnotationColorListModel.length; i++)
+               // fAnnotationList.add(fAnnotationColorListModel[i][0]);
+               // fAnnotationList.getDisplay().asyncExec(new Runnable() {
+               // public void run() {
+               // if (fAnnotationList != null && !fAnnotationList.isDisposed()) {
+               // fAnnotationList.select(0);
+               // handleAnnotationListSelection();
+               // }
+               // }
+               // });
+               // for (int i= 0; i < fContentAssistColorListModel.length; i++)
+               // fContentAssistColorList.add(fContentAssistColorListModel[i][0]);
+               // fContentAssistColorList.getDisplay().asyncExec(new Runnable() {
+               // public void run() {
+               // if (fContentAssistColorList != null &&
+               // !fContentAssistColorList.isDisposed()) {
+               // fContentAssistColorList.select(0);
+               // handleContentAssistColorListSelection();
+               // }
+               // }
+               // });
+               fFoldingConfigurationBlock.initialize();
+       }
+
+       private void initializeFields() {
+               Iterator e = fColorButtons.keySet().iterator();
+               while (e.hasNext()) {
+                       ColorEditor c = (ColorEditor) e.next();
+                       String key = (String) fColorButtons.get(c);
+                       RGB rgb = PreferenceConverter.getColor(fOverlayStore, key);
+                       c.setColorValue(rgb);
+               }
+               e = fCheckBoxes.keySet().iterator();
+               while (e.hasNext()) {
+                       Button b = (Button) e.next();
+                       String key = (String) fCheckBoxes.get(b);
+                       b.setSelection(fOverlayStore.getBoolean(key));
+               }
+               e = fTextFields.keySet().iterator();
+               while (e.hasNext()) {
+                       Text t = (Text) e.next();
+                       String key = (String) fTextFields.get(t);
+                       t.setText(fOverlayStore.getString(key));
+               }
+               RGB rgb = PreferenceConverter.getColor(fOverlayStore,
+                               PreferenceConstants.EDITOR_BACKGROUND_COLOR);
+               fBackgroundColorEditor.setColorValue(rgb);
+               boolean default_ = fOverlayStore
+                               .getBoolean(PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR);
+               fBackgroundDefaultRadioButton.setSelection(default_);
+               fBackgroundCustomRadioButton.setSelection(!default_);
+               fBackgroundColorButton.setEnabled(!default_);
+               boolean closeJavaDocs = fOverlayStore
+                               .getBoolean(PreferenceConstants.EDITOR_CLOSE_JAVADOCS);
+               // fAddJavaDocTagsButton.setEnabled(closeJavaDocs);
+               fEscapeStringsButtonDQ.setEnabled(fOverlayStore
+                               .getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS_DQ));
+               fEscapeStringsButtonSQ.setEnabled(fOverlayStore
+                               .getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS_SQ));
+               // boolean fillMethodArguments=
+               // fOverlayStore.getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES);
+               // fGuessMethodArgumentsButton.setEnabled(fillMethodArguments);
+               // boolean completionInserts=
+               // fOverlayStore.getBoolean(PreferenceConstants.CODEASSIST_INSERT_COMPLETION);
+               // fCompletionInsertsRadioButton.setSelection(completionInserts);
+               // fCompletionOverwritesRadioButton.setSelection(! completionInserts);
+               //
+               fBrowserLikeLinksKeyModifierText.setEnabled(fBrowserLikeLinksCheckBox
+                               .getSelection());
+               // boolean markOccurrences=
+               // fOverlayStore.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES);
+               // fStickyOccurrencesButton.setEnabled(markOccurrences);
+               updateAutoactivationControls();
+       }
+
+       private void initializeDefaultColors() {
+               if (!getPreferenceStore().contains(
+                               PreferenceConstants.EDITOR_BACKGROUND_COLOR)) {
+                       RGB rgb = getControl().getDisplay().getSystemColor(
+                                       SWT.COLOR_LIST_BACKGROUND).getRGB();
+                       PreferenceConverter.setDefault(fOverlayStore,
+                                       PreferenceConstants.EDITOR_BACKGROUND_COLOR, rgb);
+                       PreferenceConverter.setDefault(getPreferenceStore(),
+                                       PreferenceConstants.EDITOR_BACKGROUND_COLOR, rgb);
+               }
+               if (!getPreferenceStore().contains(
+                               PreferenceConstants.EDITOR_FOREGROUND_COLOR)) {
+                       RGB rgb = getControl().getDisplay().getSystemColor(
+                                       SWT.COLOR_LIST_FOREGROUND).getRGB();
+                       PreferenceConverter.setDefault(fOverlayStore,
+                                       PreferenceConstants.EDITOR_FOREGROUND_COLOR, rgb);
+                       PreferenceConverter.setDefault(getPreferenceStore(),
+                                       PreferenceConstants.EDITOR_FOREGROUND_COLOR, rgb);
+               }
+       }
+
+       private void updateAutoactivationControls() {
+               // boolean autoactivation=
+               // fOverlayStore.getBoolean(PreferenceConstants.CODEASSIST_AUTOACTIVATION);
+               // fAutoInsertDelayText.setEnabled(autoactivation);
+               // fAutoInsertDelayLabel.setEnabled(autoactivation);
+               // fAutoInsertJavaTriggerText.setEnabled(autoactivation);
+               // fAutoInsertJavaTriggerLabel.setEnabled(autoactivation);
+               //
+               // fAutoInsertJavaDocTriggerText.setEnabled(autoactivation);
+               // fAutoInsertJavaDocTriggerLabel.setEnabled(autoactivation);
+       }
+
+       /*
+        * @see PreferencePage#performOk()
+        */
+       public boolean performOk() {
+               // fJavaEditorHoverConfigurationBlock.performOk();
+               fFoldingConfigurationBlock.performOk();
+               fOverlayStore
+                               .setValue(
+                                               PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK,
+                                               computeStateMask(fBrowserLikeLinksKeyModifierText
+                                                               .getText()));
+               fOverlayStore.propagate();
+               WebUI.getDefault().savePluginPreferences();
+               return true;
+       }
+
+       /*
+        * @see PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               fOverlayStore.loadDefaults();
+               initializeFields();
+               handleSyntaxColorListSelection();
+               handleAppearanceColorListSelection();
+               // handleAnnotationListSelection();
+               // handleContentAssistColorListSelection();
+               // fJavaEditorHoverConfigurationBlock.performDefaults();
+               fFoldingConfigurationBlock.performDefaults();
+               super.performDefaults();
+               fPreviewViewer.invalidateTextPresentation();
+       }
+
+       /*
+        * @see DialogPage#dispose()
+        */
+       public void dispose() {
+               fFoldingConfigurationBlock.dispose();
+
+               if (fJavaTextTools != null) {
+                       fJavaTextTools.dispose();
+                       fJavaTextTools = null;
+               }
+               if (fOverlayStore != null) {
+                       fOverlayStore.stop();
+                       fOverlayStore = null;
+               }
+               if (fBackgroundColor != null && !fBackgroundColor.isDisposed())
+                       fBackgroundColor.dispose();
+               super.dispose();
+       }
+
+       private Button addCheckBox(Composite parent, String label, String key,
+                       int indentation) {
+               Button checkBox = new Button(parent, SWT.CHECK);
+               checkBox.setText(label);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indentation;
+               gd.horizontalSpan = 2;
+               checkBox.setLayoutData(gd);
+               checkBox.addSelectionListener(fCheckBoxListener);
+               fCheckBoxes.put(checkBox, key);
+               return checkBox;
+       }
+
+       private Text addTextField(Composite composite, String label, String key,
+                       int textLimit, int indentation, boolean isNumber) {
+               return getTextControl(addLabelledTextField(composite, label, key,
+                               textLimit, indentation, isNumber));
+       }
+
+       private static Label getLabelControl(Control[] labelledTextField) {
+               return (Label) labelledTextField[0];
+       }
+
+       private static Text getTextControl(Control[] labelledTextField) {
+               return (Text) labelledTextField[1];
+       }
+
+       /**
+        * Returns an array of size 2: - first element is of type <code>Label</code>-
+        * second element is of type <code>Text</code> Use
+        * <code>getLabelControl</code> and <code>getTextControl</code> to get
+        * the 2 controls.
+        */
+       private Control[] addLabelledTextField(Composite composite, String label,
+                       String key, int textLimit, int indentation, boolean isNumber) {
+               Label labelControl = new Label(composite, SWT.NONE);
+               labelControl.setText(label);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indentation;
+               labelControl.setLayoutData(gd);
+               Text textControl = new Text(composite, SWT.BORDER | SWT.SINGLE);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.widthHint = convertWidthInCharsToPixels(textLimit + 1);
+               textControl.setLayoutData(gd);
+               textControl.setTextLimit(textLimit);
+               fTextFields.put(textControl, key);
+               if (isNumber) {
+                       fNumberFields.add(textControl);
+                       textControl.setText("0");
+                       textControl.addModifyListener(fNumberFieldListener);
+               } else {
+                       textControl.addModifyListener(fTextFieldListener);
+               }
+               return new Control[] { labelControl, textControl };
+       }
+
+       private String loadPreviewContentFromFile(String filename) {
+               String line;
+               String separator = System.getProperty("line.separator"); //$NON-NLS-1$
+               StringBuffer buffer = new StringBuffer(512);
+               BufferedReader reader = null;
+               try {
+                       reader = new BufferedReader(new InputStreamReader(getClass()
+                                       .getResourceAsStream(filename)));
+                       while ((line = reader.readLine()) != null) {
+                               buffer.append(line);
+                               buffer.append(separator);
+                       }
+               } catch (IOException io) {
+                       WebUI.log(io);
+               } finally {
+                       if (reader != null) {
+                               try {
+                                       reader.close();
+                               } catch (IOException e) {
+                               }
+                       }
+               }
+               return buffer.toString();
+       }
+
+       private void numberFieldChanged(Text textControl) {
+               String number = textControl.getText();
+               IStatus status = validatePositiveNumber(number);
+               if (!status.matches(IStatus.ERROR))
+                       fOverlayStore.setValue((String) fTextFields.get(textControl),
+                                       number);
+               updateStatus(status);
+       }
+
+       private IStatus validatePositiveNumber(String number) {
+               StatusInfo status = new StatusInfo();
+               if (number.length() == 0) {
+                       status.setError(PreferencesMessages
+                                       .getString("JavaEditorPreferencePage.empty_input")); //$NON-NLS-1$
+               } else {
+                       try {
+                               int value = Integer.parseInt(number);
+                               if (value < 0)
+                                       status.setError(PreferencesMessages.getFormattedString(
+                                                       "JavaEditorPreferencePage.invalid_input", number)); //$NON-NLS-1$
+                       } catch (NumberFormatException e) {
+                               status.setError(PreferencesMessages.getFormattedString(
+                                               "JavaEditorPreferencePage.invalid_input", number)); //$NON-NLS-1$
+                       }
+               }
+               return status;
+       }
+
+       void updateStatus(IStatus status) {
+               if (!status.matches(IStatus.ERROR)) {
+                       for (int i = 0; i < fNumberFields.size(); i++) {
+                               Text text = (Text) fNumberFields.get(i);
+                               IStatus s = validatePositiveNumber(text.getText());
+                               status = StatusUtil.getMoreSevere(s, status);
+                       }
+               }
+               // status=
+               // StatusUtil.getMoreSevere(fJavaEditorHoverConfigurationBlock.getStatus(),
+               // status);
+               // status=
+               // StatusUtil.getMoreSevere(getBrowserLikeLinksKeyModifierStatus(),
+               // status);
+               setValid(!status.matches(IStatus.ERROR));
+               StatusUtil.applyToStatusLine(this, status);
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaPreferencesSettings.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaPreferencesSettings.java
new file mode 100644 (file)
index 0000000..bbb7687
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.internal.corext.codemanipulation.CodeGenerationSettings;
+import net.sourceforge.phpdt.internal.corext.util.CodeFormatterUtil;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+public class JavaPreferencesSettings {
+
+       public static CodeGenerationSettings getCodeGenerationSettings() {
+               IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+
+               CodeGenerationSettings res = new CodeGenerationSettings();
+               res.createComments = store
+                               .getBoolean(PreferenceConstants.CODEGEN_ADD_COMMENTS);
+               res.useKeywordThis = store
+                               .getBoolean(PreferenceConstants.CODEGEN_KEYWORD_THIS);
+               // res.importOrder= getImportOrderPreference(store);
+               res.importThreshold = getImportNumberThreshold(store);
+               res.tabWidth = CodeFormatterUtil.getTabWidth();
+               return res;
+       }
+
+       public static int getImportNumberThreshold(IPreferenceStore prefs) {
+               int threshold = prefs
+                               .getInt(PreferenceConstants.ORGIMPORTS_ONDEMANDTHRESHOLD);
+               if (threshold < 0) {
+                       threshold = Integer.MAX_VALUE;
+               }
+               return threshold;
+       }
+
+       // public static String[] getImportOrderPreference(IPreferenceStore prefs) {
+       // String str= prefs.getString(PreferenceConstants.ORGIMPORTS_IMPORTORDER);
+       // if (str != null) {
+       // return unpackList(str, ";"); //$NON-NLS-1$
+       // }
+       // return new String[0];
+       // }
+
+       private static String[] unpackList(String str, String separator) {
+               StringTokenizer tok = new StringTokenizer(str, separator); //$NON-NLS-1$
+               int nTokens = tok.countTokens();
+               String[] res = new String[nTokens];
+               for (int i = 0; i < nTokens; i++) {
+                       res[i] = tok.nextToken().trim();
+               }
+               return res;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaSourcePreviewerUpdater.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaSourcePreviewerUpdater.java
new file mode 100644 (file)
index 0000000..5fedc3a
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * Handles Java editor font changes for Java source preview viewers.
+ * 
+ * @since 3.0
+ */
+class JavaSourcePreviewerUpdater {
+
+       /**
+        * Creates a Java source preview updater for the given viewer, configuration
+        * and preference store.
+        * 
+        * @param viewer
+        *            the viewer
+        * @param configuration
+        *            the configuration
+        * @param preferenceStore
+        *            the preference store
+        */
+       JavaSourcePreviewerUpdater(final SourceViewer viewer,
+                       final PHPSourceViewerConfiguration configuration,
+                       final IPreferenceStore preferenceStore) {
+               Assert.isNotNull(viewer);
+               Assert.isNotNull(configuration);
+               Assert.isNotNull(preferenceStore);
+               final IPropertyChangeListener fontChangeListener = new IPropertyChangeListener() {
+                       /*
+                        * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+                        */
+                       public void propertyChange(PropertyChangeEvent event) {
+                               if (event.getProperty().equals(
+                                               PreferenceConstants.EDITOR_TEXT_FONT)) {
+                                       Font font = JFaceResources
+                                                       .getFont(PreferenceConstants.EDITOR_TEXT_FONT);
+                                       viewer.getTextWidget().setFont(font);
+                               }
+                       }
+               };
+               final IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
+                       /*
+                        * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+                        */
+                       public void propertyChange(PropertyChangeEvent event) {
+                               if (configuration.affectsTextPresentation(event)) {
+                                       configuration.handlePropertyChangeEvent(event);
+                                       viewer.invalidateTextPresentation();
+                               }
+                       }
+               };
+               viewer.getTextWidget().addDisposeListener(new DisposeListener() {
+                       /*
+                        * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+                        */
+                       public void widgetDisposed(DisposeEvent e) {
+                               preferenceStore
+                                               .removePropertyChangeListener(propertyChangeListener);
+                               JFaceResources.getFontRegistry().removeListener(
+                                               fontChangeListener);
+                       }
+               });
+               JFaceResources.getFontRegistry().addListener(fontChangeListener);
+               preferenceStore.addPropertyChangeListener(propertyChangeListener);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaTemplatePreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/JavaTemplatePreferencePage.java
new file mode 100644 (file)
index 0000000..79c6d07
--- /dev/null
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.templates.TemplatePreferencePage;
+
+public class JavaTemplatePreferencePage extends TemplatePreferencePage
+               implements IWorkbenchPreferencePage {
+
+       private TemplateVariableProcessor fTemplateProcessor;
+
+       public JavaTemplatePreferencePage() {
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+               setTemplateStore(WebUI.getDefault().getTemplateStore());
+               setContextTypeRegistry(WebUI.getDefault()
+                               .getTemplateContextRegistry());
+               fTemplateProcessor = new TemplateVariableProcessor();
+       }
+
+       /*
+        * @see PreferencePage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.JAVA_EDITOR_PREFERENCE_PAGE);
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               boolean ok = super.performOk();
+
+               WebUI.getDefault().savePluginPreferences();
+
+               return ok;
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#getFormatterPreferenceKey()
+        */
+       protected String getFormatterPreferenceKey() {
+               return PreferenceConstants.TEMPLATES_USE_CODEFORMATTER;
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#createTemplateEditDialog(org.eclipse.jface.text.templates.Template,
+        *      boolean, boolean)
+        */
+       protected Dialog createTemplateEditDialog(Template template, boolean edit,
+                       boolean isNameModifiable) {
+               return new EditTemplateDialog(getShell(), template, edit,
+                               isNameModifiable, getContextTypeRegistry());
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#createViewer(org.eclipse.swt.widgets.Composite)
+        */
+       protected SourceViewer createViewer(Composite parent) {
+               GridData data = new GridData();
+               IDocument document = new Document();
+               JavaTextTools tools = WebUI.getDefault().getJavaTextTools();
+               tools.setupJavaDocumentPartitioner(document,
+                               IPHPPartitions.PHP_PARTITIONING);
+               IPreferenceStore store = WebUI.getDefault()
+                               .getCombinedPreferenceStore();
+               SourceViewer viewer = new JavaSourceViewer(parent, null, null, false,
+                               SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
+               TemplateEditorSourceViewerConfiguration configuration = new TemplateEditorSourceViewerConfiguration(
+                               tools.getColorManager(), store, null, fTemplateProcessor);
+               viewer.configure(configuration);
+               viewer.setEditable(false);
+               viewer.setDocument(document);
+
+               Font font = JFaceResources
+                               .getFont(PreferenceConstants.EDITOR_TEXT_FONT);
+               viewer.getTextWidget().setFont(font);
+               new JavaSourcePreviewerUpdater(viewer, configuration, store);
+
+               Control control = viewer.getControl();
+               data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.FILL_VERTICAL);
+               control.setLayoutData(data);
+
+               return viewer;
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.templates.TemplatePreferencePage#updateViewerInput()
+        */
+       protected void updateViewerInput() {
+               IStructuredSelection selection = (IStructuredSelection) getTableViewer()
+                               .getSelection();
+               SourceViewer viewer = getViewer();
+
+               if (selection.size() == 1
+                               && selection.getFirstElement() instanceof TemplatePersistenceData) {
+                       TemplatePersistenceData data = (TemplatePersistenceData) selection
+                                       .getFirstElement();
+                       Template template = data.getTemplate();
+                       String contextId = template.getContextTypeId();
+                       TemplateContextType type = WebUI.getDefault()
+                                       .getTemplateContextRegistry().getContextType(contextId);
+                       fTemplateProcessor.setContextType(type);
+
+                       IDocument doc = viewer.getDocument();
+
+                       String start = null;
+                       if ("javadoc".equals(contextId)) { //$NON-NLS-1$
+                               start = "/**" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
+                       } else
+                               start = ""; //$NON-NLS-1$
+
+                       doc.set(start + template.getPattern());
+                       int startLen = start.length();
+                       viewer.setDocument(doc, startLen, doc.getLength() - startLen);
+
+               } else {
+                       viewer.getDocument().set(""); //$NON-NLS-1$
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MarkOccurrencesConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MarkOccurrencesConfigurationBlock.java
new file mode 100644 (file)
index 0000000..0b580c0
--- /dev/null
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.text.Assert;
+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.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Configures Java Editor hover preferences.
+ * 
+ * @since 2.1
+ */
+class MarkOccurrencesConfigurationBlock implements
+               IPreferenceConfigurationBlock {
+
+       private OverlayPreferenceStore fStore;
+
+       private Map fCheckBoxes = new HashMap();
+
+       private SelectionListener fCheckBoxListener = new SelectionListener() {
+               public void widgetDefaultSelected(SelectionEvent e) {
+               }
+
+               public void widgetSelected(SelectionEvent e) {
+                       Button button = (Button) e.widget;
+                       fStore.setValue((String) fCheckBoxes.get(button), button
+                                       .getSelection());
+               }
+       };
+
+       /**
+        * List of master/slave listeners when there's a dependency.
+        * 
+        * @see #createDependency(Button, String, Control)
+        * @since 3.0
+        */
+       private ArrayList fMasterSlaveListeners = new ArrayList();
+
+       private StatusInfo fStatus;
+
+       public MarkOccurrencesConfigurationBlock(OverlayPreferenceStore store) {
+               Assert.isNotNull(store);
+               fStore = store;
+
+               fStore.addKeys(createOverlayStoreKeys());
+       }
+
+       private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() {
+
+               ArrayList overlayKeys = new ArrayList();
+
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_MARK_OCCURRENCES));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_MARK_IMPLEMENTORS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_STICKY_OCCURRENCES));
+
+               OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys
+                               .size()];
+               overlayKeys.toArray(keys);
+               return keys;
+       }
+
+       /**
+        * Creates page for mark occurrences preferences.
+        * 
+        * @param parent
+        *            the parent composite
+        * @return the control for the preference page
+        */
+       public Control createControl(Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               composite.setLayout(layout);
+
+               GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_VERTICAL);
+               composite.setLayoutData(gd);
+
+               String label;
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.markOccurrences");
+               Button master = addCheckBox(composite, label,
+                               PreferenceConstants.EDITOR_MARK_OCCURRENCES, 0); //$NON-NLS-1$
+
+               // label=
+               // PreferencesMessages.MarkOccurrencesConfigurationBlock_markTypeOccurrences;
+               // Button slave= addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES, 0); //$NON-NLS-1$
+               // createDependency(master,
+               // PreferenceConstants.EDITOR_STICKY_OCCURRENCES, slave);
+               //
+               // label=
+               // PreferencesMessages.MarkOccurrencesConfigurationBlock_markMethodOccurrences;
+               // slave= addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES, 0); //$NON-NLS-1$
+               // createDependency(master,
+               // PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES, slave);
+               //
+               // label=
+               // PreferencesMessages.MarkOccurrencesConfigurationBlock_markConstantOccurrences;
+               // slave= addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES, 0);
+               // //$NON-NLS-1$
+               // createDependency(master,
+               // PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES, slave);
+               //
+               // label=
+               // PreferencesMessages.MarkOccurrencesConfigurationBlock_markFieldOccurrences;
+               // slave= addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES, 0); //$NON-NLS-1$
+               // createDependency(master,
+               // PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES, slave);
+               //
+               // label=
+               // PreferencesMessages.MarkOccurrencesConfigurationBlock_markLocalVariableOccurrences;
+               // slave= addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES, 0);
+               // //$NON-NLS-1$
+               // createDependency(master,
+               // PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES, slave);
+               //
+               // label=
+               // PreferencesMessages.MarkOccurrencesConfigurationBlock_markExceptionOccurrences;
+               // slave= addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES, 0);
+               // //$NON-NLS-1$
+               // createDependency(master,
+               // PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES, slave);
+               //
+               // label=
+               // PreferencesMessages.MarkOccurrencesConfigurationBlock_markMethodExitPoints;
+               // slave= addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS, 0); //$NON-NLS-1$
+               // createDependency(master,
+               // PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS, slave);
+               //
+               // label=
+               // PreferencesMessages.MarkOccurrencesConfigurationBlock_markImplementors;
+               // slave= addCheckBox(composite, label,
+               // PreferenceConstants.EDITOR_MARK_IMPLEMENTORS, 0); //$NON-NLS-1$
+               // createDependency(master,
+               // PreferenceConstants.EDITOR_MARK_IMPLEMENTORS, slave);
+
+               //addFiller(composite);
+
+               label = PreferencesMessages
+                               .getString("JavaEditorPreferencePage.stickyOccurrences");
+               Button slave = addCheckBox(composite, label,
+                               PreferenceConstants.EDITOR_STICKY_OCCURRENCES, 0); //$NON-NLS-1$
+               createDependency(master, PreferenceConstants.EDITOR_STICKY_OCCURRENCES,
+                               slave);
+
+               return composite;
+       }
+
+       private void addFiller(Composite composite) {
+               PixelConverter pixelConverter = new PixelConverter(composite);
+
+               Label filler = new Label(composite, SWT.LEFT);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = 2;
+               gd.heightHint = pixelConverter.convertHeightInCharsToPixels(1) / 2;
+               filler.setLayoutData(gd);
+       }
+
+       private Button addCheckBox(Composite parent, String label, String key,
+                       int indentation) {
+               Button checkBox = new Button(parent, SWT.CHECK);
+               checkBox.setText(label);
+
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indentation;
+               gd.horizontalSpan = 2;
+               checkBox.setLayoutData(gd);
+               checkBox.addSelectionListener(fCheckBoxListener);
+
+               fCheckBoxes.put(checkBox, key);
+
+               return checkBox;
+       }
+
+       private void createDependency(final Button master, String masterKey,
+                       final Control slave) {
+               indent(slave);
+               boolean masterState = fStore.getBoolean(masterKey);
+               slave.setEnabled(masterState);
+               SelectionListener listener = new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               slave.setEnabled(master.getSelection());
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               };
+               master.addSelectionListener(listener);
+               fMasterSlaveListeners.add(listener);
+       }
+
+       private static void indent(Control control) {
+               GridData gridData = new GridData();
+               gridData.horizontalIndent = 20;
+               control.setLayoutData(gridData);
+       }
+
+       public void initialize() {
+               initializeFields();
+       }
+
+       void initializeFields() {
+
+               Iterator iter = fCheckBoxes.keySet().iterator();
+               while (iter.hasNext()) {
+                       Button b = (Button) iter.next();
+                       String key = (String) fCheckBoxes.get(b);
+                       b.setSelection(fStore.getBoolean(key));
+               }
+
+               // Update slaves
+               iter = fMasterSlaveListeners.iterator();
+               while (iter.hasNext()) {
+                       SelectionListener listener = (SelectionListener) iter.next();
+                       listener.widgetSelected(null);
+               }
+
+       }
+
+       public void performOk() {
+       }
+
+       public void performDefaults() {
+               restoreFromPreferences();
+               initializeFields();
+       }
+
+       private void restoreFromPreferences() {
+
+       }
+
+       IStatus getStatus() {
+               if (fStatus == null)
+                       fStatus = new StatusInfo();
+               return fStatus;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.IPreferenceConfigurationBlock#dispose()
+        * @since 3.0
+        */
+       public void dispose() {
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MarkOccurrencesPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MarkOccurrencesPreferencePage.java
new file mode 100644 (file)
index 0000000..0cdcb6f
--- /dev/null
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * The page for setting the editor options.
+ */
+public final class MarkOccurrencesPreferencePage extends
+               AbstractConfigurationBlockPreferencePage {
+
+       /*
+        * @see org.eclipse.ui.internal.editors.text.AbstractConfigureationBlockPreferencePage#getHelpId()
+        */
+       protected String getHelpId() {
+               return IJavaHelpContextIds.JAVA_EDITOR_PREFERENCE_PAGE;
+       }
+
+       /*
+        * @see org.eclipse.ui.internal.editors.text.AbstractConfigurationBlockPreferencePage#setDescription()
+        */
+       protected void setDescription() {
+               String description = PreferencesMessages
+                               .getString("MarkOccurrencesConfigurationBlock.title");
+               setDescription(description);
+       }
+
+       /*
+        * @see org.org.eclipse.ui.internal.editors.text.AbstractConfigurationBlockPreferencePage#setPreferenceStore()
+        */
+       protected void setPreferenceStore() {
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+       }
+
+       protected Label createDescriptionLabel(Composite parent) {
+               return null; // no description for new look.
+       }
+
+       /*
+        * @see org.eclipse.ui.internal.editors.text.AbstractConfigureationBlockPreferencePage#createConfigurationBlock(org.eclipse.ui.internal.editors.text.OverlayPreferenceStore)
+        */
+       protected IPreferenceConfigurationBlock createConfigurationBlock(
+                       OverlayPreferenceStore overlayPreferenceStore) {
+               return new MarkOccurrencesConfigurationBlock(overlayPreferenceStore);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferenceCache.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferenceCache.java
new file mode 100644 (file)
index 0000000..cf34946
--- /dev/null
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ */
+public class MembersOrderPreferenceCache implements IPropertyChangeListener {
+
+       public static final int TYPE_INDEX = 0;
+
+       public static final int CONSTRUCTORS_INDEX = 1;
+
+       public static final int METHOD_INDEX = 2;
+
+       public static final int FIELDS_INDEX = 3;
+
+       public static final int INIT_INDEX = 4;
+
+       public static final int STATIC_FIELDS_INDEX = 5;
+
+       public static final int STATIC_INIT_INDEX = 6;
+
+       public static final int STATIC_METHODS_INDEX = 7;
+
+       public static final int N_CATEGORIES = STATIC_METHODS_INDEX + 1;
+
+       private static final int PUBLIC_INDEX = 0;
+
+       private static final int PRIVATE_INDEX = 1;
+
+       private static final int PROTECTED_INDEX = 2;
+
+       private static final int DEFAULT_INDEX = 3;
+
+       private static final int N_VISIBILITIES = DEFAULT_INDEX + 1;
+
+       private int[] fCategoryOffsets = null;
+
+       private boolean fSortByVisibility;
+
+       private int[] fVisibilityOffsets = null;
+
+       public MembersOrderPreferenceCache() {
+               fCategoryOffsets = null;
+               fSortByVisibility = PreferenceConstants
+                               .getPreferenceStore()
+                               .getBoolean(
+                                               PreferenceConstants.APPEARANCE_ENABLE_VISIBILITY_SORT_ORDER);
+               fVisibilityOffsets = null;
+       }
+
+       public static boolean isMemberOrderProperty(String property) {
+               return PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER
+                               .equals(property)
+                               || PreferenceConstants.APPEARANCE_VISIBILITY_SORT_ORDER
+                                               .equals(property)
+                               || PreferenceConstants.APPEARANCE_ENABLE_VISIBILITY_SORT_ORDER
+                                               .equals(property);
+       }
+
+       public void propertyChange(PropertyChangeEvent event) {
+               String property = event.getProperty();
+
+               if (PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER.equals(property)) {
+                       fCategoryOffsets = null;
+               } else if (PreferenceConstants.APPEARANCE_VISIBILITY_SORT_ORDER
+                               .equals(property)) {
+                       fVisibilityOffsets = null;
+               } else if (PreferenceConstants.APPEARANCE_ENABLE_VISIBILITY_SORT_ORDER
+                               .equals(property)) {
+                       fSortByVisibility = PreferenceConstants
+                                       .getPreferenceStore()
+                                       .getBoolean(
+                                                       PreferenceConstants.APPEARANCE_ENABLE_VISIBILITY_SORT_ORDER);
+               }
+       }
+
+       public int getCategoryIndex(int kind) {
+               if (fCategoryOffsets == null) {
+                       fCategoryOffsets = getCategoryOffsets();
+               }
+               return fCategoryOffsets[kind];
+       }
+
+       private int[] getCategoryOffsets() {
+               int[] offsets = new int[N_CATEGORIES];
+               IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+               String key = PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER;
+               boolean success = fillCategoryOffsetsFromPreferenceString(store
+                               .getString(key), offsets);
+               if (!success) {
+                       store.setToDefault(key);
+                       fillCategoryOffsetsFromPreferenceString(
+                                       store.getDefaultString(key), offsets);
+               }
+               return offsets;
+       }
+
+       private boolean fillCategoryOffsetsFromPreferenceString(String str,
+                       int[] offsets) {
+               StringTokenizer tokenizer = new StringTokenizer(str, ","); //$NON-NLS-1$
+               int i = 0;
+               while (tokenizer.hasMoreTokens()) {
+                       String token = tokenizer.nextToken().trim();
+                       if ("T".equals(token)) { //$NON-NLS-1$
+                               offsets[TYPE_INDEX] = i++;
+                       } else if ("M".equals(token)) { //$NON-NLS-1$
+                               offsets[METHOD_INDEX] = i++;
+                       } else if ("F".equals(token)) { //$NON-NLS-1$
+                               offsets[FIELDS_INDEX] = i++;
+                       } else if ("I".equals(token)) { //$NON-NLS-1$
+                               offsets[INIT_INDEX] = i++;
+                       } else if ("SF".equals(token)) { //$NON-NLS-1$
+                               offsets[STATIC_FIELDS_INDEX] = i++;
+                       } else if ("SI".equals(token)) { //$NON-NLS-1$
+                               offsets[STATIC_INIT_INDEX] = i++;
+                       } else if ("SM".equals(token)) { //$NON-NLS-1$
+                               offsets[STATIC_METHODS_INDEX] = i++;
+                       } else if ("C".equals(token)) { //$NON-NLS-1$
+                               offsets[CONSTRUCTORS_INDEX] = i++;
+                       }
+               }
+               return i == N_CATEGORIES;
+       }
+
+       public boolean isSortByVisibility() {
+               return fSortByVisibility;
+       }
+
+       public int getVisibilityIndex(int modifierFlags) {
+               if (fVisibilityOffsets == null) {
+                       fVisibilityOffsets = getVisibilityOffsets();
+               }
+               int kind = DEFAULT_INDEX;
+               if (Flags.isPublic(modifierFlags)) {
+                       kind = PUBLIC_INDEX;
+               } else if (Flags.isProtected(modifierFlags)) {
+                       kind = PROTECTED_INDEX;
+               } else if (Flags.isPrivate(modifierFlags)) {
+                       kind = PRIVATE_INDEX;
+               }
+
+               return fVisibilityOffsets[kind];
+       }
+
+       private int[] getVisibilityOffsets() {
+               int[] offsets = new int[N_VISIBILITIES];
+               IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+               String key = PreferenceConstants.APPEARANCE_VISIBILITY_SORT_ORDER;
+               boolean success = fillVisibilityOffsetsFromPreferenceString(store
+                               .getString(key), offsets);
+               if (!success) {
+                       store.setToDefault(key);
+                       fillVisibilityOffsetsFromPreferenceString(store
+                                       .getDefaultString(key), offsets);
+               }
+               return offsets;
+       }
+
+       private boolean fillVisibilityOffsetsFromPreferenceString(String str,
+                       int[] offsets) {
+               StringTokenizer tokenizer = new StringTokenizer(str, ","); //$NON-NLS-1$
+               int i = 0;
+               while (tokenizer.hasMoreTokens()) {
+                       String token = tokenizer.nextToken().trim();
+                       if ("B".equals(token)) { //$NON-NLS-1$
+                               offsets[PUBLIC_INDEX] = i++;
+                       } else if ("V".equals(token)) { //$NON-NLS-1$
+                               offsets[PRIVATE_INDEX] = i++;
+                       } else if ("R".equals(token)) { //$NON-NLS-1$
+                               offsets[PROTECTED_INDEX] = i++;
+                       } else if ("D".equals(token)) { //$NON-NLS-1$
+                               offsets[DEFAULT_INDEX] = i++;
+                       }
+               }
+               return i == N_VISIBILITIES;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MembersOrderPreferencePage.java
new file mode 100644 (file)
index 0000000..1bc2806
--- /dev/null
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry;
+import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementImageProvider;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ListDialogField;
+import net.sourceforge.phpdt.ui.JavaElementImageDescriptor;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+public class MembersOrderPreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage {
+
+       private static final String ALL_ENTRIES = "T,SI,SF,SM,I,F,C,M"; //$NON-NLS-1$
+
+       private static final String PREF_OUTLINE_SORT_OPTION = PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER;
+
+       public static final String CONSTRUCTORS = "C"; //$NON-NLS-1$
+
+       public static final String FIELDS = "F"; //$NON-NLS-1$
+
+       public static final String METHODS = "M"; //$NON-NLS-1$
+
+       public static final String STATIC_METHODS = "SM"; //$NON-NLS-1$
+
+       public static final String STATIC_FIELDS = "SF"; //$NON-NLS-1$
+
+       public static final String INIT = "I"; //$NON-NLS-1$
+
+       public static final String STATIC_INIT = "SI"; //$NON-NLS-1$
+
+       public static final String TYPES = "T"; //$NON-NLS-1$
+
+       private ListDialogField fSortOrderList;
+
+       private static List getSortOrderList(String string) {
+               StringTokenizer tokenizer = new StringTokenizer(string, ","); //$NON-NLS-1$
+               List entries = new ArrayList();
+               for (int i = 0; tokenizer.hasMoreTokens(); i++) {
+                       String token = tokenizer.nextToken();
+                       entries.add(token);
+               }
+               return entries;
+       }
+
+       private static boolean isValidEntries(List entries) {
+               StringTokenizer tokenizer = new StringTokenizer(ALL_ENTRIES, ","); //$NON-NLS-1$
+               int i = 0;
+               for (; tokenizer.hasMoreTokens(); i++) {
+                       String token = tokenizer.nextToken();
+                       if (!entries.contains(token))
+                               return false;
+               }
+               return i == entries.size();
+       }
+
+       public MembersOrderPreferencePage() {
+               // set the preference store
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+
+               setDescription(PreferencesMessages
+                               .getString("MembersOrderPreferencePage.label.description")); //$NON-NLS-1$
+
+               String string = getPreferenceStore()
+                               .getString(PREF_OUTLINE_SORT_OPTION);
+
+               String upLabel = PreferencesMessages
+                               .getString("MembersOrderPreferencePage.button.up"); //$NON-NLS-1$
+               String downLabel = PreferencesMessages
+                               .getString("MembersOrderPreferencePage.button.down"); //$NON-NLS-1$
+               String[] buttonlabels = new String[] { upLabel, downLabel };
+
+               fSortOrderList = new ListDialogField(null, buttonlabels,
+                               new MemberSortLabelProvider());
+               fSortOrderList.setDownButtonIndex(1);
+               fSortOrderList.setUpButtonIndex(0);
+
+               // validate entries stored in store, false get defaults
+               List entries = getSortOrderList(string);
+               if (!isValidEntries(entries)) {
+                       string = WebUI.getDefault().getPreferenceStore()
+                                       .getDefaultString(PREF_OUTLINE_SORT_OPTION);
+                       entries = getSortOrderList(string);
+               }
+
+               fSortOrderList.setElements(entries);
+       }
+
+       /*
+        * @see PreferencePage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               // WorkbenchHelp.setHelp(getControl(),
+               // IJavaHelpContextIds.SORT_ORDER_PREFERENCE_PAGE);
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 3;
+               layout.marginWidth = 0;
+               layout.marginHeight = 0;
+               composite.setLayout(layout);
+
+               GridData data = new GridData();
+               data.verticalAlignment = GridData.FILL;
+               data.horizontalAlignment = GridData.FILL_HORIZONTAL;
+               composite.setLayoutData(data);
+
+               createSortOrderListDialogField(composite, 3);
+               Dialog.applyDialogFont(composite);
+               return composite;
+       }
+
+       private void createSortOrderListDialogField(Composite composite, int span) {
+               fSortOrderList.doFillIntoGrid(composite, span);
+
+               fSortOrderList.getLabelControl(null).dispose();
+
+               GridData data = (GridData) fSortOrderList.getListControl(null)
+                               .getLayoutData();
+               data.grabExcessHorizontalSpace = true;
+               data.verticalAlignment = 0;
+               data.heightHint = SWTUtil.getTableHeightHint(fSortOrderList
+                               .getTableViewer().getTable(), 8);
+       }
+
+       /*
+        * @see org.eclipse.ui.IWorkbenchPreferencePage#init(IWorkbench)
+        */
+       public void init(IWorkbench workbench) {
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               String string = getPreferenceStore().getDefaultString(
+                               PREF_OUTLINE_SORT_OPTION);
+               fSortOrderList.setElements(getSortOrderList(string));
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+        */
+       // reorders elements in the Outline based on selection
+       public boolean performOk() {
+               // update outline view
+
+               // save preferences
+               IPreferenceStore store = getPreferenceStore();
+
+               StringBuffer buf = new StringBuffer();
+               List curr = fSortOrderList.getElements();
+               for (Iterator iter = curr.iterator(); iter.hasNext();) {
+                       String s = (String) iter.next();
+                       buf.append(s);
+                       buf.append(',');
+               }
+               store.setValue(PREF_OUTLINE_SORT_OPTION, buf.toString());
+               WebUI.getDefault().savePluginPreferences();
+               return true;
+       }
+
+       private class MemberSortLabelProvider extends LabelProvider {
+
+               public MemberSortLabelProvider() {
+               }
+
+               /*
+                * @see org.eclipse.jface.viewers.ILabelProvider#getText(Object)
+                */
+               public String getText(Object element) {
+
+                       if (element instanceof String) {
+                               String s = (String) element;
+                               if (s.equals(FIELDS)) {
+                                       return PreferencesMessages
+                                                       .getString("MembersOrderPreferencePage.fields.label"); //$NON-NLS-1$
+                               } else if (s.equals(CONSTRUCTORS)) {
+                                       return PreferencesMessages
+                                                       .getString("MembersOrderPreferencePage.constructors.label"); //$NON-NLS-1$
+                               } else if (s.equals(METHODS)) {
+                                       return PreferencesMessages
+                                                       .getString("MembersOrderPreferencePage.methods.label"); //$NON-NLS-1$
+                               } else if (s.equals(STATIC_FIELDS)) {
+                                       return PreferencesMessages
+                                                       .getString("MembersOrderPreferencePage.staticfields.label"); //$NON-NLS-1$
+                               } else if (s.equals(STATIC_METHODS)) {
+                                       return PreferencesMessages
+                                                       .getString("MembersOrderPreferencePage.staticmethods.label"); //$NON-NLS-1$
+                               } else if (s.equals(INIT)) {
+                                       return PreferencesMessages
+                                                       .getString("MembersOrderPreferencePage.initialisers.label"); //$NON-NLS-1$
+                               } else if (s.equals(STATIC_INIT)) {
+                                       return PreferencesMessages
+                                                       .getString("MembersOrderPreferencePage.staticinitialisers.label"); //$NON-NLS-1$
+                               } else if (s.equals(TYPES)) {
+                                       return PreferencesMessages
+                                                       .getString("MembersOrderPreferencePage.types.label"); //$NON-NLS-1$
+                               }
+                       }
+                       return ""; //$NON-NLS-1$
+               }
+
+               /*
+                * @see org.eclipse.jface.viewers.ILabelProvider#getImage(Object)
+                */
+               public Image getImage(Object element) {
+                       // access to image registry
+                       ImageDescriptorRegistry registry = WebUI
+                                       .getImageDescriptorRegistry();
+                       ImageDescriptor descriptor = null;
+
+                       if (element instanceof String) {
+                               int visibility = Flags.AccPublic;
+                               String s = (String) element;
+                               if (s.equals(FIELDS)) {
+                                       // 0 will give the default field image
+                                       descriptor = JavaElementImageProvider
+                                                       .getFieldImageDescriptor(false, visibility);
+                               } else if (s.equals(CONSTRUCTORS)) {
+                                       descriptor = JavaElementImageProvider
+                                                       .getMethodImageDescriptor(false, visibility);
+                                       // add a constructor adornment to the image descriptor
+                                       descriptor = new JavaElementImageDescriptor(descriptor,
+                                                       JavaElementImageDescriptor.CONSTRUCTOR,
+                                                       JavaElementImageProvider.SMALL_SIZE);
+                               } else if (s.equals(METHODS)) {
+                                       descriptor = JavaElementImageProvider
+                                                       .getMethodImageDescriptor(false, visibility);
+                               } else if (s.equals(STATIC_FIELDS)) {
+                                       descriptor = JavaElementImageProvider
+                                                       .getFieldImageDescriptor(false, visibility);
+                                       // add a constructor adornment to the image descriptor
+                                       descriptor = new JavaElementImageDescriptor(descriptor,
+                                                       JavaElementImageDescriptor.STATIC,
+                                                       JavaElementImageProvider.SMALL_SIZE);
+                               } else if (s.equals(STATIC_METHODS)) {
+                                       descriptor = JavaElementImageProvider
+                                                       .getMethodImageDescriptor(false, visibility);
+                                       // add a constructor adornment to the image descriptor
+                                       descriptor = new JavaElementImageDescriptor(descriptor,
+                                                       JavaElementImageDescriptor.STATIC,
+                                                       JavaElementImageProvider.SMALL_SIZE);
+                               } else if (s.equals(INIT)) {
+                                       descriptor = JavaElementImageProvider
+                                                       .getMethodImageDescriptor(false, visibility);
+                               } else if (s.equals(STATIC_INIT)) {
+                                       descriptor = JavaElementImageProvider
+                                                       .getMethodImageDescriptor(false, visibility);
+                                       descriptor = new JavaElementImageDescriptor(descriptor,
+                                                       JavaElementImageDescriptor.STATIC,
+                                                       JavaElementImageProvider.SMALL_SIZE);
+                               } else if (s.equals(TYPES)) {
+                                       descriptor = JavaElementImageProvider
+                                                       .getTypeImageDescriptor(false, true,
+                                                                       Flags.AccPublic);
+                               } else {
+                                       descriptor = JavaElementImageProvider
+                                                       .getMethodImageDescriptor(false, Flags.AccPublic);
+                               }
+                               return registry.get(descriptor);
+                       }
+                       return null;
+               }
+
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MockupPreferenceStore.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/MockupPreferenceStore.java
new file mode 100644 (file)
index 0000000..bb54cd6
--- /dev/null
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * Mockup preference store, for registering listeners and firing events, without
+ * being an actual store.
+ * <p>
+ * All methods except firing, adding and removing listeners throw an
+ * {@link java.lang.UnsupportedOperationException}.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class MockupPreferenceStore implements IPreferenceStore {
+
+       /** Listeners on this store */
+       private ListenerList fListeners = new ListenerList();
+
+       /**
+        * {@inheritDoc}
+        */
+       public void addPropertyChangeListener(IPropertyChangeListener listener) {
+               fListeners.add(listener);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void removePropertyChangeListener(IPropertyChangeListener listener) {
+               fListeners.remove(listener);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean contains(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void firePropertyChangeEvent(String name, Object oldValue,
+                       Object newValue) {
+               firePropertyChangeEvent(this, name, oldValue, newValue);
+       }
+
+       /**
+        * Fires a property change event with the given source, property name, old
+        * and new value. Used when the event source should be different from this
+        * mockup preference store.
+        * 
+        * @param source
+        *            The event source
+        * @param name
+        *            The property name
+        * @param oldValue
+        *            The property's old value
+        * @param newValue
+        *            The property's new value
+        */
+       public void firePropertyChangeEvent(Object source, String name,
+                       Object oldValue, Object newValue) {
+               PropertyChangeEvent event = new PropertyChangeEvent(source, name,
+                               oldValue, newValue);
+               Object[] listeners = fListeners.getListeners();
+               for (int i = 0; i < listeners.length; i++)
+                       ((IPropertyChangeListener) listeners[i]).propertyChange(event);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean getBoolean(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean getDefaultBoolean(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public double getDefaultDouble(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public float getDefaultFloat(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public int getDefaultInt(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public long getDefaultLong(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public String getDefaultString(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public double getDouble(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public float getFloat(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public int getInt(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public long getLong(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public String getString(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean isDefault(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean needsSaving() {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void putValue(String name, String value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, double value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, float value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, int value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, long value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, String defaultObject) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, boolean value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setToDefault(String name) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, double value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, float value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, int value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, long value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, String value) {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, boolean value) {
+               throw new UnsupportedOperationException();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/OptionsConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/OptionsConfigurationBlock.java
new file mode 100644 (file)
index 0000000..4e22c99
--- /dev/null
@@ -0,0 +1,585 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Map.Entry;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Abstract options configuration block providing a general implementation for
+ * setting up an options configuration page.
+ * 
+ * @since 2.1
+ */
+public abstract class OptionsConfigurationBlock {
+
+       protected static class ControlData {
+               private String fKey;
+
+               private String[] fValues;
+
+               public ControlData(String key, String[] values) {
+                       fKey = key;
+                       fValues = values;
+               }
+
+               public String getKey() {
+                       return fKey;
+               }
+
+               public String getValue(boolean selection) {
+                       int index = selection ? 0 : 1;
+                       return fValues[index];
+               }
+
+               public String getValue(int index) {
+                       return fValues[index];
+               }
+
+               public int getSelection(String value) {
+                       if (value != null) {
+                               for (int i = 0; i < fValues.length; i++) {
+                                       if (value.equals(fValues[i])) {
+                                               return i;
+                                       }
+                               }
+                       }
+                       return fValues.length - 1; // assume the last option is the least
+                                                                               // severe
+               }
+       }
+
+       protected Map fWorkingValues;
+
+       protected ArrayList fCheckBoxes;
+
+       protected ArrayList fComboBoxes;
+
+       protected ArrayList fTextBoxes;
+
+       protected HashMap fLabels;
+
+       private SelectionListener fSelectionListener;
+
+       private ModifyListener fTextModifyListener;
+
+       protected IStatusChangeListener fContext;
+
+       protected IJavaProject fProject; // project or null
+
+       protected String[] fAllKeys;
+
+       private Shell fShell;
+
+       public OptionsConfigurationBlock(IStatusChangeListener context,
+                       IJavaProject project, String[] allKeys) {
+               fContext = context;
+               fProject = project;
+               fAllKeys = allKeys;
+
+               fWorkingValues = getOptions(true);
+               testIfOptionsComplete(fWorkingValues, allKeys);
+
+               fCheckBoxes = new ArrayList();
+               fComboBoxes = new ArrayList();
+               fTextBoxes = new ArrayList(2);
+               fLabels = new HashMap();
+       }
+
+       private void testIfOptionsComplete(Map workingValues, String[] allKeys) {
+               for (int i = 0; i < allKeys.length; i++) {
+                       if (workingValues.get(allKeys[i]) == null) {
+                               WebUI
+                                               .logErrorMessage("preference option missing: " + allKeys[i] + " (" + this.getClass().getName() + ')'); //$NON-NLS-1$//$NON-NLS-2$
+                       }
+               }
+       }
+
+       protected Map getOptions(boolean inheritJavaCoreOptions) {
+               if (fProject != null) {
+                       return fProject.getOptions(inheritJavaCoreOptions);
+               } else {
+                       return JavaCore.getOptions();
+               }
+       }
+
+       protected Map getDefaultOptions() {
+               return JavaCore.getDefaultOptions();
+       }
+
+       public final boolean hasProjectSpecificOptions() {
+               if (fProject != null) {
+                       Map settings = fProject.getOptions(false);
+                       String[] allKeys = fAllKeys;
+                       for (int i = 0; i < allKeys.length; i++) {
+                               if (settings.get(allKeys[i]) != null) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       protected void setOptions(Map map) {
+               if (fProject != null) {
+                       Map oldOptions = fProject.getOptions(false);
+                       fProject.setOptions(map);
+                       firePropertyChangeEvents(oldOptions, map);
+               } else {
+                       JavaCore.setOptions((Hashtable) map);
+               }
+       }
+
+       /**
+        * Computes the differences between the given old and new options and fires
+        * corresponding property change events on the Java plugin's mockup
+        * preference store.
+        * 
+        * @param oldOptions
+        *            The old options
+        * @param newOptions
+        *            The new options
+        */
+       private void firePropertyChangeEvents(Map oldOptions, Map newOptions) {
+               oldOptions = new HashMap(oldOptions);
+               Object source = fProject.getProject();
+               MockupPreferenceStore store = WebUI.getDefault()
+                               .getMockupPreferenceStore();
+               Iterator iter = newOptions.entrySet().iterator();
+               while (iter.hasNext()) {
+                       Entry entry = (Entry) iter.next();
+
+                       String name = (String) entry.getKey();
+                       Object oldValue = oldOptions.get(name);
+                       Object newValue = entry.getValue();
+
+                       if ((oldValue != null && !oldValue.equals(newValue))
+                                       || (oldValue == null && newValue != null))
+                               store.firePropertyChangeEvent(source, name, oldValue, newValue);
+                       oldOptions.remove(name);
+               }
+
+               iter = oldOptions.entrySet().iterator();
+               while (iter.hasNext()) {
+                       Entry entry = (Entry) iter.next();
+                       store.firePropertyChangeEvent(source, (String) entry.getKey(),
+                                       entry.getValue(), null);
+               }
+       }
+
+       protected Shell getShell() {
+               return fShell;
+       }
+
+       protected void setShell(Shell shell) {
+               fShell = shell;
+       }
+
+       protected abstract Control createContents(Composite parent);
+
+       protected Button addCheckBox(Composite parent, String label, String key,
+                       String[] values, int indent) {
+               ControlData data = new ControlData(key, values);
+
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = 3;
+               gd.horizontalIndent = indent;
+
+               Button checkBox = new Button(parent, SWT.CHECK);
+               checkBox.setText(label);
+               checkBox.setData(data);
+               checkBox.setLayoutData(gd);
+               checkBox.addSelectionListener(getSelectionListener());
+
+               String currValue = (String) fWorkingValues.get(key);
+               checkBox.setSelection(data.getSelection(currValue) == 0);
+
+               fCheckBoxes.add(checkBox);
+
+               return checkBox;
+       }
+
+       protected Combo addComboBox(Composite parent, String label, String key,
+                       String[] values, String[] valueLabels, int indent) {
+               ControlData data = new ControlData(key, values);
+
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indent;
+
+               Label labelControl = new Label(parent, SWT.LEFT | SWT.WRAP);
+               labelControl.setText(label);
+               labelControl.setLayoutData(gd);
+
+               Combo comboBox = new Combo(parent, SWT.READ_ONLY);
+               comboBox.setItems(valueLabels);
+               comboBox.setData(data);
+               comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+               comboBox.addSelectionListener(getSelectionListener());
+
+               fLabels.put(comboBox, labelControl);
+
+               Label placeHolder = new Label(parent, SWT.NONE);
+               placeHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               String currValue = (String) fWorkingValues.get(key);
+               comboBox.select(data.getSelection(currValue));
+
+               fComboBoxes.add(comboBox);
+               return comboBox;
+       }
+
+       protected void addInversedComboBox(Composite parent, String label,
+                       String key, String[] values, String[] valueLabels, int indent) {
+               ControlData data = new ControlData(key, values);
+
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indent;
+               gd.horizontalSpan = 3;
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               composite.setLayout(layout);
+               composite.setLayoutData(gd);
+
+               Combo comboBox = new Combo(composite, SWT.READ_ONLY);
+               comboBox.setItems(valueLabels);
+               comboBox.setData(data);
+               comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+               comboBox.addSelectionListener(getSelectionListener());
+
+               Label labelControl = new Label(composite, SWT.LEFT | SWT.WRAP);
+               labelControl.setText(label);
+               labelControl.setLayoutData(new GridData());
+
+               fLabels.put(comboBox, labelControl);
+
+               String currValue = (String) fWorkingValues.get(key);
+               comboBox.select(data.getSelection(currValue));
+
+               fComboBoxes.add(comboBox);
+       }
+
+       protected Text addTextField(Composite parent, String label, String key,
+                       int indent, int widthHint) {
+               Label labelControl = new Label(parent, SWT.NONE);
+               labelControl.setText(label);
+               labelControl.setLayoutData(new GridData());
+
+               Text textBox = new Text(parent, SWT.BORDER | SWT.SINGLE);
+               textBox.setData(key);
+               textBox.setLayoutData(new GridData());
+
+               fLabels.put(textBox, labelControl);
+
+               String currValue = (String) fWorkingValues.get(key);
+               if (currValue != null) {
+                       textBox.setText(currValue);
+               }
+               textBox.addModifyListener(getTextModifyListener());
+
+               GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               if (widthHint != 0) {
+                       data.widthHint = widthHint;
+               }
+               data.horizontalIndent = indent;
+               data.horizontalSpan = 2;
+               textBox.setLayoutData(data);
+
+               fTextBoxes.add(textBox);
+               return textBox;
+       }
+
+       protected SelectionListener getSelectionListener() {
+               if (fSelectionListener == null) {
+                       fSelectionListener = new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                               }
+
+                               public void widgetSelected(SelectionEvent e) {
+                                       controlChanged(e.widget);
+                               }
+                       };
+               }
+               return fSelectionListener;
+       }
+
+       protected ModifyListener getTextModifyListener() {
+               if (fTextModifyListener == null) {
+                       fTextModifyListener = new ModifyListener() {
+                               public void modifyText(ModifyEvent e) {
+                                       textChanged((Text) e.widget);
+                               }
+                       };
+               }
+               return fTextModifyListener;
+       }
+
+       protected void controlChanged(Widget widget) {
+               ControlData data = (ControlData) widget.getData();
+               String newValue = null;
+               if (widget instanceof Button) {
+                       newValue = data.getValue(((Button) widget).getSelection());
+               } else if (widget instanceof Combo) {
+                       newValue = data.getValue(((Combo) widget).getSelectionIndex());
+               } else {
+                       return;
+               }
+               fWorkingValues.put(data.getKey(), newValue);
+
+               validateSettings(data.getKey(), newValue);
+       }
+
+       protected void textChanged(Text textControl) {
+               String key = (String) textControl.getData();
+               String number = textControl.getText();
+               fWorkingValues.put(key, number);
+               validateSettings(key, number);
+       }
+
+       protected boolean checkValue(String key, String value) {
+               return value.equals(fWorkingValues.get(key));
+       }
+
+       /*
+        * (non-javadoc) Update fields and validate. @param changedKey Key that
+        * changed, or null, if all changed.
+        */
+       protected abstract void validateSettings(String changedKey, String newValue);
+
+       protected String[] getTokens(String text, String separator) {
+               StringTokenizer tok = new StringTokenizer(text, separator); //$NON-NLS-1$
+               int nTokens = tok.countTokens();
+               String[] res = new String[nTokens];
+               for (int i = 0; i < res.length; i++) {
+                       res[i] = tok.nextToken().trim();
+               }
+               return res;
+       }
+
+       public boolean performOk(boolean enabled) {
+               String[] allKeys = fAllKeys;
+               Map actualOptions = getOptions(false);
+
+               // preserve other options
+               boolean hasChanges = false;
+               for (int i = 0; i < allKeys.length; i++) {
+                       String key = allKeys[i];
+                       String oldVal = (String) actualOptions.get(key);
+                       String val = null;
+                       if (enabled) {
+                               val = (String) fWorkingValues.get(key);
+                               if (val != null && !val.equals(oldVal)) {
+                                       hasChanges = true;
+                                       actualOptions.put(key, val);
+                               }
+                       } else {
+                               if (oldVal != null) {
+                                       actualOptions.remove(key);
+                                       hasChanges = true;
+                               }
+                       }
+               }
+
+               if (hasChanges) {
+                       boolean doBuild = false;
+                       String[] strings = getFullBuildDialogStrings(fProject == null);
+                       if (strings != null) {
+                               MessageDialog dialog = new MessageDialog(getShell(),
+                                               strings[0], null, strings[1], MessageDialog.QUESTION,
+                                               new String[] { IDialogConstants.YES_LABEL,
+                                                               IDialogConstants.NO_LABEL,
+                                                               IDialogConstants.CANCEL_LABEL }, 2);
+                               int res = dialog.open();
+                               if (res == 0) {
+                                       doBuild = true;
+                               } else if (res != 1) {
+                                       return false; // cancel pressed
+                               }
+                       }
+                       setOptions(actualOptions);
+                       if (doBuild) {
+                               boolean res = doFullBuild();
+                               if (!res) {
+                                       return false;
+                               }
+                       }
+               }
+               return true;
+       }
+
+       protected abstract String[] getFullBuildDialogStrings(
+                       boolean workspaceSettings);
+
+       protected boolean doFullBuild() {
+
+               Job buildJob = new Job(PreferencesMessages
+                               .getString("OptionsConfigurationBlock.job.title")) { //$NON-NLS-1$
+                       /*
+                        * (non-Javadoc)
+                        * 
+                        * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+                        */
+                       protected IStatus run(IProgressMonitor monitor) {
+                               try {
+                                       if (fProject != null) {
+                                               monitor
+                                                               .setTaskName(PreferencesMessages
+                                                                               .getFormattedString(
+                                                                                               "OptionsConfigurationBlock.buildproject.taskname", fProject.getElementName())); //$NON-NLS-1$
+                                               fProject.getProject().build(
+                                                               IncrementalProjectBuilder.FULL_BUILD,
+                                                               new SubProgressMonitor(monitor, 1));
+                                               WebUI.getWorkspace().build(
+                                                               IncrementalProjectBuilder.INCREMENTAL_BUILD,
+                                                               new SubProgressMonitor(monitor, 1));
+                                       } else {
+                                               monitor
+                                                               .setTaskName(PreferencesMessages
+                                                                               .getString("OptionsConfigurationBlock.buildall.taskname")); //$NON-NLS-1$
+                                               WebUI.getWorkspace().build(
+                                                               IncrementalProjectBuilder.FULL_BUILD,
+                                                               new SubProgressMonitor(monitor, 2));
+                                       }
+                               } catch (CoreException e) {
+                                       return e.getStatus();
+                               } catch (OperationCanceledException e) {
+                                       return Status.CANCEL_STATUS;
+                               } finally {
+                                       monitor.done();
+                               }
+                               return Status.OK_STATUS;
+                       }
+
+                       public boolean belongsTo(Object family) {
+                               return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
+                       }
+               };
+
+               buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory()
+                               .buildRule());
+               buildJob.setUser(true);
+               buildJob.schedule();
+               return true;
+       }
+
+       public void performDefaults() {
+               fWorkingValues = getDefaultOptions();
+               updateControls();
+               validateSettings(null, null);
+       }
+
+       protected void updateControls() {
+               // update the UI
+               for (int i = fCheckBoxes.size() - 1; i >= 0; i--) {
+                       updateCheckBox((Button) fCheckBoxes.get(i));
+               }
+               for (int i = fComboBoxes.size() - 1; i >= 0; i--) {
+                       updateCombo((Combo) fComboBoxes.get(i));
+               }
+               for (int i = fTextBoxes.size() - 1; i >= 0; i--) {
+                       updateText((Text) fTextBoxes.get(i));
+               }
+       }
+
+       protected void updateCombo(Combo curr) {
+               ControlData data = (ControlData) curr.getData();
+
+               String currValue = (String) fWorkingValues.get(data.getKey());
+               curr.select(data.getSelection(currValue));
+       }
+
+       protected void updateCheckBox(Button curr) {
+               ControlData data = (ControlData) curr.getData();
+
+               String currValue = (String) fWorkingValues.get(data.getKey());
+               curr.setSelection(data.getSelection(currValue) == 0);
+       }
+
+       protected void updateText(Text curr) {
+               String key = (String) curr.getData();
+
+               String currValue = (String) fWorkingValues.get(key);
+               if (currValue != null) {
+                       curr.setText(currValue);
+               }
+       }
+
+       protected Button getCheckBox(String key) {
+               for (int i = fCheckBoxes.size() - 1; i >= 0; i--) {
+                       Button curr = (Button) fCheckBoxes.get(i);
+                       ControlData data = (ControlData) curr.getData();
+                       if (key.equals(data.getKey())) {
+                               return curr;
+                       }
+               }
+               return null;
+       }
+
+       protected Combo getComboBox(String key) {
+               for (int i = fComboBoxes.size() - 1; i >= 0; i--) {
+                       Combo curr = (Combo) fComboBoxes.get(i);
+                       ControlData data = (ControlData) curr.getData();
+                       if (key.equals(data.getKey())) {
+                               return curr;
+                       }
+               }
+               return null;
+       }
+
+       protected void setComboEnabled(String key, boolean enabled) {
+               Combo combo = getComboBox(key);
+               Label label = (Label) fLabels.get(combo);
+               combo.setEnabled(enabled);
+               label.setEnabled(enabled);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/OverlayPreferenceStore.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/OverlayPreferenceStore.java
new file mode 100644 (file)
index 0000000..e33b313
--- /dev/null
@@ -0,0 +1,496 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * An overlaying preference store.
+ */
+public class OverlayPreferenceStore implements IPreferenceStore {
+
+       public static final class TypeDescriptor {
+               private TypeDescriptor() {
+               }
+       }
+
+       public static final TypeDescriptor BOOLEAN = new TypeDescriptor();
+
+       public static final TypeDescriptor DOUBLE = new TypeDescriptor();
+
+       public static final TypeDescriptor FLOAT = new TypeDescriptor();
+
+       public static final TypeDescriptor INT = new TypeDescriptor();
+
+       public static final TypeDescriptor LONG = new TypeDescriptor();
+
+       public static final TypeDescriptor STRING = new TypeDescriptor();
+
+       public static class OverlayKey {
+
+               TypeDescriptor fDescriptor;
+
+               String fKey;
+
+               public OverlayKey(TypeDescriptor descriptor, String key) {
+                       fDescriptor = descriptor;
+                       fKey = key;
+               }
+       }
+
+       private class PropertyListener implements IPropertyChangeListener {
+
+               /*
+                * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+                */
+               public void propertyChange(PropertyChangeEvent event) {
+                       OverlayKey key = findOverlayKey(event.getProperty());
+                       if (key != null)
+                               propagateProperty(fParent, key, fStore);
+               }
+       }
+
+       private IPreferenceStore fParent;
+
+       private IPreferenceStore fStore;
+
+       private OverlayKey[] fOverlayKeys;
+
+       private PropertyListener fPropertyListener;
+
+       private boolean fLoaded;
+
+       public OverlayPreferenceStore(IPreferenceStore parent,
+                       OverlayKey[] overlayKeys) {
+               fParent = parent;
+               fOverlayKeys = overlayKeys;
+               fStore = new PreferenceStore();
+       }
+
+       private OverlayKey findOverlayKey(String key) {
+               for (int i = 0; i < fOverlayKeys.length; i++) {
+                       if (fOverlayKeys[i].fKey.equals(key))
+                               return fOverlayKeys[i];
+               }
+               return null;
+       }
+
+       private boolean covers(String key) {
+               return (findOverlayKey(key) != null);
+       }
+
+       private void propagateProperty(IPreferenceStore orgin, OverlayKey key,
+                       IPreferenceStore target) {
+
+               if (orgin.isDefault(key.fKey)) {
+                       if (!target.isDefault(key.fKey))
+                               target.setToDefault(key.fKey);
+                       return;
+               }
+
+               TypeDescriptor d = key.fDescriptor;
+               if (BOOLEAN == d) {
+
+                       boolean originValue = orgin.getBoolean(key.fKey);
+                       boolean targetValue = target.getBoolean(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (DOUBLE == d) {
+
+                       double originValue = orgin.getDouble(key.fKey);
+                       double targetValue = target.getDouble(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (FLOAT == d) {
+
+                       float originValue = orgin.getFloat(key.fKey);
+                       float targetValue = target.getFloat(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (INT == d) {
+
+                       int originValue = orgin.getInt(key.fKey);
+                       int targetValue = target.getInt(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (LONG == d) {
+
+                       long originValue = orgin.getLong(key.fKey);
+                       long targetValue = target.getLong(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (STRING == d) {
+
+                       String originValue = orgin.getString(key.fKey);
+                       String targetValue = target.getString(key.fKey);
+                       if (targetValue != null && originValue != null
+                                       && !targetValue.equals(originValue))
+                               target.setValue(key.fKey, originValue);
+
+               }
+       }
+
+       public void propagate() {
+               for (int i = 0; i < fOverlayKeys.length; i++)
+                       propagateProperty(fStore, fOverlayKeys[i], fParent);
+       }
+
+       private void loadProperty(IPreferenceStore orgin, OverlayKey key,
+                       IPreferenceStore target, boolean forceInitialization) {
+               TypeDescriptor d = key.fDescriptor;
+               if (BOOLEAN == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, true);
+                       target.setValue(key.fKey, orgin.getBoolean(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultBoolean(key.fKey));
+
+               } else if (DOUBLE == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, 1.0D);
+                       target.setValue(key.fKey, orgin.getDouble(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultDouble(key.fKey));
+
+               } else if (FLOAT == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, 1.0F);
+                       target.setValue(key.fKey, orgin.getFloat(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultFloat(key.fKey));
+
+               } else if (INT == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, 1);
+                       target.setValue(key.fKey, orgin.getInt(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultInt(key.fKey));
+
+               } else if (LONG == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, 1L);
+                       target.setValue(key.fKey, orgin.getLong(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultLong(key.fKey));
+
+               } else if (STRING == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, "1"); //$NON-NLS-1$
+                       target.setValue(key.fKey, orgin.getString(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultString(key.fKey));
+
+               }
+       }
+
+       public void load() {
+               for (int i = 0; i < fOverlayKeys.length; i++)
+                       loadProperty(fParent, fOverlayKeys[i], fStore, true);
+
+               fLoaded = true;
+
+       }
+
+       public void loadDefaults() {
+               for (int i = 0; i < fOverlayKeys.length; i++)
+                       setToDefault(fOverlayKeys[i].fKey);
+       }
+
+       public void start() {
+               if (fPropertyListener == null) {
+                       fPropertyListener = new PropertyListener();
+                       fParent.addPropertyChangeListener(fPropertyListener);
+               }
+       }
+
+       public void stop() {
+               if (fPropertyListener != null) {
+                       fParent.removePropertyChangeListener(fPropertyListener);
+                       fPropertyListener = null;
+               }
+       }
+
+       /*
+        * @see IPreferenceStore#addPropertyChangeListener(IPropertyChangeListener)
+        */
+       public void addPropertyChangeListener(IPropertyChangeListener listener) {
+               fStore.addPropertyChangeListener(listener);
+       }
+
+       /*
+        * @see IPreferenceStore#removePropertyChangeListener(IPropertyChangeListener)
+        */
+       public void removePropertyChangeListener(IPropertyChangeListener listener) {
+               fStore.removePropertyChangeListener(listener);
+       }
+
+       /*
+        * @see IPreferenceStore#firePropertyChangeEvent(String, Object, Object)
+        */
+       public void firePropertyChangeEvent(String name, Object oldValue,
+                       Object newValue) {
+               fStore.firePropertyChangeEvent(name, oldValue, newValue);
+       }
+
+       /*
+        * @see IPreferenceStore#contains(String)
+        */
+       public boolean contains(String name) {
+               return fStore.contains(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getBoolean(String)
+        */
+       public boolean getBoolean(String name) {
+               return fStore.getBoolean(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultBoolean(String)
+        */
+       public boolean getDefaultBoolean(String name) {
+               return fStore.getDefaultBoolean(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultDouble(String)
+        */
+       public double getDefaultDouble(String name) {
+               return fStore.getDefaultDouble(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultFloat(String)
+        */
+       public float getDefaultFloat(String name) {
+               return fStore.getDefaultFloat(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultInt(String)
+        */
+       public int getDefaultInt(String name) {
+               return fStore.getDefaultInt(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultLong(String)
+        */
+       public long getDefaultLong(String name) {
+               return fStore.getDefaultLong(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultString(String)
+        */
+       public String getDefaultString(String name) {
+               return fStore.getDefaultString(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDouble(String)
+        */
+       public double getDouble(String name) {
+               return fStore.getDouble(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getFloat(String)
+        */
+       public float getFloat(String name) {
+               return fStore.getFloat(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getInt(String)
+        */
+       public int getInt(String name) {
+               return fStore.getInt(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getLong(String)
+        */
+       public long getLong(String name) {
+               return fStore.getLong(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getString(String)
+        */
+       public String getString(String name) {
+               return fStore.getString(name);
+       }
+
+       /*
+        * @see IPreferenceStore#isDefault(String)
+        */
+       public boolean isDefault(String name) {
+               return fStore.isDefault(name);
+       }
+
+       /*
+        * @see IPreferenceStore#needsSaving()
+        */
+       public boolean needsSaving() {
+               return fStore.needsSaving();
+       }
+
+       /*
+        * @see IPreferenceStore#putValue(String, String)
+        */
+       public void putValue(String name, String value) {
+               if (covers(name))
+                       fStore.putValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, double)
+        */
+       public void setDefault(String name, double value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, float)
+        */
+       public void setDefault(String name, float value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, int)
+        */
+       public void setDefault(String name, int value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, long)
+        */
+       public void setDefault(String name, long value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, String)
+        */
+       public void setDefault(String name, String value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, boolean)
+        */
+       public void setDefault(String name, boolean value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setToDefault(String)
+        */
+       public void setToDefault(String name) {
+               fStore.setToDefault(name);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, double)
+        */
+       public void setValue(String name, double value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, float)
+        */
+       public void setValue(String name, float value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, int)
+        */
+       public void setValue(String name, int value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, long)
+        */
+       public void setValue(String name, long value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, String)
+        */
+       public void setValue(String name, String value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, boolean)
+        */
+       public void setValue(String name, boolean value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /**
+        * The keys to add to the list of overlay keys.
+        * <p>
+        * Note: This method must be called before {@link #load()} is called.
+        * </p>
+        * 
+        * @param keys
+        * @since 3.0
+        */
+       public void addKeys(OverlayKey[] keys) {
+               Assert.isTrue(!fLoaded);
+               Assert.isNotNull(keys);
+
+               int overlayKeysLength = fOverlayKeys.length;
+               OverlayKey[] result = new OverlayKey[keys.length + overlayKeysLength];
+
+               for (int i = 0, length = overlayKeysLength; i < length; i++)
+                       result[i] = fOverlayKeys[i];
+
+               for (int i = 0, length = keys.length; i < length; i++)
+                       result[overlayKeysLength + i] = keys[i];
+
+               fOverlayKeys = result;
+
+               if (fLoaded)
+                       load();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.java
new file mode 100644 (file)
index 0000000..2356ede
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class PreferencesMessages {
+
+       private static final String RESOURCE_BUNDLE = "net.sourceforge.phpdt.internal.ui.preferences.PreferencesMessages";//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private PreferencesMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       public static String getFormattedString(String key, String arg) {
+               return getFormattedString(key, new String[] { arg });
+       }
+
+       public static String getFormattedString(String key, String[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/PreferencesMessages.properties
new file mode 100644 (file)
index 0000000..7a0486e
--- /dev/null
@@ -0,0 +1,730 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+BuildPathsPropertyPage.error.message=An error occurred while setting the build path
+BuildPathsPropertyPage.error.title=Error Setting Build Path
+BuildPathsPropertyPage.no_java_project.message=Not a PHP project.
+BuildPathsPropertyPage.closed_project.message=PHP information is not available for a closed project.
+
+ClasspathVariablesPreferencePage.title=Classpath Variables
+ClasspathVariablesPreferencePage.description=A classpath variable can be added to a project's class path. It can be used to define the location of a JAR file that isn't part of the workspace. The reserved class path variables JRE_LIB, JRE_SRC, JRE_SRCROOT are set internally depending on the JRE setting.
+
+ImportOrganizePreferencePage.description=Preferences used by the Organize Imports action:
+
+ImportOrganizePreferencePage.order.label=Define the &sorting order of import statements. A package name prefix (e.g. org.eclipse) is a valid entry.
+
+ImportOrganizePreferencePage.order.add.button=&New...
+ImportOrganizePreferencePage.order.edit.button=&Edit...
+ImportOrganizePreferencePage.order.up.button=&Up
+ImportOrganizePreferencePage.order.down.button=Do&wn
+ImportOrganizePreferencePage.order.remove.button=&Remove
+ImportOrganizePreferencePage.order.load.button=&Load...
+ImportOrganizePreferencePage.order.save.button=Sa&ve...
+ImportOrganizePreferencePage.ignoreLowerCase.label=Do not create imports for &types starting with a lowercase letter
+
+ImportOrganizePreferencePage.threshold.label=Number of &imports needed for .* (e.g. org.eclipse.*):
+ImportOrganizePreferencePage.error.invalidthreshold=Invalid import number.
+
+ImportOrganizePreferencePage.loadDialog.title=Load Import Order from File
+ImportOrganizePreferencePage.loadDialog.error.title=Load Import Order
+ImportOrganizePreferencePage.loadDialog.error.message=Loading failed. Not a valid import order file.
+
+ImportOrganizePreferencePage.saveDialog.title=Save Import Order to File
+ImportOrganizePreferencePage.saveDialog.error.title=Save Import Order
+ImportOrganizePreferencePage.saveDialog.error.message=Writing import order file failed.
+
+
+ImportOrganizeInputDialog.title=Import Order Entry
+ImportOrganizeInputDialog.message=&Package name or package name prefix:
+ImportOrganizeInputDialog.browse.button=&Browse...
+ImportOrganizeInputDialog.ChoosePackageDialog.title=Package Selection
+ImportOrganizeInputDialog.ChoosePackageDialog.description=Choose package name or package prefix:
+ImportOrganizeInputDialog.ChoosePackageDialog.empty=No packages available.
+ImportOrganizeInputDialog.error.enterName=Enter a package name.
+ImportOrganizeInputDialog.error.invalidName=Not a valid package name. {0}
+ImportOrganizeInputDialog.error.entryExists=Package name already exists in list.
+
+JavaBasePreferencePage.description=General settings for PHP development:
+
+JavaBasePreferencePage.updateJavaViews=Update PHP views
+JavaBasePreferencePage.onSave=On &save only
+JavaBasePreferencePage.whileEditing=While &editing
+JavaBasePreferencePage.note=Note:
+JavaBasePreferencePage.notice.outliner=This preference is not applied to already opened views\n(Outline view is always updated while editing)
+
+JavaBasePreferencePage.openTypeHierarchy=When opening a Type Hierarchy
+JavaBasePreferencePage.inPerspective=Open a new Type Hierarchy &Perspective
+JavaBasePreferencePage.inView=Show the &Type Hierarchy View in the current perspective
+JavaBasePreferencePage.doubleclick.action=Action on double click in the Package Explorer
+JavaBasePreferencePage.doubleclick.gointo=&Go into the selected element
+JavaBasePreferencePage.doubleclick.expand=E&xpand the selected element
+
+NewJavaProjectPreferencePage.description=Specify the classpath entries used as default by the New PHP Project creation wizard:
+
+NewJavaProjectPreferencePage.sourcefolder.label=Source and output folder
+NewJavaProjectPreferencePage.sourcefolder.project=&Project
+NewJavaProjectPreferencePage.sourcefolder.folder=&Folders
+NewJavaProjectPreferencePage.folders.src=&Source folder name:
+NewJavaProjectPreferencePage.folders.bin=&Output folder name:
+
+NewJavaProjectPreferencePage.folders.error.namesempty=Enter folder names.
+NewJavaProjectPreferencePage.folders.error.invalidsrcname=Invalid source folder name: {0}
+NewJavaProjectPreferencePage.folders.error.invalidbinname=Invalid output folder name: {0}
+NewJavaProjectPreferencePage.folders.error.invalidcp=Settings will result in an invalid build path. Check for nested folders.
+
+JavaEditorPreferencePage.appearanceTabLink=Some general preferences now live on the Eclipse <a href="org.eclipse.ui.preferencePages.GeneralTextEditor">Text Editors</a> pages.
+JavaEditorPreferencePage.appearanceTabTooltip=Jump to the Text Editors page
+
+JavaEditorPreferencePage.annotationsTab.title= Annotation&s
+JavaEditorPreferencePage.showQuickFixables= Indicate annotations solvable with &Quick Fix in vertical ruler
+JavaEditorPreferencePage.analyseAnnotationsWhileTyping= Analyze annotations &while typing
+JavaEditorPreferencePage.annotationPresentationOptions= Annotation &presentation:
+JavaEditorPreferencePage.description=PHP Editor settings:
+JavaEditorPreferencePage.annotations.bookmarks= Bookmarks
+JavaEditorPreferencePage.annotations.searchResults= Search Results
+JavaEditorPreferencePage.annotations.errors= Errors
+JavaEditorPreferencePage.annotations.warnings= Warnings
+JavaEditorPreferencePage.annotations.tasks= Tasks
+JavaEditorPreferencePage.annotations.others= Others
+JavaEditorPreferencePage.annotations.showInText= Show in &text
+TextEditorPreferencePage.annotations.highlightInText= &Highlight in text
+JavaEditorPreferencePage.annotations.showInOverviewRuler= Show in overview &ruler
+JavaEditorPreferencePage.annotations.showInVerticalRuler= Show in vertical r&uler
+JavaEditorPreferencePage.annotations.color= C&olor:
+JavaEditorPreferencePage.tags=PHP tags
+JavaEditorPreferencePage.multiLineComment=Multi-line comment
+JavaEditorPreferencePage.singleLineComment=Single-line comment
+JavaEditorPreferencePage.returnKeyword= Keyword 'return'
+JavaEditorPreferencePage.keywords=Keywords excluding 'return'
+JavaEditorPreferencePage.functionNames=Predefined function names
+JavaEditorPreferencePage.variables='$' Variables
+JavaEditorPreferencePage.variables_dollar='$_' Variables
+JavaEditorPreferencePage.constants=Constants
+JavaEditorPreferencePage.types=Types
+JavaEditorPreferencePage.strings_dq=Double Quoted Strings
+JavaEditorPreferencePage.strings_sq=Single Quoted Strings
+JavaEditorPreferencePage.others=Others
+JavaEditorPreferencePage.methodNames=Method names
+JavaEditorPreferencePage.operators=Operators, brackets excluding '{}'
+JavaEditorPreferencePage.braces='{}' brackets
+JavaEditorPreferencePage.javaCommentTaskTags=Task Tags
+JavaEditorPreferencePage.phpDocKeywords=PHPDoc keywords
+JavaEditorPreferencePage.phpDocHtmlTags=PHPDoc HTML tags
+JavaEditorPreferencePage.phpDocLinks=PHPDoc links
+JavaEditorPreferencePage.phpDocOthers=PHPDoc others
+
+JavaEditorPreferencePage.backgroundColor=Background color
+JavaEditorPreferencePage.systemDefault=S&ystem Default
+JavaEditorPreferencePage.custom=C&ustom:
+JavaEditorPreferencePage.foreground=Fo&reground:
+JavaEditorPreferencePage.color=C&olor:
+JavaEditorPreferencePage.bold=&Bold
+JavaEditorPreferencePage.preview=Preview:
+JavaEditorPreferencePage.displayedTabWidth=Displayed &tab width:
+JavaEditorPreferencePage.insertSpaceForTabs=Ins&ert spaces for tab (see Code Formatter preference page)
+JavaEditorPreferencePage.showOverviewRuler=Show overview &ruler
+JavaEditorPreferencePage.highlightMatchingBrackets=Highlight &matching brackets
+JavaEditorPreferencePage.highlightCurrentLine=Hi&ghlight current line
+JavaEditorPreferencePage.showPrintMargin=Sho&w print margin
+JavaEditorPreferencePage.printMarginColumn=Print margin col&umn:
+JavaEditorPreferencePage.insertSingleProposalsAutomatically=Insert single &proposals automatically
+JavaEditorPreferencePage.showOnlyProposalsVisibleInTheInvocationContext=S&how only proposals visible in the invocation context
+JavaEditorPreferencePage.presentProposalsInAlphabeticalOrder=Present proposals in a&lphabetical order
+JavaEditorPreferencePage.enableAutoActivation=&Enable auto activation
+JavaEditorPreferencePage.automaticallyAddImportInsteadOfQualifiedName=Automatically add import instead of &qualified name
+JavaEditorPreferencePage.completionInserts=Completion inser&ts
+JavaEditorPreferencePage.completionOverwrites=Completion over&writes
+JavaEditorPreferencePage.fillArgumentNamesOnMethodCompletion=&Fill argument names on method completion
+JavaEditorPreferencePage.guessArgumentNamesOnMethodCompletion=&Guess filled argument names
+JavaEditorPreferencePage.autoActivationDelay=A&uto activation delay:
+JavaEditorPreferencePage.autoActivationTriggersForJava=Auto activation &triggers for PHP:
+JavaEditorPreferencePage.autoActivationTriggersForJavaDoc=Auto activation triggers for &PHPdoc:
+JavaEditorPreferencePage.autoActivationTriggersForHTML=Auto activation triggers for &HTML:
+
+JavaEditorPreferencePage.codeAssist.colorOptions= Code assist colo&r options:
+JavaEditorPreferencePage.codeAssist.color= C&olor:
+JavaEditorPreferencePage.backgroundForCompletionProposals= Completion proposal background
+JavaEditorPreferencePage.foregroundForCompletionProposals= Completion proposal foreground
+JavaEditorPreferencePage.backgroundForMethodParameters= Method parameter background
+JavaEditorPreferencePage.foregroundForMethodParameters= Method parameter foreground
+JavaEditorPreferencePage.backgroundForCompletionReplacement= Completion overwrite background
+JavaEditorPreferencePage.foregroundForCompletionReplacement= Completion overwrite foreground
+
+JavaEditorPreferencePage.general=Appeara&nce
+JavaEditorPreferencePage.colors=Synta&x
+JavaEditorPreferencePage.codeAssist= &Code Assist
+JavaEditorPreferencePage.empty_input=Empty input
+JavaEditorPreferencePage.invalid_input=''{0}'' is not a valid input.
+JavaEditorPreferencePage.matchingBracketsHighlightColor2=Matching brackets highlight
+JavaEditorPreferencePage.currentLineHighlighColor=Current line highlight
+JavaEditorPreferencePage.printMarginColor2=Print margin
+JavaEditorPreferencePage.findScopeColor2=Find scope
+JavaEditorPreferencePage.linkedPositionColor2=Linked focus position
+JavaEditorPreferencePage.linkedPositionSlaveColor2=Linked position
+JavaEditorPreferencePage.linkedPositionTargetColor2=Linked target position
+JavaEditorPreferencePage.linkedPositionExitColor2=Linked exit position
+JavaEditorPreferencePage.linkColor2=Link
+JavaEditorPreferencePage.synchronizeOnCursor=Synchroni&ze outline selection and range indication on caret move
+JavaEditorPreferencePage.appearanceOptions=Appearance co&lor options:
+
+JavaEditorPreferencePage.typing.tabTitle= T&yping
+JavaEditorPreferencePage.typing.description= Select options for automatic text modifications
+JavaEditorPreferencePage.closeStringsDQ= Close double quoted strin&gs
+JavaEditorPreferencePage.closeStringsSQ= Close &single quoted strings
+JavaEditorPreferencePage.closeBrackets= Close &brackets and parenthesis
+JavaEditorPreferencePage.closeBraces= Cl&ose braces
+JavaEditorPreferencePage.closeJavaDocs= Close PHP&docs and comments
+JavaEditorPreferencePage.formatJavaDocs= &Wrap PHPdocs and comments at print margin
+JavaEditorPreferencePage.wrapWords= Wrap words
+JavaEditorPreferencePage.wrapStringsDQ= Wra&p double quoted PHP strings
+JavaEditorPreferencePage.escapeStringsDQ= &Escape text when pasting into a double quoted PHP string
+JavaEditorPreferencePage.wrapStringsSQ= Wra&p single quoted PHP strings
+JavaEditorPreferencePage.escapeStringsSQ= &Escape text when pasting into a single quoted PHP string
+JavaEditorPreferencePage.addJavaDocTags= Add PHPdoc &tags
+JavaEditorPreferencePage.smartPaste= Pasting fo&r correct indentation
+
+JavaEditorPreferencePage.smartHomeEnd= S&mart cursor positioning at line start and end
+JavaEditorPreferencePage.subWordNavigation= Smart cursor positioning in &PHP names
+JavaEditorPreferencePage.overwriteMode= Disable over&write typing mode in PHP editors
+
+JavaEditorPreferencePage.hoverTab.title= Ho&vers
+
+JavaEditorPreferencePage.navigationTab.title= Nav&igation
+JavaEditorPreferencePage.navigation.browserLikeLinks= S&upport hyperlink style navigation for "Open Declaration"
+JavaEditorPreferencePage.navigation.browserLikeLinksKeyModifier= Hyperlink style navigation key &modifier:
+JavaEditorPreferencePage.navigation.modifierIsNotValid= Modifier ''{0}'' is not valid.
+JavaEditorPreferencePage.navigation.shiftIsDisabled= The modifier 'Shift' is not allowed because 'Shift' + click sets a new selection.
+
+JavaEditorPreferencePage.navigation.delimiter= +
+JavaEditorPreferencePage.navigation.insertDelimiterAndModifierAndDelimiter= \ + {0} +
+JavaEditorPreferencePage.navigation.insertModifierAndDelimiter= \ {0} +
+JavaEditorPreferencePage.navigation.insertDelimiterAndModifier= \ + {0}
+
+MarkOccurrencesConfigurationBlock.title=Mark Occurences
+JavaEditorPreferencePage.markOccurrences= Mar&k occurrences in file
+JavaEditorPreferencePage.stickyOccurrences= S&ticky
+
+JavaEditorHoverConfigurationBlock.hoverPreferences= &Hover key modifier preferences:
+JavaEditorHoverConfigurationBlock.enabled= &Enabled
+JavaEditorHoverConfigurationBlock.keyModifier= Key &Modifier:
+JavaEditorHoverConfigurationBlock.description= Description:
+JavaEditorHoverConfigurationBlock.modifierIsNotValid= Modifier ''{0}'' is not valid.
+JavaEditorHoverConfigurationBlock.modifierIsNotValidForHover= Modifier ''{0}'' for ''{1}'' hover is not valid.
+JavaEditorHoverConfigurationBlock.duplicateModifier= ''{0}'' hover uses the same modifier as ''{1}'' hover.
+
+JavaEditorHoverConfigurationBlock.delimiter= +
+JavaEditorHoverConfigurationBlock.insertDelimiterAndModifierAndDelimiter= \ + {0} +
+JavaEditorHoverConfigurationBlock.insertModifierAndDelimiter= \ {0} +
+JavaEditorHoverConfigurationBlock.insertDelimiterAndModifier= \ + {0}
+
+JavaEditorHoverConfigurationBlock.showAffordance= Show affordance in hover on how to make it sticky
+
+JavaElementInfoPage.binary=binary
+JavaElementInfoPage.classpath_entry_kind=Classpath entry kind:
+JavaElementInfoPage.library=library
+JavaElementInfoPage.nameLabel=Name:
+JavaElementInfoPage.not_present=not present
+JavaElementInfoPage.package=Package:
+JavaElementInfoPage.package_contents=Package contents:
+JavaElementInfoPage.project=project
+JavaElementInfoPage.resource_path=Resource path:
+JavaElementInfoPage.source=source
+JavaElementInfoPage.variable=variable
+JavaElementInfoPage.variable_path=Variable path:
+JavaElementInfoPage.location=Location:
+
+JavadocConfigurationPropertyPage.IsPackageFragmentRoot.description=Specify the location (URL) of the documentation generated by PHPdoc. The PHPdoc location will contain a file called 'package-list'.
+JavadocConfigurationPropertyPage.IsIncorrectElement.description=PHPdoc location can only be attached to PHP projects or JAR files in PHP projects
+JavadocConfigurationPropertyPage.IsJavaProject.description=Specify the location of the project\'s PHPdoc documentation. This location is used by the PHPdoc export wizard as the default value and by the \'Open External PHPdoc\' action. For example: \'c:/myworkspace/myproject/doc\'.
+
+JavadocConfigurationBlock.browse.button=&Browse...
+JavadocConfigurationBlock.error.notafolder=Location does not exist.
+JavadocConfigurationBlock.warning.packagelistnotfound=Location does not contain file 'package-list'.
+JavadocConfigurationBlock.javadocFolderDialog.label=PHPdoc Location Selection
+JavadocConfigurationBlock.javadocFolderDialog.message=Select PHPdoc location:
+JavadocConfigurationBlock.javadocArchiveDialog.label=PHPdoc Archive Selection
+JavadocConfigurationBlock.MalformedURL.error=Invalid URL
+JavadocConfigurationBlock.validate.button=&Validate...
+JavadocConfigurationBlock.InvalidLocation.message= Location is invalid. Location contains neither the file \'package-list\' nor \'index.html'.
+JavadocConfigurationBlock.ValidLocation.message= Location is valid. Files \'package-list\' and \'index.html\' found. Click OK to open in browser.
+JavadocConfigurationBlock.UnableToValidateLocation.message=Unable to validate location
+JavadocConfigurationBlock.MessageDialog.title=Validating PHPdoc Location
+JavadocConfigurationBlock.location.type.path.label=PHPdoc URL (e.g. \'http://www.sample-url.org/doc/\' or 'file:/c:/myworkspace/myproject/doc\')
+JavadocConfigurationBlock.location.type.jar.label=PHPdoc in archive
+JavadocConfigurationBlock.location.path.label=PHPdoc &location path:
+JavadocConfigurationBlock.location.jar.label=Archive &path:
+JavadocConfigurationBlock.jar.path.label=Path &within archive:
+JavadocConfigurationBlock.zipImportSource.title=PHPdoc Archive Selection
+JavadocConfigurationBlock.location_in_jarorzip.message=&Select the folder that is the root of the PHPdoc documentation:
+JavadocConfigurationBlock.browse_jarorzip_path.title=PHPdoc Root Location
+JavadocConfigurationBlock.error.notafile=Archive does not exist
+
+JavadocPreferencePage.description=Specify the location of the PHPdoc command to be used by the PHPdoc export wizard. Location must be an absolute path.
+JavadocPreferencePage.command.label=&PHPdoc command:
+JavadocPreferencePage.command.button=&Browse...
+
+JavadocPreferencePage.error.notexists=PHPdoc command does not exist
+JavadocPreferencePage.info.notset=Set to enable PHPdoc generation tool.
+
+JavadocPreferencePage.browsedialog.title=PHPdoc Command Selection
+
+
+SourceAttachmentPropertyPage.error.title=Error Attaching Source
+SourceAttachmentPropertyPage.error.message=An error occurred while associating the source
+
+SourceAttachmentPropertyPage.noarchive.message=Source can only be attached to JAR files in PHP projects.
+SourceAttachmentPropertyPage.containerentry.message=JAR belongs to the container ''{0}''.\nTo configure the source attachment, go directly to the corresponding configuration page (For example for JREs go to ''Installed JREs'' page in the preferences).
+
+AppearancePreferencePage.description= Appearance of PHP elements in viewers:
+AppearancePreferencePage.methodreturntype.label= Show &method return types
+AppearancePreferencePage.overrideindicator.label= Show &override indicators in outline and hierarchy
+AppearancePreferencePage.pkgNamePatternEnable.label= &Compress all package name segments, except the final segment
+AppearancePreferencePage.pkgNamePattern.label= Com&pression pattern (e.g. given package name 'net.sourceforge.phpdt' pattern '.' will compress it to '..jdt',  '0' to 'jdt', '1~.' to 'o~.e~.jdt'):
+AppearancePreferencePage.showMembersInPackagesView=S&how members in Package Explorer
+AppearancePreferencePage.stackViewsVerticallyInTheJavaBrowsingPerspective=&Stack views vertically in the Java Browsing perspective
+AppearancePreferencePage.note=Note:
+AppearancePreferencePage.preferenceOnlyEffectiveForNewPerspectives=This preference will only take effect on new perspectives
+AppearancePreferencePage.packageNameCompressionPattern.error.isEmpty=Enter a package name compression pattern
+AppearancePreferencePage.foldEmptyPackages= &Fold empty packages in hierarchical Package Explorer layout
+
+CodeFormatterPreferencePage.title=Code Formatter
+CodeFormatterPreferencePage.description=Sele&ct a profile:
+
+CodeFormatterPreferencePage.empty_input=Empty input
+CodeFormatterPreferencePage.invalid_input=''{0}'' is not a valid input.
+
+CodeFormatterPreferencePage.newline_opening_braces.label=I&nsert a new line before an opening brace
+CodeFormatterPreferencePage.newline_control_statement.label=Insert new &lines in control statements
+CodeFormatterPreferencePage.newline_clear_lines=Clear all &blank lines
+CodeFormatterPreferencePage.newline_else_if.label=&Insert new line between 'else if'
+CodeFormatterPreferencePage.newline_empty_block.label=In&sert a new line inside an empty block
+CodeFormatterPreferencePage.split_code.label=Ma&ximum code line length:
+CodeFormatterPreferencePage.split_comment.label=Maxi&mum comment line length:
+CodeFormatterPreferencePage.style_compact_assignement.label=&Compact assignment
+CodeFormatterPreferencePage.style_space_castexpression.label=Insert sp&ace after a cast
+CodeFormatterPreferencePage.tab_char.label=Insert &tabs for indentation, not spaces
+CodeFormatterPreferencePage.tab_size.label=&Number of spaces representing an indentation level:
+CodeFormatterPreferencePage.comment_format.label=&Format comments
+CodeFormatterPreferencePage.comment_formathtml.label=Format HTML &tags
+CodeFormatterPreferencePage.comment_formatsource.label=Format PHP code &snippets
+CodeFormatterPreferencePage.comment_indentroottags.label=&Indent PHPdoc tags
+CodeFormatterPreferencePage.comment_newlineparam.label=&New line after PHPdoc tag parameters
+CodeFormatterPreferencePage.comment_separateroottags.label=&Empty line before PHPdoc tag block
+CodeFormatterPreferencePage.comment_formatheader.label=Format &header comment
+CodeFormatterPreferencePage.comment_indentparamdesc.label= Indent PHPdoc parameter &descriptions
+
+CodeFormatterPreferencePage.tab.newline.tabtitle=Ne&w Lines
+CodeFormatterPreferencePage.tab.linesplit.tabtitle=Line Len&gth
+CodeFormatterPreferencePage.tab.style.tabtitle=St&yle
+CodeFormatterPreferencePage.tab.comment.tabtitle=&Comments
+
+TodoTaskPreferencePage.title=Task Tags
+
+TodoTaskPropertyPage.useworkspacesettings.label=Use &workspace settings
+TodoTaskPropertyPage.useworkspacesettings.change=&Configure Workspace Settings...
+TodoTaskPropertyPage.useprojectsettings.label=Use pr&oject settings
+
+TodoTaskConfigurationBlock.markers.tasks.high.priority=High
+TodoTaskConfigurationBlock.markers.tasks.normal.priority=Normal
+TodoTaskConfigurationBlock.markers.tasks.low.priority=Low
+TodoTaskConfigurationBlock.markers.tasks.label=&Strings indicating tasks in PHP comments:
+TodoTaskConfigurationBlock.markers.tasks.add.button=&New...
+TodoTaskConfigurationBlock.markers.tasks.remove.button=&Remove
+TodoTaskConfigurationBlock.markers.tasks.edit.button=&Edit...
+TodoTaskConfigurationBlock.markers.tasks.name.column=Tag
+TodoTaskConfigurationBlock.markers.tasks.priority.column=Priority
+
+TodoTaskConfigurationBlock.needsbuild.title=Task Tags Settings Changed
+TodoTaskConfigurationBlock.needsfullbuild.message=The task tags settings have changed. A full rebuild is required to make changes effective. Do the full build now?
+TodoTaskConfigurationBlock.needsprojectbuild.message=The task tags settings have changed. A rebuild of the project is required to make changes effective. Do the project build now?
+
+TodoTaskInputDialog.new.title=New Task Tag
+TodoTaskInputDialog.edit.title=Edit Task Tag
+TodoTaskInputDialog.name.label=T&ag:
+TodoTaskInputDialog.priority.label=&Priority:
+TodoTaskInputDialog.priority.high=High
+TodoTaskInputDialog.priority.normal=Normal
+TodoTaskInputDialog.priority.low=Low
+TodoTaskInputDialog.error.enterName=Enter task tag name.
+TodoTaskInputDialog.error.comma=Name cannot contain a comma.
+TodoTaskInputDialog.error.entryExists=Entry with the same name already exists.
+TodoTaskInputDialog.error.noSpace=Name can not start or end with a whitespace.
+
+CompilerPreferencePage.title=Compiler
+CompilerPreferencePage.description=Options for the PHP compiler:\nNote that a full rebuild is required to make changes effective.
+
+CompilerPropertyPage.useworkspacesettings.label=Use &workspace settings
+CompilerPropertyPage.useworkspacesettings.change=&Configure Workspace Settings...
+CompilerPropertyPage.useprojectsettings.label=Use pr&oject settings
+
+CompilerConfigurationBlock.advanced.tabtitle=Ad&vanced
+CompilerConfigurationBlock.unused.tabtitle=&Unused Code
+CompilerConfigurationBlock.common.tabtitle=&Style
+CompilerConfigurationBlock.compliance.tabtitle=&Compliance and Classfiles
+CompilerConfigurationBlock.others.tabtitle=Build &Path
+CompilerConfigurationBlock.javadoc.tabtitle=&PHPdoc
+
+CompilerConfigurationBlock.common.description=Select the severity level for the following problems:
+CompilerConfigurationBlock.unused.description=Select the severity level for the following problems:
+CompilerConfigurationBlock.advanced.description=Select the severity level for the following problems:
+CompilerConfigurationBlock.build_warnings.description=Select the severity level for the following build path problems:
+
+CompilerConfigurationBlock.variable_attr.label=Add varia&ble attributes to generated class files (used by the debugger)
+CompilerConfigurationBlock.line_number_attr.label=Add &line number attributes to generated class files (used by the debugger)
+CompilerConfigurationBlock.source_file_attr.label=Add source &file name to generated class file (used by the debugger)
+CompilerConfigurationBlock.codegen_unused_local.label=Pr&eserve unused local variables (never read)
+
+CompilerConfigurationBlock.compiler_compliance.label=Comp&iler compliance level:
+CompilerConfigurationBlock.default_settings.label=Use defaul&t compliance settings
+CompilerConfigurationBlock.source_compatibility.label=Source co&mpatibility:
+CompilerConfigurationBlock.codegen_targetplatform.label=Ge&nerated .class files compatibility:
+CompilerConfigurationBlock.pb_assert_as_identifier.label=Disallow identifie&rs called 'assert':
+
+CompilerConfigurationBlock.compliance.group.label=JDK Compliance
+CompilerConfigurationBlock.classfiles.group.label=Classfile Generation
+
+CompilerConfigurationBlock.pb_file_not_exist.label=Include filename doesn't exist in project:
+CompilerConfigurationBlock.pb_var_deprecated.label=Keyword 'var' is deprecated:
+CompilerConfigurationBlock.pb_keyword.label=Don't use keyword as identifier:
+CompilerConfigurationBlock.pb_uppercase_identifier.label=Non-variable identifiers should contain only uppercase characters:
+CompilerConfigurationBlock.pb_unreachable_code.label=&Unreachable code:
+CompilerConfigurationBlock.pb_unitialized_local_variable.label=Uninitialized local function or method variable:
+
+CompilerConfigurationBlock.pb_invalid_import.label=Unresol&vable import statements:
+CompilerConfigurationBlock.pb_overriding_pkg_dflt.label=&Methods overridden but not package visible:
+CompilerConfigurationBlock.pb_method_naming.label=Me&thods with a constructor name:
+CompilerConfigurationBlock.pb_no_effect_assignment.label=Assignment has no &effect (e.g. 'x = x'):
+CompilerConfigurationBlock.pb_incompatible_interface_method.label=Conflict of &interface method with protected 'Object' method:
+
+CompilerConfigurationBlock.pb_indirect_access_to_static.label=Indi&rect access to static member:
+
+CompilerConfigurationBlock.pb_hidden_catchblock.label=&Hidden catch blocks:
+CompilerConfigurationBlock.pb_static_access_receiver.label=Non-stat&ic access to static member:
+CompilerConfigurationBlock.pb_unused_imports.label=Unus&ed imports:
+CompilerConfigurationBlock.pb_unused_local.label=&Local variable is never read:
+CompilerConfigurationBlock.pb_unused_parameter.label=Parameter is &never read:
+CompilerConfigurationBlock.pb_signal_param_in_overriding.label=Chec&k overriding and implementing methods
+
+CompilerConfigurationBlock.pb_unused_private.label=Unused or unread priva&te members:
+CompilerConfigurationBlock.pb_non_externalized_strings.label=Usage of non-e&xternalized strings:
+CompilerConfigurationBlock.pb_deprecation.label=Usa&ge of deprecated API:
+CompilerConfigurationBlock.pb_deprecation_in_deprecation.label=Signal use o&f deprecated API inside deprecated code.
+CompilerConfigurationBlock.pb_deprecation_when_overriding.label=Check ove&rriding and implementing methods
+CompilerConfigurationBlock.pb_superfluous_semicolon.label=Unnecessary se&micolon:
+CompilerConfigurationBlock.pb_unnecessary_type_check.label=Unnecessary cast or '&instanceof' operation:
+
+CompilerConfigurationBlock.pb_synth_access_emul.label=Access to a &non-accessible member of an enclosing type:
+CompilerConfigurationBlock.pb_char_array_in_concat.label=Using a c&har array in string concatenation:
+CompilerConfigurationBlock.pb_incomplete_build_path.label=&Incomplete build path:
+CompilerConfigurationBlock.pb_build_path_cycles.label=Circular d&ependencies:
+CompilerConfigurationBlock.pb_duplicate_resources.label=Duplica&ted resources:
+CompilerConfigurationBlock.pb_max_per_unit.label=&Maximum number of problems reported per compilation unit:
+CompilerConfigurationBlock.pb_check_prereq_binary_level.label=Incompatible required &binaries:
+
+CompilerConfigurationBlock.pb_accidential_assignement.label=Possi&ble accidental boolean assignment (e.g. if (a = b)):
+CompilerConfigurationBlock.pb_local_variable_hiding.label=&Local variable declaration hides another field or variable:
+CompilerConfigurationBlock.pb_field_hiding.label=&Field declaration hides another field or variable:
+CompilerConfigurationBlock.pb_special_param_hiding.label=Include const&ructor or setter method parameters
+
+CompilerConfigurationBlock.pb_unqualified_field_access.label=Unqualified access to instance fi&eld:
+CompilerConfigurationBlock.pb_finally_block_not_completing.label='&finally' does not complete normally:
+CompilerConfigurationBlock.pb_undocumented_empty_block.label=U&ndocumented empty block:
+CompilerConfigurationBlock.pb_unused_throwing_exception.label=Unnecessary declaration of t&hrown checked exception:
+CompilerConfigurationBlock.pb_unused_throwing_exception_when_overriding.label=Check &overriding and implementing methods
+
+CompilerConfigurationBlock.javadoc.description=Select the severity level for the following problems:
+CompilerConfigurationBlock.pb_invalid_javadoc.label=Mal&formed PHPdoc comments:
+CompilerConfigurationBlock.pb_invalid_javadoc_tags.label=Report e&rrors in tags
+CompilerConfigurationBlock.pb_invalid_javadoc_tags_visibility.label=On&ly consider members as visible as:
+
+CompilerConfigurationBlock.pb_missing_javadoc.label=Missing PHPdoc &tags:
+CompilerConfigurationBlock.pb_missing_javadoc_tags_visibility.label=O&nly consider members as visible as:
+CompilerConfigurationBlock.pb_missing_javadoc_tags_overriding.label=C&heck overriding and implementing methods
+
+CompilerConfigurationBlock.pb_missing_comments.label=&Missing PHPdoc comments:
+CompilerConfigurationBlock.pb_missing_comments_visibility.label=&Only consider members as visible as:
+CompilerConfigurationBlock.pb_missing_comments_overriding.label=Ch&eck overriding and implementing methods
+
+CompilerConfigurationBlock.resource_filter.description=Enter resources and resource types that should not be copied to the output folder during a build. List is comma separated (e.g. '*.doc, plugin.xml, scripts/')
+CompilerConfigurationBlock.resource_filter.label=&Filtered Resources:
+CompilerConfigurationBlock.build_invalid_classpath.label=Abo&rt building on build path errors
+CompilerConfigurationBlock.build_clean_outputfolder.label=Clea&n output folders on full build
+CompilerConfigurationBlock.enable_exclusion_patterns.label=Enable using e&xclusion patterns in source folders
+CompilerConfigurationBlock.enable_multiple_outputlocations.label=Enable using &multiple output locations for source folders
+
+CompilerConfigurationBlock.error=Error
+CompilerConfigurationBlock.warning=Warning
+CompilerConfigurationBlock.ignore=Ignore
+
+CompilerConfigurationBlock.public=Public
+CompilerConfigurationBlock.protected=Protected
+CompilerConfigurationBlock.default=Default
+CompilerConfigurationBlock.private=Private
+
+CompilerConfigurationBlock.enabled=Enabled
+CompilerConfigurationBlock.disabled=Disabled
+
+CompilerConfigurationBlock.version11=1.1
+CompilerConfigurationBlock.version12=1.2
+CompilerConfigurationBlock.version13=1.3
+CompilerConfigurationBlock.version14=1.4
+
+CompilerConfigurationBlock.needsbuild.title=Compiler Settings Changed
+CompilerConfigurationBlock.needsfullbuild.message=The compiler settings have changed. A full rebuild is required to make changes effective. Do the full build now?
+CompilerConfigurationBlock.needsprojectbuild.message=The compiler settings have changed. A rebuild of the project is required to make changes effective. Do the project build now?
+
+CompilerConfigurationBlock.cpl13src14.error=In 1.3 compliance level, source compatibility can not be 1.4
+CompilerConfigurationBlock.cpl13trg14.error=In 1.3 compliance level, the classfile compatibility can not be 1.4
+CompilerConfigurationBlock.src14asrterr.error=When source compatibility is 1.4, 'assert' cannot be an identifier.
+CompilerConfigurationBlock.src14tgt14.error=When source compatibility is 1.4, the classfile compatibility has to be 1.4.
+
+CompilerConfigurationBlock.empty_input=Number of problems can not be empty.
+CompilerConfigurationBlock.invalid_input={0} is not a valid number of problems.
+
+CompilerConfigurationBlock.filter.invalidsegment.error=Filter is invalid: {0}
+
+OptionsConfigurationBlock.builderror.title=Preference Changes
+OptionsConfigurationBlock.builderror.message=Problem while building. Check log for details.
+
+OptionsConfigurationBlock.job.title=Rebuilding
+
+OptionsConfigurationBlock.buildall.taskname=Build all...
+OptionsConfigurationBlock.buildproject.taskname=Build project ''{0}''...
+
+CodeGenerationPreferencePage.title=&Code Generation
+CodeGenerationPreferencePage.description=Options for Code Generation:
+
+CodeGenerationPreferencePage.tab.names.tabtitle=&Names
+CodeGenerationPreferencePage.tab.templates.tabtitle=&Code and Comments
+
+NameConventionConfigurationBlock.field.label=Fields
+NameConventionConfigurationBlock.static.label=Static Fields
+NameConventionConfigurationBlock.arg.label=Parameters
+NameConventionConfigurationBlock.local.label=Local Variables
+NameConventionConfigurationBlock.keywordthis.label=&Qualify all generated field accesses with 'this.'
+NameConventionConfigurationBlock.isforbooleangetters.label=&Use 'is' prefix for getters that return boolean.
+
+NameConventionConfigurationBlock.dialog.prefix=P&refix list:
+NameConventionConfigurationBlock.dialog.suffix=S&uffix list:
+
+NameConventionConfigurationBlock.exceptionname.label=E&xception variable name in catch blocks:
+
+NameConventionConfigurationBlock.error.emptyprefix=Prefix strings can not contain an empty entry.
+NameConventionConfigurationBlock.error.emptysuffix=Suffix strings can not contain an empty entry.
+NameConventionConfigurationBlock.error.invalidprefix={0} is not a valid prefix.
+NameConventionConfigurationBlock.error.invalidsuffix={0} is not a valid suffix.
+
+NameConventionConfigurationBlock.list.label=C&onventions for variable names:
+NameConventionConfigurationBlock.list.edit.button=&Edit...
+NameConventionConfigurationBlock.list.name.column=Variable type
+NameConventionConfigurationBlock.list.prefix.column=Prefix list
+NameConventionConfigurationBlock.list.suffix.column=Suffix list
+
+NameConventionConfigurationBlock.field.dialog.title=Field Name Conventions
+NameConventionConfigurationBlock.field.dialog.message=Specify prefix and suffix to be used for fields  (comma separated):
+
+NameConventionConfigurationBlock.static.dialog.title=Static Field Name Conventions
+NameConventionConfigurationBlock.static.dialog.message=Specify prefix and suffix to be used for static fields (comma separated):
+
+NameConventionConfigurationBlock.arg.dialog.title=Parameter Name Conventions
+NameConventionConfigurationBlock.arg.dialog.message=Specify prefix and suffix to be used for parameters (comma separated):
+
+NameConventionConfigurationBlock.local.dialog.title=Local Variable Name Conventions
+NameConventionConfigurationBlock.local.dialog.message=Specify prefix and suffix to be used for local variables (comma separated):
+
+MembersOrderPreferencePage.category.button.up=&Up
+MembersOrderPreferencePage.category.button.down=D&own
+
+MembersOrderPreferencePage.visibility.button.up=U&p
+MembersOrderPreferencePage.visibility.button.down=Do&wn
+
+MembersOrderPreferencePage.label.description=&Choose the order in which members will be displayed. The order is also used by the 'Sort Members' action.
+
+
+MembersOrderPreferencePage.fields.label=Fields
+MembersOrderPreferencePage.constructors.label=Constructors
+MembersOrderPreferencePage.methods.label=Methods
+MembersOrderPreferencePage.staticfields.label=Static Fields
+MembersOrderPreferencePage.staticmethods.label=Static Methods
+MembersOrderPreferencePage.initialisers.label=Initializers
+MembersOrderPreferencePage.staticinitialisers.label=Static Initializers
+MembersOrderPreferencePage.types.label=Types
+
+MembersOrderPreferencePage.public.label=Public
+MembersOrderPreferencePage.private.label=Private
+MembersOrderPreferencePage.protected.label=Protected
+MembersOrderPreferencePage.default.label=Default
+
+MembersOrderPreferencePage.usevisibilitysort.label=&Sort members in same category by visibility
+
+CodeTemplateBlock.templates.comment.node=Comments
+CodeTemplateBlock.templates.code.node=Code
+
+CodeTemplateBlock.catchblock.label=Catch block body
+CodeTemplateBlock.methodstub.label=Method body
+CodeTemplateBlock.constructorstub.label=Constructor body
+CodeTemplateBlock.newtype.label=New PHP files
+CodeTemplateBlock.typecomment.label=Types
+CodeTemplateBlock.fieldcomment.label=Fields
+CodeTemplateBlock.methodcomment.label=Methods
+CodeTemplateBlock.overridecomment.label=Overriding methods
+CodeTemplateBlock.constructorcomment.label=Constructors
+CodeTemplateBlock.gettercomment.label=Getters
+CodeTemplateBlock.settercomment.label=Setters
+CodeTemplateBlock.getterstub.label=Getter body
+CodeTemplateBlock.setterstub.label=Setter body
+
+CodeTemplateBlock.templates.edit.button=&Edit...
+CodeTemplateBlock.templates.import.button=&Import...
+CodeTemplateBlock.templates.export.button=E&xport...
+CodeTemplateBlock.templates.exportall.button=Ex&port All...
+
+CodeTemplateBlock.createcomment.label=A&utomatically add comments for new methods and types
+CodeTemplateBlock.createcomment.description=(does not apply to comments contained in the code patterns)
+CodeTemplateBlock.templates.label=C&onfigure generated code and comments:
+CodeTemplateBlock.preview=Pa&ttern:
+
+CodeTemplateBlock.import.title=Importing Templates
+CodeTemplateBlock.import.extension=*.xml
+
+CodeTemplateBlock.export.title=Exporting {0} Code Template(s)
+CodeTemplateBlock.export.filename=codetemplates.xml
+CodeTemplateBlock.export.extension=*.xml
+
+CodeTemplateBlock.export.exists.title=Exporting Code Templates
+CodeTemplateBlock.export.exists.message={0} already exists.\nDo you want to replace it?
+
+CodeTemplateBlock.error.read.title= Code Templates
+CodeTemplateBlock.error.read.message= Failed to read templates.
+
+CodeTemplateBlock.error.parse.message= Failed to parse templates:\n{0}
+
+CodeTemplateBlock.error.write.title=Code Templates
+CodeTemplateBlock.error.write.message=Failed to write templates.
+
+CodeTemplateBlock.export.error.title= Exporting Templates
+CodeTemplateBlock.export.error.hidden= Export failed.\n{0} is a hidden file.
+CodeTemplateBlock.export.error.canNotWrite= Export failed.\n{0} can not be modified.
+CodeTemplateBlock.export.error.fileNotFound= Export failed:\n{0}
+
+TypeFilterPreferencePage.description=All types in packages that match with the selected filter strings will not be shown in the 'Open Type' dialog and will also be ignored in code assist or quick fix proposals.
+TypeFilterPreferencePage.list.label=Filter list:
+TypeFilterPreferencePage.add.button=&New...
+TypeFilterPreferencePage.addpackage.button=Add &Packages...
+TypeFilterPreferencePage.edit.button=&Edit...
+TypeFilterPreferencePage.remove.button=&Remove
+TypeFilterPreferencePage.selectall.button=Ena&ble All
+TypeFilterPreferencePage.deselectall.button=Di&sable All
+
+TypeFilterPreferencePage.choosepackage.label=Package Selection
+TypeFilterPreferencePage.choosepackage.description=&Choose packages to filter:
+
+TypeFilterInputDialog.title=Type Filter
+TypeFilterInputDialog.message=&Type filter name ('*' and '?' are valid wildcards):
+TypeFilterInputDialog.browse.button=&Browse...
+TypeFilterInputDialog.error.enterName=Enter a qualified type name.
+TypeFilterInputDialog.error.invalidName=Invalid name: {0}.
+TypeFilterInputDialog.error.entryExists=Entry already exists.
+TypeFilterInputDialog.choosepackage.label=Package Selection
+TypeFilterInputDialog.choosepackage.description=&Choose packages to filter:
+
+WorkInProgress.quickdiff= Quick Diff
+WorkInProgress.quickdiff.changedLineColor= Changed lines background
+WorkInProgress.quickdiff.addedLineColor= Added lines background
+WorkInProgress.quickdiff.deletedLineColor= Deleted lines indicator
+WorkInProgress.quickdiff.appearanceOptions= Appearance color options:
+WorkInProgress.editor=Editor
+WorkInProgress.formatComments= Enable formatting of PHPdoc, multi- and single line comments (reopen editor for activation)
+WorkInProgress.smartTyping.label= Enable the following functions in Smart Insert typing mode
+WorkInProgress.smartTyping.smartSemicolon= Smart &Semicolon
+WorkInProgress.smartTyping.smartOpeningBrace= Smart Opening &Brace
+WorkInProgress.smartTyping.smartTab= Smart &Tab
+WorkInProgress.formatter= Code Fomatter
+WorkInProgress.formatter.option= Enable new code fomatter (press 'Apply' before going to the formatter preference page)
+WorkInProgress.quickassist.group= Quick Assist
+WorkInProgress.quickassist.option= Enable light bulb for quick assists
+WorkInProgress.showQuickDiffPerDefault=Always show &Quick Diff coloring
+WorkInProgress.quickdiff.referenceprovidertitle=Quick Diff reference providers:
+WorkInProgress.quickdiff.setDefault=Make &Default
+WorkInProgress.quickdiff.defaultlabel= (default)
+WorkInProgress.quickdiff.characterMode= Show changes using &characters instead of colors (on line number bar only)
+WorkInProgress.search= Search
+WorkInProgress.search.small_menu=Use reduced search menu
+WorkInProgress.newsearch.option=Use new search view
+WorkInProgress.search.ignore_imports=Ignore references in imports statements
+WorkInProgress.rollover= Enable annotation &roll-over (does not affect already open editors)
+
+JavadocPreferencePage.title=PHPdoc
+
+SpellingPreferencePage.description=Options for Spelling:
+SpellingPreferencePage.title=Spelling
+SpellingPreferencePage.empty_threshold=No number of correction proposals specified
+SpellingPreferencePage.invalid_threshold=''{0}'' is not a valid number for correction proposals
+SpellingPreferencePage.enable.label=Sp&ell-check comments
+SpellingPreferencePage.ignore.digits.label=Ignore words with &digits
+SpellingPreferencePage.ignore.mixed.label=Ignore &mixed case words
+SpellingPreferencePage.ignore.sentence.label=Ignore &sentence capitalization
+SpellingPreferencePage.ignore.upper.label=Ignore u&pper case words
+SpellingPreferencePage.ignore.url.label=Ignore &internet addresses
+SpellingPreferencePage.proposals.threshold=&Number of correction proposals:
+SpellingPreferencePage.dictionary.label=&Platform dictionary:
+SpellingPreferencePage.workspace.dictionary.label=&User defined dictionary:
+SpellingPreferencePage.browse.label=&Browse...
+SpellingPreferencePage.dictionary.error=The dictionary must be a readable and writable file
+SpellingPreferencePage.locale.error=There exists no dictionary for this language
+SpellingPreferencePage.filedialog.title=Select dictionary
+SpellingPreferencePage.filter.dictionary.extension=*.dictionary
+SpellingPreferencePage.filter.all.extension=*.*
+SpellingPreferencePage.filter.dictionary.label=Dictionary Files
+SpellingPreferencePage.filter.all.label=All Files
+SpellingPreferencePage.enable.contentassist.label=&Make dictionary available to content assist
+
+SpellingPreferencePage.preferences.user=&Comments
+SpellingPreferencePage.preferences.engine=&Language
+SpellingPreferencePage.preferences.advanced=&Advanced
+
+EditorPreferencePage.description=General Editor Preferences:
+EditorPreferencePage.title=Editor
+EditorPreferencePage.file.title=File Saving
+EditorPreferencePage.save_on_blur=&Save files when focus is lost
+EditorPreferencePage.p_rtrim_on_save=&Remove trailing spaces on save
+
+
+JavaEditorPreferencePage.AnnotationDecoration.NONE=None
+JavaEditorPreferencePage.AnnotationDecoration.SQUIGGLIES=Squiggles
+JavaEditorPreferencePage.AnnotationDecoration.UNDERLINE=Underline
+JavaEditorPreferencePage.AnnotationDecoration.BOX=Box
+JavaEditorPreferencePage.AnnotationDecoration.IBEAM=IBeam
+
+# edit template dialog
+EditTemplateDialog.error.noname=Template name cannot be empty.
+EditTemplateDialog.title.new=New Template
+EditTemplateDialog.title.edit=Edit Template
+
+EditTemplateDialog.name=&Name:
+EditTemplateDialog.description=&Description:
+EditTemplateDialog.context=&Context:
+EditTemplateDialog.pattern=&Pattern:
+EditTemplateDialog.insert.variable=Insert &Variable...
+
+EditTemplateDialog.undo=&Undo
+EditTemplateDialog.cut=Cu&t
+EditTemplateDialog.copy=&Copy
+EditTemplateDialog.paste=&Paste
+EditTemplateDialog.select.all=Select &All
+EditTemplateDialog.content.assist=Insert &Variable...
+
+JavaEditorPreferencePage.folding.title= &Folding
+
+FoldingConfigurationBlock.enable= Enable folding when &opening a new editor
+FoldingConfigurationBlock.combo_caption= Select folding to &use:
+FoldingConfigurationBlock.info.no_preferences= The selected folding provider did not provide a preference control
+FoldingConfigurationBlock.error.not_exist= The selected folding provider does not exist
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/SpellingConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/SpellingConfigurationBlock.java
new file mode 100644 (file)
index 0000000..f676e4f
--- /dev/null
@@ -0,0 +1,509 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.text.spelling.SpellCheckEngine;
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.preference.IPreferenceStore;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Options configuration block for spell-check related settings.
+ * 
+ * @since 3.0
+ */
+public class SpellingConfigurationBlock extends OptionsConfigurationBlock {
+
+       /** Preference keys for the preferences in this block */
+       private static final String PREF_SPELLING_CHECK_SPELLING = PreferenceConstants.SPELLING_CHECK_SPELLING;
+
+       private static final String PREF_SPELLING_IGNORE_DIGITS = PreferenceConstants.SPELLING_IGNORE_DIGITS;
+
+       private static final String PREF_SPELLING_IGNORE_MIXED = PreferenceConstants.SPELLING_IGNORE_MIXED;
+
+       private static final String PREF_SPELLING_IGNORE_SENTENCE = PreferenceConstants.SPELLING_IGNORE_SENTENCE;
+
+       private static final String PREF_SPELLING_IGNORE_UPPER = PreferenceConstants.SPELLING_IGNORE_UPPER;
+
+       private static final String PREF_SPELLING_IGNORE_URLS = PreferenceConstants.SPELLING_IGNORE_URLS;
+
+       private static final String PREF_SPELLING_LOCALE = PreferenceConstants.SPELLING_LOCALE;
+
+       private static final String PREF_SPELLING_PROPOSAL_THRESHOLD = PreferenceConstants.SPELLING_PROPOSAL_THRESHOLD;
+
+       private static final String PREF_SPELLING_USER_DICTIONARY = PreferenceConstants.SPELLING_USER_DICTIONARY;
+
+       private static final String PREF_SPELLING_ENABLE_CONTENTASSIST = PreferenceConstants.SPELLING_ENABLE_CONTENTASSIST;
+
+       /**
+        * Creates a selection dependency between a master and a slave control.
+        * 
+        * @param master
+        *            The master button that controls the state of the slave
+        * @param slave
+        *            The slave control that is enabled only if the master is
+        *            selected
+        */
+       protected static void createSelectionDependency(final Button master,
+                       final Control slave) {
+
+               master.addSelectionListener(new SelectionListener() {
+
+                       public void widgetDefaultSelected(SelectionEvent event) {
+                               // Do nothing
+                       }
+
+                       public void widgetSelected(SelectionEvent event) {
+                               slave.setEnabled(master.getSelection());
+                       }
+               });
+               slave.setEnabled(master.getSelection());
+       }
+
+       /**
+        * Returns the locale codes for the locale list.
+        * 
+        * @param locales
+        *            The list of locales
+        * @return Array of locale codes for the list
+        */
+       protected static String[] getDictionaryCodes(final Set locales) {
+
+               int index = 0;
+               Locale locale = null;
+
+               final String[] codes = new String[locales.size()];
+               for (final Iterator iterator = locales.iterator(); iterator.hasNext();) {
+
+                       locale = (Locale) iterator.next();
+                       codes[index++] = locale.toString();
+               }
+               return codes;
+       }
+
+       /**
+        * Returns the display labels for the locale list.
+        * 
+        * @param locales
+        *            The list of locales
+        * @return Array of display labels for the list
+        */
+       protected static String[] getDictionaryLabels(final Set locales) {
+
+               int index = 0;
+               Locale locale = null;
+
+               final String[] labels = new String[locales.size()];
+               for (final Iterator iterator = locales.iterator(); iterator.hasNext();) {
+
+                       locale = (Locale) iterator.next();
+                       labels[index++] = locale.getDisplayName(SpellCheckEngine
+                                       .getDefaultLocale());
+               }
+               return labels;
+       }
+
+       /**
+        * Validates that the file with the specified absolute path exists and can
+        * be opened.
+        * 
+        * @param path
+        *            The path of the file to validate
+        * @return <code>true</code> iff the file exists and can be opened,
+        *         <code>false</code> otherwise
+        */
+       protected static IStatus validateAbsoluteFilePath(final String path) {
+
+               final StatusInfo status = new StatusInfo();
+               if (path.length() > 0) {
+
+                       final File file = new File(path);
+                       if (!file.isFile() || !file.isAbsolute() || !file.exists()
+                                       || !file.canRead() || !file.canWrite())
+                               status.setError(PreferencesMessages
+                                               .getString("SpellingPreferencePage.dictionary.error")); //$NON-NLS-1$
+
+               }
+               return status;
+       }
+
+       /**
+        * Validates that the specified locale is available.
+        * 
+        * @param locale
+        *            The locale to validate
+        * @return The status of the validation
+        */
+       protected static IStatus validateLocale(final String locale) {
+
+               final StatusInfo status = new StatusInfo(IStatus.ERROR,
+                               PreferencesMessages
+                                               .getString("SpellingPreferencePage.locale.error")); //$NON-NLS-1$
+               final Set locales = SpellCheckEngine.getAvailableLocales();
+
+               Locale current = null;
+               for (final Iterator iterator = locales.iterator(); iterator.hasNext();) {
+
+                       current = (Locale) iterator.next();
+                       if (current.toString().equals(locale))
+                               return new StatusInfo();
+               }
+               return status;
+       }
+
+       /**
+        * Validates that the specified number is positive.
+        * 
+        * @param number
+        *            The number to validate
+        * @return The status of the validation
+        */
+       protected static IStatus validatePositiveNumber(final String number) {
+
+               final StatusInfo status = new StatusInfo();
+               if (number.length() == 0) {
+                       status.setError(PreferencesMessages
+                                       .getString("SpellingPreferencePage.empty_threshold")); //$NON-NLS-1$
+               } else {
+                       try {
+                               final int value = Integer.parseInt(number);
+                               if (value < 0) {
+                                       status
+                                                       .setError(PreferencesMessages
+                                                                       .getFormattedString(
+                                                                                       "SpellingPreferencePage.invalid_threshold", number)); //$NON-NLS-1$
+                               }
+                       } catch (NumberFormatException exception) {
+                               status.setError(PreferencesMessages.getFormattedString(
+                                               "SpellingPreferencePage.invalid_threshold", number)); //$NON-NLS-1$
+                       }
+               }
+               return status;
+       }
+
+       /** The dictionary path field */
+       private Text fDictionaryPath = null;
+
+       /** The status for the workspace dictionary file */
+       private IStatus fFileStatus = new StatusInfo();
+
+       /** The status for the platform locale */
+       private IStatus fLocaleStatus = new StatusInfo();
+
+       /** The status for the proposal threshold */
+       private IStatus fThresholdStatus = new StatusInfo();
+
+       /**
+        * Creates a new spelling configuration block.
+        * 
+        * @param context
+        *            The status change listener
+        * @param project
+        *            The Java project
+        */
+       public SpellingConfigurationBlock(final IStatusChangeListener context,
+                       final IJavaProject project) {
+               super(context, project, getAllKeys());
+
+               IStatus status = validateAbsoluteFilePath((String) fWorkingValues
+                               .get(PREF_SPELLING_USER_DICTIONARY));
+               if (status.getSeverity() != IStatus.OK)
+                       fWorkingValues.put(PREF_SPELLING_USER_DICTIONARY, ""); //$NON-NLS-1$
+
+               status = validateLocale((String) fWorkingValues
+                               .get(PREF_SPELLING_LOCALE));
+               if (status.getSeverity() != IStatus.OK)
+                       fWorkingValues.put(PREF_SPELLING_LOCALE, SpellCheckEngine
+                                       .getDefaultLocale().toString());
+       }
+
+       protected Combo addComboBox(Composite parent, String label, String key,
+                       String[] values, String[] valueLabels, int indent) {
+               ControlData data = new ControlData(key, values);
+
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indent;
+
+               Label labelControl = new Label(parent, SWT.LEFT | SWT.WRAP);
+               labelControl.setText(label);
+               labelControl.setLayoutData(gd);
+
+               Combo comboBox = new Combo(parent, SWT.READ_ONLY);
+               comboBox.setItems(valueLabels);
+               comboBox.setData(data);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = 2;
+               comboBox.setLayoutData(gd);
+               comboBox.addSelectionListener(getSelectionListener());
+
+               fLabels.put(comboBox, labelControl);
+
+               String currValue = (String) fWorkingValues.get(key);
+               comboBox.select(data.getSelection(currValue));
+
+               fComboBoxes.add(comboBox);
+               return comboBox;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite)
+        */
+       protected Control createContents(final Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               composite.setLayout(layout);
+
+               final PixelConverter converter = new PixelConverter(parent);
+
+               layout = new GridLayout();
+               layout.numColumns = 3;
+
+               final String[] trueFalse = new String[] { IPreferenceStore.TRUE,
+                               IPreferenceStore.FALSE };
+
+               Group user = new Group(composite, SWT.NONE);
+               user.setText(PreferencesMessages
+                               .getString("SpellingPreferencePage.preferences.user")); //$NON-NLS-1$
+               user.setLayout(new GridLayout());
+               user.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               String label = PreferencesMessages
+                               .getString("SpellingPreferencePage.enable.label"); //$NON-NLS-1$
+               final Button master = addCheckBox(user, label,
+                               PREF_SPELLING_CHECK_SPELLING, trueFalse, 0);
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.ignore.digits.label"); //$NON-NLS-1$
+               Control slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_DIGITS,
+                               trueFalse, 20);
+               createSelectionDependency(master, slave);
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.ignore.mixed.label"); //$NON-NLS-1$
+               slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_MIXED, trueFalse,
+                               20);
+               createSelectionDependency(master, slave);
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.ignore.sentence.label"); //$NON-NLS-1$
+               slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_SENTENCE,
+                               trueFalse, 20);
+               createSelectionDependency(master, slave);
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.ignore.upper.label"); //$NON-NLS-1$
+               slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_UPPER, trueFalse,
+                               20);
+               createSelectionDependency(master, slave);
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.ignore.url.label"); //$NON-NLS-1$
+               slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_URLS, trueFalse,
+                               20);
+               createSelectionDependency(master, slave);
+
+               final Group engine = new Group(composite, SWT.NONE);
+               engine.setText(PreferencesMessages
+                               .getString("SpellingPreferencePage.preferences.engine")); //$NON-NLS-1$
+               layout = new GridLayout();
+               layout.numColumns = 4;
+               engine.setLayout(layout);
+               engine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.dictionary.label"); //$NON-NLS-1$
+               final Set locales = SpellCheckEngine.getAvailableLocales();
+
+               Combo combo = addComboBox(engine, label, PREF_SPELLING_LOCALE,
+                               getDictionaryCodes(locales), getDictionaryLabels(locales), 0);
+               combo.setEnabled(locales.size() > 1);
+
+               new Label(engine, SWT.NONE); // placeholder
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.workspace.dictionary.label"); //$NON-NLS-1$
+               fDictionaryPath = addTextField(engine, label,
+                               PREF_SPELLING_USER_DICTIONARY, 0, 0);
+
+               Button button = new Button(engine, SWT.PUSH);
+               button.setText(PreferencesMessages
+                               .getString("SpellingPreferencePage.browse.label")); //$NON-NLS-1$
+               button.addSelectionListener(new SelectionAdapter() {
+
+                       public void widgetSelected(final SelectionEvent event) {
+                               handleBrowseButtonSelected();
+                       }
+               });
+               button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+               SWTUtil.setButtonDimensionHint(button);
+
+               layout = new GridLayout();
+               layout.numColumns = 3;
+
+               Group advanced = new Group(composite, SWT.NONE);
+               advanced.setText(PreferencesMessages
+                               .getString("SpellingPreferencePage.preferences.advanced")); //$NON-NLS-1$
+               layout = new GridLayout();
+               layout.numColumns = 3;
+               advanced.setLayout(layout);
+               advanced.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.proposals.threshold"); //$NON-NLS-1$
+               Text text = addTextField(advanced, label,
+                               PREF_SPELLING_PROPOSAL_THRESHOLD, 0, 0);
+               text.setTextLimit(3);
+               GridData data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               data.widthHint = converter.convertWidthInCharsToPixels(4);
+               text.setLayoutData(data);
+
+               label = PreferencesMessages
+                               .getString("SpellingPreferencePage.enable.contentassist.label"); //$NON-NLS-1$
+               addCheckBox(advanced, label, PREF_SPELLING_ENABLE_CONTENTASSIST,
+                               trueFalse, 0);
+
+               return composite;
+       }
+
+       private static String[] getAllKeys() {
+               return new String[] { PREF_SPELLING_USER_DICTIONARY,
+                               PREF_SPELLING_CHECK_SPELLING, PREF_SPELLING_IGNORE_DIGITS,
+                               PREF_SPELLING_IGNORE_MIXED, PREF_SPELLING_IGNORE_SENTENCE,
+                               PREF_SPELLING_IGNORE_UPPER, PREF_SPELLING_IGNORE_URLS,
+                               PREF_SPELLING_LOCALE, PREF_SPELLING_PROPOSAL_THRESHOLD,
+                               PREF_SPELLING_ENABLE_CONTENTASSIST };
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getDefaultOptions()
+        */
+       protected Map getDefaultOptions() {
+
+               final String[] keys = fAllKeys;
+               final Map options = new HashMap();
+               final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+
+               for (int index = 0; index < keys.length; index++)
+                       options.put(keys[index], store.getDefaultString(keys[index]));
+
+               return options;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean)
+        */
+       protected final String[] getFullBuildDialogStrings(final boolean workspace) {
+               return null;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getOptions(boolean)
+        */
+       protected Map getOptions(final boolean inherit) {
+
+               final String[] keys = fAllKeys;
+               final Map options = new HashMap();
+               final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+
+               for (int index = 0; index < keys.length; index++)
+                       options.put(keys[index], store.getString(keys[index]));
+
+               return options;
+       }
+
+       /**
+        * Handles selections of the browse button.
+        */
+       protected void handleBrowseButtonSelected() {
+
+               final FileDialog dialog = new FileDialog(fDictionaryPath.getShell(),
+                               SWT.OPEN);
+               dialog.setText(PreferencesMessages
+                               .getString("SpellingPreferencePage.filedialog.title")); //$NON-NLS-1$
+               dialog
+                               .setFilterExtensions(new String[] {
+                                               PreferencesMessages
+                                                               .getString("SpellingPreferencePage.filter.dictionary.extension"), PreferencesMessages.getString("SpellingPreferencePage.filter.all.extension") }); //$NON-NLS-1$ //$NON-NLS-2$
+               dialog
+                               .setFilterNames(new String[] {
+                                               PreferencesMessages
+                                                               .getString("SpellingPreferencePage.filter.dictionary.label"), PreferencesMessages.getString("SpellingPreferencePage.filter.all.label") }); //$NON-NLS-1$ //$NON-NLS-2$
+
+               final String path = dialog.open();
+               if (path != null)
+                       fDictionaryPath.setText(path);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#setOptions(java.util.Map)
+        */
+       protected void setOptions(final Map options) {
+
+               final String[] keys = fAllKeys;
+               final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+
+               for (int index = 0; index < keys.length; index++)
+                       store.setValue(keys[index], (String) fWorkingValues
+                                       .get(keys[index]));
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(java.lang.String,java.lang.String)
+        */
+       protected void validateSettings(final String key, final String value) {
+
+               if (key == null || PREF_SPELLING_PROPOSAL_THRESHOLD.equals(key))
+                       fThresholdStatus = validatePositiveNumber((String) fWorkingValues
+                                       .get(PREF_SPELLING_PROPOSAL_THRESHOLD));
+
+               if (key == null || PREF_SPELLING_USER_DICTIONARY.equals(key))
+                       fFileStatus = validateAbsoluteFilePath((String) fWorkingValues
+                                       .get(PREF_SPELLING_USER_DICTIONARY));
+
+               if (key == null || PREF_SPELLING_LOCALE.equals(key))
+                       fLocaleStatus = validateLocale((String) fWorkingValues
+                                       .get(PREF_SPELLING_LOCALE));
+
+               fContext.statusChanged(StatusUtil.getMostSevere(new IStatus[] {
+                               fThresholdStatus, fFileStatus, fLocaleStatus }));
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/SpellingPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/SpellingPreferencePage.java
new file mode 100644 (file)
index 0000000..8f7010b
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Preference page for spell checking preferences.
+ * 
+ * @since 3.0
+ */
+public class SpellingPreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage, IStatusChangeListener {
+
+       /** The spelling configuration block */
+       private final SpellingConfigurationBlock fBlock = new SpellingConfigurationBlock(
+                       this, null);
+
+       /**
+        * Creates a new spelling preference page.
+        */
+       public SpellingPreferencePage() {
+
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+               setDescription(PreferencesMessages
+                               .getString("SpellingPreferencePage.description")); //$NON-NLS-1$
+               setTitle(PreferencesMessages.getString("SpellingPreferencePage.title")); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+        */
+       protected Control createContents(final Composite parent) {
+
+               final Control control = fBlock.createContents(parent);
+               Dialog.applyDialogFont(control);
+
+               return control;
+       }
+
+       /*
+        * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+        */
+       public void createControl(final Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.JAVA_EDITOR_PREFERENCE_PAGE);
+       }
+
+       /*
+        * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+        */
+       public void init(final IWorkbench workbench) {
+               // Do nothing
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               fBlock.performDefaults();
+
+               super.performDefaults();
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+
+               if (!fBlock.performOk(true))
+                       return false;
+
+               return super.performOk();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener#statusChanged(org.eclipse.core.runtime.IStatus)
+        */
+       public void statusChanged(final IStatus status) {
+               setValid(!status.matches(IStatus.ERROR));
+
+               StatusUtil.applyToStatusLine(this, status);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TemplateEditorSourceViewerConfiguration.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TemplateEditorSourceViewerConfiguration.java
new file mode 100644 (file)
index 0000000..439288a
--- /dev/null
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder;
+import net.sourceforge.phpdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class TemplateEditorSourceViewerConfiguration extends
+               PHPSourceViewerConfiguration {
+
+       private static class TemplateVariableTextHover implements ITextHover {
+
+               private TemplateVariableProcessor fProcessor;
+
+               /**
+                * @param type
+                */
+               public TemplateVariableTextHover(TemplateVariableProcessor processor) {
+                       fProcessor = processor;
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer,
+                *      org.eclipse.jface.text.IRegion)
+                */
+               public String getHoverInfo(ITextViewer textViewer, IRegion subject) {
+                       try {
+                               IDocument doc = textViewer.getDocument();
+                               int offset = subject.getOffset();
+                               if (offset >= 2 && "${".equals(doc.get(offset - 2, 2))) { //$NON-NLS-1$
+                                       String varName = doc.get(offset, subject.getLength());
+                                       TemplateContextType contextType = fProcessor
+                                                       .getContextType();
+                                       if (contextType != null) {
+                                               Iterator iter = contextType.resolvers();
+                                               while (iter.hasNext()) {
+                                                       TemplateVariableResolver var = (TemplateVariableResolver) iter
+                                                                       .next();
+                                                       if (varName.equals(var.getType())) {
+                                                               return var.getDescription();
+                                                       }
+                                               }
+                                       }
+                               }
+                       } catch (BadLocationException e) {
+                       }
+                       return null;
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer,
+                *      int)
+                */
+               public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+                       if (textViewer != null) {
+                               return JavaWordFinder
+                                               .findWord(textViewer.getDocument(), offset);
+                       }
+                       return null;
+               }
+
+       }
+
+       private final TemplateVariableProcessor fProcessor;
+
+       public TemplateEditorSourceViewerConfiguration(IColorManager colorManager,
+                       IPreferenceStore store, ITextEditor editor,
+                       TemplateVariableProcessor processor) {
+               super(colorManager, store, editor, IPHPPartitions.PHP_PARTITIONING);
+               fProcessor = processor;
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getContentAssistant(ISourceViewer)
+        */
+       public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               JavaTextTools textTools = WebUI.getDefault()
+                               .getJavaTextTools();
+               IColorManager manager = textTools.getColorManager();
+
+               ContentAssistant assistant = new ContentAssistant();
+               assistant.setContentAssistProcessor(fProcessor,
+                               IDocument.DEFAULT_CONTENT_TYPE);
+               // Register the same processor for strings and single line comments to
+               // get code completion at the start of those partitions.
+               assistant.setContentAssistProcessor(fProcessor,
+                               IPHPPartitions.PHP_STRING_DQ);
+               assistant.setContentAssistProcessor(fProcessor,
+                               IPHPPartitions.PHP_STRING_SQ);
+               assistant.setContentAssistProcessor(fProcessor,
+                               IPHPPartitions.PHP_STRING_HEREDOC);
+               assistant.setContentAssistProcessor(fProcessor,
+                               IPHPPartitions.PHP_SINGLELINE_COMMENT);
+               assistant.setContentAssistProcessor(fProcessor,
+                               IPHPPartitions.PHP_MULTILINE_COMMENT);
+               assistant.setContentAssistProcessor(fProcessor,
+                               IPHPPartitions.PHP_PHPDOC_COMMENT);
+
+               assistant.enableAutoInsert(store
+                               .getBoolean(PreferenceConstants.CODEASSIST_AUTOINSERT));
+               assistant.enableAutoActivation(store
+                               .getBoolean(PreferenceConstants.CODEASSIST_AUTOACTIVATION));
+               assistant.setAutoActivationDelay(store
+                               .getInt(PreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY));
+               assistant
+                               .setProposalPopupOrientation(ContentAssistant.PROPOSAL_OVERLAY);
+               assistant
+                               .setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_ABOVE);
+               assistant
+                               .setInformationControlCreator(getInformationControlCreator(sourceViewer));
+
+               Color background = getColor(store,
+                               PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND, manager);
+               assistant.setContextInformationPopupBackground(background);
+               assistant.setContextSelectorBackground(background);
+               assistant.setProposalSelectorBackground(background);
+
+               Color foreground = getColor(store,
+                               PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND, manager);
+               assistant.setContextInformationPopupForeground(foreground);
+               assistant.setContextSelectorForeground(foreground);
+               assistant.setProposalSelectorForeground(foreground);
+
+               return assistant;
+       }
+
+       private Color getColor(IPreferenceStore store, String key,
+                       IColorManager manager) {
+               RGB rgb = PreferenceConverter.getColor(store, key);
+               return manager.getColor(rgb);
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String, int)
+        * @since 2.1
+        */
+       public ITextHover getTextHover(ISourceViewer sourceViewer,
+                       String contentType, int stateMask) {
+               return new TemplateVariableTextHover(fProcessor);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskConfigurationBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskConfigurationBlock.java
new file mode 100644 (file)
index 0000000..e487226
--- /dev/null
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IListAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ListDialogField;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/** 
+ */
+public class TodoTaskConfigurationBlock extends OptionsConfigurationBlock {
+
+       private static final String PREF_COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;
+
+       private static final String PREF_COMPILER_TASK_PRIORITIES = JavaCore.COMPILER_TASK_PRIORITIES;
+
+       private static final String PRIORITY_HIGH = JavaCore.COMPILER_TASK_PRIORITY_HIGH;
+
+       private static final String PRIORITY_NORMAL = JavaCore.COMPILER_TASK_PRIORITY_NORMAL;
+
+       private static final String PRIORITY_LOW = JavaCore.COMPILER_TASK_PRIORITY_LOW;
+
+       public static class TodoTask {
+               public String name;
+
+               public String priority;
+       }
+
+       private static class TodoTaskLabelProvider extends LabelProvider implements
+                       ITableLabelProvider {
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+                */
+               public Image getImage(Object element) {
+                       return null; // JavaPluginImages.get(JavaPluginImages.IMG_OBJS_REFACTORING_INFO);
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+                */
+               public String getText(Object element) {
+                       return getColumnText(element, 0);
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
+                *      int)
+                */
+               public Image getColumnImage(Object element, int columnIndex) {
+                       return null;
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
+                *      int)
+                */
+               public String getColumnText(Object element, int columnIndex) {
+                       TodoTask task = (TodoTask) element;
+                       if (columnIndex == 0) {
+                               return task.name;
+                       } else {
+                               if (PRIORITY_HIGH.equals(task.priority)) {
+                                       return PreferencesMessages
+                                                       .getString("TodoTaskConfigurationBlock.markers.tasks.high.priority"); //$NON-NLS-1$
+                               } else if (PRIORITY_NORMAL.equals(task.priority)) {
+                                       return PreferencesMessages
+                                                       .getString("TodoTaskConfigurationBlock.markers.tasks.normal.priority"); //$NON-NLS-1$
+                               } else if (PRIORITY_LOW.equals(task.priority)) {
+                                       return PreferencesMessages
+                                                       .getString("TodoTaskConfigurationBlock.markers.tasks.low.priority"); //$NON-NLS-1$
+                               }
+                               return ""; //$NON-NLS-1$
+                       }
+               }
+
+       }
+
+       private static final int IDX_ADD = 0;
+
+       private static final int IDX_EDIT = 1;
+
+       private static final int IDX_REMOVE = 2;
+
+       private IStatus fTaskTagsStatus;
+
+       private ListDialogField fTodoTasksList;
+
+       public TodoTaskConfigurationBlock(IStatusChangeListener context,
+                       IJavaProject project) {
+               super(context, project, getKeys());
+
+               TaskTagAdapter adapter = new TaskTagAdapter();
+               String[] buttons = new String[] {
+                               /* 0 */PreferencesMessages
+                                               .getString("TodoTaskConfigurationBlock.markers.tasks.add.button"), //$NON-NLS-1$
+                               /* 1 */PreferencesMessages
+                                               .getString("TodoTaskConfigurationBlock.markers.tasks.edit.button"), //$NON-NLS-1$
+                               /* 2 */PreferencesMessages
+                                               .getString("TodoTaskConfigurationBlock.markers.tasks.remove.button"), //$NON-NLS-1$
+
+               };
+               fTodoTasksList = new ListDialogField(adapter, buttons,
+                               new TodoTaskLabelProvider());
+               fTodoTasksList.setDialogFieldListener(adapter);
+               fTodoTasksList.setLabelText(PreferencesMessages
+                               .getString("TodoTaskConfigurationBlock.markers.tasks.label")); //$NON-NLS-1$
+               fTodoTasksList.setRemoveButtonIndex(IDX_REMOVE);
+
+               String[] columnsHeaders = new String[] {
+                               PreferencesMessages
+                                               .getString("TodoTaskConfigurationBlock.markers.tasks.name.column"), //$NON-NLS-1$
+                               PreferencesMessages
+                                               .getString("TodoTaskConfigurationBlock.markers.tasks.priority.column"), //$NON-NLS-1$
+               };
+
+               fTodoTasksList.setTableColumns(new ListDialogField.ColumnsDescription(
+                               columnsHeaders, true));
+               unpackTodoTasks();
+               if (fTodoTasksList.getSize() > 0) {
+                       fTodoTasksList.selectFirstElement();
+               } else {
+                       fTodoTasksList.enableButton(IDX_EDIT, false);
+               }
+
+               fTaskTagsStatus = new StatusInfo();
+       }
+
+       private final static String[] getKeys() {
+               return new String[] { PREF_COMPILER_TASK_TAGS,
+                               PREF_COMPILER_TASK_PRIORITIES };
+       }
+
+       public class TaskTagAdapter implements IListAdapter, IDialogFieldListener {
+
+               private boolean canEdit(ListDialogField field) {
+                       return field.getSelectedElements().size() == 1;
+               }
+
+               public void customButtonPressed(ListDialogField field, int index) {
+                       doTodoButtonPressed(index);
+               }
+
+               public void selectionChanged(ListDialogField field) {
+                       field.enableButton(IDX_EDIT, canEdit(field));
+               }
+
+               public void doubleClicked(ListDialogField field) {
+                       if (canEdit(field)) {
+                               doTodoButtonPressed(IDX_EDIT);
+                       }
+               }
+
+               public void dialogFieldChanged(DialogField field) {
+                       validateSettings(PREF_COMPILER_TASK_TAGS, null);
+               }
+
+       }
+
+       protected Control createContents(Composite parent) {
+               setShell(parent.getShell());
+
+               Composite markersComposite = createMarkersTabContent(parent);
+
+               validateSettings(null, null);
+
+               return markersComposite;
+       }
+
+       private Composite createMarkersTabContent(Composite folder) {
+
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+
+               Composite markersComposite = new Composite(folder, SWT.NULL);
+               markersComposite.setLayout(layout);
+
+               fTodoTasksList.doFillIntoGrid(markersComposite, 3);
+               LayoutUtil.setHorizontalSpan(fTodoTasksList.getLabelControl(null), 2);
+
+               GridData data = (GridData) fTodoTasksList.getListControl(null)
+                               .getLayoutData();
+               data.grabExcessHorizontalSpace = true;
+               data.grabExcessVerticalSpace = true;
+               data.verticalAlignment = GridData.FILL;
+               // data.heightHint= SWTUtil.getTableHeightHint(table, 6);
+
+               return markersComposite;
+       }
+
+       protected void validateSettings(String changedKey, String newValue) {
+               if (changedKey != null) {
+                       if (PREF_COMPILER_TASK_TAGS.equals(changedKey)) {
+                               fTaskTagsStatus = validateTaskTags();
+                       } else {
+                               return;
+                       }
+               } else {
+                       fTaskTagsStatus = validateTaskTags();
+               }
+               IStatus status = fTaskTagsStatus; // StatusUtil.getMostSevere(new
+                                                                                       // IStatus[] { fTaskTagsStatus });
+               fContext.statusChanged(status);
+       }
+
+       private IStatus validateTaskTags() {
+               return new StatusInfo();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#performOk(boolean)
+        */
+       public boolean performOk(boolean enabled) {
+               packTodoTasks();
+               return super.performOk(enabled);
+       }
+
+       protected String[] getFullBuildDialogStrings(boolean workspaceSettings) {
+               String title = PreferencesMessages
+                               .getString("TodoTaskConfigurationBlock.needsbuild.title"); //$NON-NLS-1$
+               String message;
+               if (fProject == null) {
+                       message = PreferencesMessages
+                                       .getString("TodoTaskConfigurationBlock.needsfullbuild.message"); //$NON-NLS-1$
+               } else {
+                       message = PreferencesMessages
+                                       .getString("TodoTaskConfigurationBlock.needsprojectbuild.message"); //$NON-NLS-1$
+               }
+               return new String[] { title, message };
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#updateControls()
+        */
+       protected void updateControls() {
+               unpackTodoTasks();
+       }
+
+       private void unpackTodoTasks() {
+               String currTags = (String) fWorkingValues.get(PREF_COMPILER_TASK_TAGS);
+               String currPrios = (String) fWorkingValues
+                               .get(PREF_COMPILER_TASK_PRIORITIES);
+               String[] tags = getTokens(currTags, ","); //$NON-NLS-1$
+               String[] prios = getTokens(currPrios, ","); //$NON-NLS-1$
+               ArrayList elements = new ArrayList(tags.length);
+               for (int i = 0; i < tags.length; i++) {
+                       TodoTask task = new TodoTask();
+                       task.name = tags[i].trim();
+                       task.priority = (i < prios.length) ? prios[i] : PRIORITY_NORMAL;
+                       elements.add(task);
+               }
+               fTodoTasksList.setElements(elements);
+       }
+
+       private void packTodoTasks() {
+               StringBuffer tags = new StringBuffer();
+               StringBuffer prios = new StringBuffer();
+               List list = fTodoTasksList.getElements();
+               for (int i = 0; i < list.size(); i++) {
+                       if (i > 0) {
+                               tags.append(',');
+                               prios.append(',');
+                       }
+                       TodoTask elem = (TodoTask) list.get(i);
+                       tags.append(elem.name);
+                       prios.append(elem.priority);
+               }
+               fWorkingValues.put(PREF_COMPILER_TASK_TAGS, tags.toString());
+               fWorkingValues.put(PREF_COMPILER_TASK_PRIORITIES, prios.toString());
+       }
+
+       private void doTodoButtonPressed(int index) {
+               TodoTask edited = null;
+               if (index != IDX_ADD) {
+                       edited = (TodoTask) fTodoTasksList.getSelectedElements().get(0);
+               }
+
+               TodoTaskInputDialog dialog = new TodoTaskInputDialog(getShell(),
+                               edited, fTodoTasksList.getElements());
+               if (dialog.open() == Window.OK) {
+                       if (edited != null) {
+                               fTodoTasksList.replaceElement(edited, dialog.getResult());
+                       } else {
+                               fTodoTasksList.addElement(dialog.getResult());
+                       }
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskInputDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskInputDialog.java
new file mode 100644 (file)
index 0000000..0d6effb
--- /dev/null
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusDialog;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.preferences.TodoTaskConfigurationBlock.TodoTask;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ComboDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringDialogField;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Dialog to enter a na new task tag
+ */
+public class TodoTaskInputDialog extends StatusDialog {
+
+       private class CompilerTodoTaskInputAdapter implements IDialogFieldListener {
+               public void dialogFieldChanged(DialogField field) {
+                       doValidation();
+               }
+       }
+
+       private StringDialogField fNameDialogField;
+
+       private ComboDialogField fPriorityDialogField;
+
+       private List fExistingNames;
+
+       public TodoTaskInputDialog(Shell parent, TodoTask task, List existingEntries) {
+               super(parent);
+
+               fExistingNames = new ArrayList(existingEntries.size());
+               for (int i = 0; i < existingEntries.size(); i++) {
+                       TodoTask curr = (TodoTask) existingEntries.get(i);
+                       if (!curr.equals(task)) {
+                               fExistingNames.add(curr.name);
+                       }
+               }
+
+               if (task == null) {
+                       setTitle(PreferencesMessages
+                                       .getString("TodoTaskInputDialog.new.title")); //$NON-NLS-1$
+               } else {
+                       setTitle(PreferencesMessages
+                                       .getString("TodoTaskInputDialog.edit.title")); //$NON-NLS-1$
+               }
+
+               CompilerTodoTaskInputAdapter adapter = new CompilerTodoTaskInputAdapter();
+
+               fNameDialogField = new StringDialogField();
+               fNameDialogField.setLabelText(PreferencesMessages
+                               .getString("TodoTaskInputDialog.name.label")); //$NON-NLS-1$
+               fNameDialogField.setDialogFieldListener(adapter);
+
+               fNameDialogField.setText((task != null) ? task.name : ""); //$NON-NLS-1$
+
+               String[] items = new String[] {
+                               PreferencesMessages
+                                               .getString("TodoTaskInputDialog.priority.high"), //$NON-NLS-1$
+                               PreferencesMessages
+                                               .getString("TodoTaskInputDialog.priority.normal"), //$NON-NLS-1$
+                               PreferencesMessages
+                                               .getString("TodoTaskInputDialog.priority.low") //$NON-NLS-1$
+               };
+
+               fPriorityDialogField = new ComboDialogField(SWT.READ_ONLY);
+               fPriorityDialogField.setLabelText(PreferencesMessages
+                               .getString("TodoTaskInputDialog.priority.label")); //$NON-NLS-1$
+               fPriorityDialogField.setItems(items);
+               if (task != null) {
+                       if (JavaCore.COMPILER_TASK_PRIORITY_HIGH.equals(task.priority)) {
+                               fPriorityDialogField.selectItem(0);
+                       } else if (JavaCore.COMPILER_TASK_PRIORITY_NORMAL
+                                       .equals(task.priority)) {
+                               fPriorityDialogField.selectItem(1);
+                       } else {
+                               fPriorityDialogField.selectItem(2);
+                       }
+               } else {
+                       fPriorityDialogField.selectItem(1);
+               }
+       }
+
+       public TodoTask getResult() {
+               TodoTask task = new TodoTask();
+               task.name = fNameDialogField.getText().trim();
+               switch (fPriorityDialogField.getSelectionIndex()) {
+               case 0:
+                       task.priority = JavaCore.COMPILER_TASK_PRIORITY_HIGH;
+                       break;
+               case 1:
+                       task.priority = JavaCore.COMPILER_TASK_PRIORITY_NORMAL;
+                       break;
+               default:
+                       task.priority = JavaCore.COMPILER_TASK_PRIORITY_LOW;
+                       break;
+               }
+               return task;
+       }
+
+       protected Control createDialogArea(Composite parent) {
+               Composite composite = (Composite) super.createDialogArea(parent);
+
+               Composite inner = new Composite(composite, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               inner.setLayout(layout);
+
+               fNameDialogField.doFillIntoGrid(inner, 2);
+               fPriorityDialogField.doFillIntoGrid(inner, 2);
+
+               LayoutUtil.setHorizontalGrabbing(fNameDialogField.getTextControl(null));
+               LayoutUtil.setWidthHint(fNameDialogField.getTextControl(null),
+                               convertWidthInCharsToPixels(45));
+
+               fNameDialogField.postSetFocusOnDialogField(parent.getDisplay());
+
+               applyDialogFont(composite);
+               return composite;
+       }
+
+       private void doValidation() {
+               StatusInfo status = new StatusInfo();
+               String newText = fNameDialogField.getText();
+               if (newText.length() == 0) {
+                       status.setError(PreferencesMessages
+                                       .getString("TodoTaskInputDialog.error.enterName")); //$NON-NLS-1$
+               } else {
+                       if (newText.indexOf(',') != -1) {
+                               status.setError(PreferencesMessages
+                                               .getString("TodoTaskInputDialog.error.comma")); //$NON-NLS-1$
+                       } else if (fExistingNames.contains(newText)) {
+                               status.setError(PreferencesMessages
+                                               .getString("TodoTaskInputDialog.error.entryExists")); //$NON-NLS-1$
+                       } else if (Character.isWhitespace(newText.charAt(0))
+                                       || Character.isWhitespace(newText
+                                                       .charAt(newText.length() - 1))) {
+                               status.setError(PreferencesMessages
+                                               .getString("TodoTaskInputDialog.error.noSpace")); //$NON-NLS-1$
+                       }
+               }
+               updateStatus(status);
+       }
+
+       /*
+        * @see org.eclipse.jface.window.Window#configureShell(Shell)
+        */
+       protected void configureShell(Shell newShell) {
+               super.configureShell(newShell);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
+                               IJavaHelpContextIds.TODO_TASK_INPUT_DIALOG);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskPreferencePage.java
new file mode 100644 (file)
index 0000000..3667bdc
--- /dev/null
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/*
+ * The page to configure the compiler options.
+ */
+public class TodoTaskPreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage, IStatusChangeListener {
+
+       public static final String ID = "net.sourceforge.phpdt.ui.preferences.TodoTaskPreferencePage"; //$NON-NLS-1$
+
+       private TodoTaskConfigurationBlock fConfigurationBlock;
+
+       public TodoTaskPreferencePage() {
+               setPreferenceStore(WebUI.getDefault().getPreferenceStore());
+               // setDescription(PreferencesMessages.getString("TodoTaskPreferencePage.description"));
+               // //$NON-NLS-1$
+
+               // only used when page is shown programatically
+               setTitle(PreferencesMessages.getString("TodoTaskPreferencePage.title")); //$NON-NLS-1$
+
+               fConfigurationBlock = new TodoTaskConfigurationBlock(this, null);
+       }
+
+       /*
+        * @see IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+        */
+       public void init(IWorkbench workbench) {
+       }
+
+       /*
+        * @see PreferencePage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               // added for 1GEUGE6: ITPJUI:WIN2000 - Help is the same on all
+               // preference pages
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.TODOTASK_PREFERENCE_PAGE);
+       }
+
+       /*
+        * @see PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+               Control result = fConfigurationBlock.createContents(parent);
+               Dialog.applyDialogFont(result);
+               return result;
+       }
+
+       /*
+        * @see IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               if (!fConfigurationBlock.performOk(true)) {
+                       return false;
+               }
+               return super.performOk();
+       }
+
+       /*
+        * @see PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               fConfigurationBlock.performDefaults();
+               super.performDefaults();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener#statusChanged(org.eclipse.core.runtime.IStatus)
+        */
+       public void statusChanged(IStatus status) {
+               setValid(!status.matches(IStatus.ERROR));
+               StatusUtil.applyToStatusLine(this, status);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskPropertyPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/preferences/TodoTaskPropertyPage.java
new file mode 100644 (file)
index 0000000..b9395f4
--- /dev/null
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ControlEnableState;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.preference.PreferenceNode;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+/**
+ * Property page used to configure project specific task tags settings
+ */
+public class TodoTaskPropertyPage extends PropertyPage {
+
+       private TodoTaskConfigurationBlock fConfigurationBlock;
+
+       private Control fConfigurationBlockControl;
+
+       private ControlEnableState fBlockEnableState;
+
+       private SelectionButtonDialogField fUseWorkspaceSettings;
+
+       private SelectionButtonDialogField fChangeWorkspaceSettings;
+
+       private SelectionButtonDialogField fUseProjectSettings;
+
+       private IStatus fBlockStatus;
+
+       public TodoTaskPropertyPage() {
+               fBlockStatus = new StatusInfo();
+               fBlockEnableState = null;
+
+               IDialogFieldListener listener = new IDialogFieldListener() {
+                       public void dialogFieldChanged(DialogField field) {
+                               doDialogFieldChanged(field);
+                       }
+               };
+
+               fUseWorkspaceSettings = new SelectionButtonDialogField(SWT.RADIO);
+               fUseWorkspaceSettings.setDialogFieldListener(listener);
+               fUseWorkspaceSettings.setLabelText(PreferencesMessages
+                               .getString("TodoTaskPropertyPage.useworkspacesettings.label")); //$NON-NLS-1$
+
+               fChangeWorkspaceSettings = new SelectionButtonDialogField(SWT.PUSH);
+               fChangeWorkspaceSettings.setLabelText(PreferencesMessages
+                               .getString("TodoTaskPropertyPage.useworkspacesettings.change")); //$NON-NLS-1$
+               fChangeWorkspaceSettings.setDialogFieldListener(listener);
+
+               fUseWorkspaceSettings.attachDialogField(fChangeWorkspaceSettings);
+
+               fUseProjectSettings = new SelectionButtonDialogField(SWT.RADIO);
+               fUseProjectSettings.setDialogFieldListener(listener);
+               fUseProjectSettings.setLabelText(PreferencesMessages
+                               .getString("TodoTaskPropertyPage.useprojectsettings.label")); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+                               IJavaHelpContextIds.TODOTASK_PROPERTY_PAGE);
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+               IStatusChangeListener listener = new IStatusChangeListener() {
+                       public void statusChanged(IStatus status) {
+                               fBlockStatus = status;
+                               doStatusChanged();
+                       }
+               };
+               fConfigurationBlock = new TodoTaskConfigurationBlock(listener,
+                               getProject());
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 1;
+               composite.setLayout(layout);
+
+               fUseWorkspaceSettings.doFillIntoGrid(composite, 1);
+               LayoutUtil.setHorizontalGrabbing(fUseWorkspaceSettings
+                               .getSelectionButton(null));
+
+               fChangeWorkspaceSettings.doFillIntoGrid(composite, 1);
+               GridData data = (GridData) fChangeWorkspaceSettings.getSelectionButton(
+                               null).getLayoutData();
+               data.horizontalIndent = convertWidthInCharsToPixels(3);
+               data.horizontalAlignment = GridData.BEGINNING;
+
+               fUseProjectSettings.doFillIntoGrid(composite, 1);
+
+               data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.VERTICAL_ALIGN_FILL);
+               data.horizontalSpan = 1;
+               data.horizontalIndent = convertWidthInCharsToPixels(2);
+
+               fConfigurationBlockControl = fConfigurationBlock
+                               .createContents(composite);
+               fConfigurationBlockControl.setLayoutData(data);
+
+               boolean useProjectSettings = fConfigurationBlock
+                               .hasProjectSpecificOptions();
+
+               fUseProjectSettings.setSelection(useProjectSettings);
+               fUseWorkspaceSettings.setSelection(!useProjectSettings);
+
+               updateEnableState();
+               Dialog.applyDialogFont(composite);
+               return composite;
+       }
+
+       private boolean useProjectSettings() {
+               return fUseProjectSettings.isSelected();
+       }
+
+       private void doDialogFieldChanged(DialogField field) {
+               if (field == fChangeWorkspaceSettings) {
+                       TodoTaskPreferencePage page = new TodoTaskPreferencePage();
+                       showPreferencePage(TodoTaskPreferencePage.ID, page);
+               } else {
+                       updateEnableState();
+                       doStatusChanged();
+               }
+       }
+
+       /**
+        * Method statusChanged.
+        */
+       private void doStatusChanged() {
+               updateStatus(useProjectSettings() ? fBlockStatus : new StatusInfo());
+       }
+
+       /**
+        * Method getProject.
+        */
+       private IJavaProject getProject() {
+               return (IJavaProject) getElement().getAdapter(IJavaElement.class);
+       }
+
+       private void updateEnableState() {
+               if (useProjectSettings()) {
+                       if (fBlockEnableState != null) {
+                               fBlockEnableState.restore();
+                               fBlockEnableState = null;
+                       }
+               } else {
+                       if (fBlockEnableState == null) {
+                               fBlockEnableState = ControlEnableState
+                                               .disable(fConfigurationBlockControl);
+                       }
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               if (useProjectSettings()) {
+                       fUseProjectSettings.setSelection(false);
+                       fUseWorkspaceSettings.setSelection(true);
+                       fConfigurationBlock.performDefaults();
+               }
+               super.performDefaults();
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               return fConfigurationBlock.performOk(useProjectSettings());
+       }
+
+       private void updateStatus(IStatus status) {
+               setValid(!status.matches(IStatus.ERROR));
+               StatusUtil.applyToStatusLine(this, status);
+       }
+
+       private boolean showPreferencePage(String id, IPreferencePage page) {
+               final IPreferenceNode targetNode = new PreferenceNode(id, page);
+
+               PreferenceManager manager = new PreferenceManager();
+               manager.addToRoot(targetNode);
+               final PreferenceDialog dialog = new PreferenceDialog(getShell(),
+                               manager);
+               final boolean[] result = new boolean[] { false };
+               BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
+                       public void run() {
+                               dialog.create();
+                               dialog.setMessage(targetNode.getLabelText());
+                               result[0] = (dialog.open() == Window.OK);
+                       }
+               });
+               return result[0];
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/AbstractJavaScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/AbstractJavaScanner.java
new file mode 100644 (file)
index 0000000..0aa214b
--- /dev/null
@@ -0,0 +1,183 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpdt.ui.text.IColorManagerExtension;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * Initialized with a color manager and a preference store, its subclasses are
+ * only responsible for providing a list of preference keys based on which
+ * tokens are generated and to use this tokens to define the rules controlling
+ * this scanner.
+ */
+public abstract class AbstractJavaScanner extends BufferedRuleBasedScanner {
+
+       private IColorManager fColorManager;
+
+       private IPreferenceStore fPreferenceStore;
+
+       private Map fTokenMap = new HashMap();
+
+       private String[] fPropertyNamesColor;
+
+       private String[] fPropertyNamesStyle;
+
+       /**
+        * Returns the list of preference keys which define the tokens used in the
+        * rules of this scanner.
+        */
+       abstract protected String[] getTokenProperties();
+
+       /**
+        * Creates the list of rules controlling this scanner.
+        */
+       abstract protected List createRules();
+
+       /**
+        * Creates an abstract Java scanner.
+        */
+       public AbstractJavaScanner(IColorManager manager, IPreferenceStore store) {
+               super();
+               fColorManager = manager;
+               fPreferenceStore = store;
+       }
+
+       /**
+        * Must be called after the constructor has been called.
+        */
+       public final void initialize() {
+
+               fPropertyNamesColor = getTokenProperties();
+               int length = fPropertyNamesColor.length;
+               fPropertyNamesStyle = new String[length];
+               for (int i = 0; i < length; i++) {
+                       fPropertyNamesStyle[i] = fPropertyNamesColor[i] + "_bold"; //$NON-NLS-1$
+                       addToken(fPropertyNamesColor[i], fPropertyNamesStyle[i]);
+               }
+
+               initializeRules();
+       }
+
+       private void addToken(String colorKey, String styleKey) {
+               RGB rgb = PreferenceConverter.getColor(fPreferenceStore, colorKey);
+               if (fColorManager instanceof IColorManagerExtension) {
+                       IColorManagerExtension ext = (IColorManagerExtension) fColorManager;
+                       ext.unbindColor(colorKey);
+                       ext.bindColor(colorKey, rgb);
+               }
+
+               boolean bold = fPreferenceStore.getBoolean(styleKey);
+               fTokenMap.put(colorKey, new Token(new TextAttribute(fColorManager
+                               .getColor(colorKey), null, bold ? SWT.BOLD : SWT.NORMAL)));
+       }
+
+       protected Token getToken(String key) {
+               return (Token) fTokenMap.get(key);
+       }
+
+       private void initializeRules() {
+               List rules = createRules();
+               if (rules != null) {
+                       IRule[] result = new IRule[rules.size()];
+                       rules.toArray(result);
+                       setRules(result);
+               }
+       }
+
+       private int indexOf(String property) {
+               if (property != null) {
+                       int length = fPropertyNamesColor.length;
+                       for (int i = 0; i < length; i++) {
+                               if (property.equals(fPropertyNamesColor[i])
+                                               || property.equals(fPropertyNamesStyle[i]))
+                                       return i;
+                       }
+               }
+               return -1;
+       }
+
+       public boolean affectsBehavior(PropertyChangeEvent event) {
+               return indexOf(event.getProperty()) >= 0;
+       }
+
+       public void adaptToPreferenceChange(PropertyChangeEvent event) {
+               String p = event.getProperty();
+               int index = indexOf(p);
+               Token token = getToken(fPropertyNamesColor[index]);
+               if (fPropertyNamesColor[index].equals(p))
+                       adaptToColorChange(token, event);
+               else
+                       adaptToStyleChange(token, event);
+       }
+
+       private void adaptToColorChange(Token token, PropertyChangeEvent event) {
+               RGB rgb = null;
+
+               Object value = event.getNewValue();
+               if (value instanceof RGB)
+                       rgb = (RGB) value;
+               else if (value instanceof String)
+                       rgb = StringConverter.asRGB((String) value);
+
+               if (rgb != null) {
+
+                       String property = event.getProperty();
+
+                       if (fColorManager instanceof IColorManagerExtension) {
+                               IColorManagerExtension ext = (IColorManagerExtension) fColorManager;
+                               ext.unbindColor(property);
+                               ext.bindColor(property, rgb);
+                       }
+
+                       Object data = token.getData();
+                       if (data instanceof TextAttribute) {
+                               TextAttribute oldAttr = (TextAttribute) data;
+                               token.setData(new TextAttribute(fColorManager
+                                               .getColor(property), oldAttr.getBackground(), oldAttr
+                                               .getStyle()));
+                       }
+               }
+       }
+
+       private void adaptToStyleChange(Token token, PropertyChangeEvent event) {
+               boolean bold = false;
+               Object value = event.getNewValue();
+               if (value instanceof Boolean)
+                       bold = ((Boolean) value).booleanValue();
+               else if (value instanceof String) {
+                       String s = (String) value;
+                       if (IPreferenceStore.TRUE.equals(s))
+                               bold = true;
+                       else if (IPreferenceStore.FALSE.equals(s))
+                               bold = false;
+               }
+
+               Object data = token.getData();
+               if (data instanceof TextAttribute) {
+                       TextAttribute oldAttr = (TextAttribute) data;
+                       boolean isBold = (oldAttr.getStyle() == SWT.BOLD);
+                       if (isBold != bold)
+                               token.setData(new TextAttribute(oldAttr.getForeground(),
+                                               oldAttr.getBackground(), bold ? SWT.BOLD : SWT.NORMAL));
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/BufferedDocumentScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/BufferedDocumentScanner.java
new file mode 100644 (file)
index 0000000..cd6833f
--- /dev/null
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+
+/**
+ * A buffered document scanner. The buffer always contains a section of a fixed
+ * size of the document to be scanned.
+ */
+
+public final class BufferedDocumentScanner implements ICharacterScanner {
+
+       /** The document being scanned. */
+       private IDocument fDocument;
+
+       /** The offset of the document range to scan. */
+       private int fRangeOffset;
+
+       /** The length of the document range to scan. */
+       private int fRangeLength;
+
+       /** The delimiters of the document. */
+       private char[][] fDelimiters;
+
+       /** The buffer. */
+       private final char[] fBuffer;
+
+       /** The offset of the buffer within the document. */
+       private int fBufferOffset;
+
+       /** The valid length of the buffer for access. */
+       private int fBufferLength;
+
+       /** The offset of the scanner within the buffer. */
+       private int fOffset;
+
+       /**
+        * Creates a new buffered document scanner. The buffer size is set to the
+        * given number of characters.
+        * 
+        * @param size
+        *            the buffer size
+        */
+       public BufferedDocumentScanner(int size) {
+               Assert.isTrue(size >= 1);
+               fBuffer = new char[size];
+       }
+
+       /**
+        * Fills the buffer with the contens of the document starting at the given
+        * offset.
+        * 
+        * @param offset
+        *            the document offset at which the buffer starts
+        */
+       private final void updateBuffer(int offset) {
+
+               fBufferOffset = offset;
+
+               if (fBufferOffset + fBuffer.length > fRangeOffset + fRangeLength)
+                       fBufferLength = fRangeLength - (fBufferOffset - fRangeOffset);
+               else
+                       fBufferLength = fBuffer.length;
+
+               try {
+                       final String content = fDocument.get(fBufferOffset, fBufferLength);
+                       if (content != null) {
+                               content.getChars(0, fBufferLength, fBuffer, 0);
+                       }
+               } catch (BadLocationException e) {
+               }
+       }
+
+       /**
+        * Configures the scanner by providing access to the document range over
+        * which to scan.
+        * 
+        * @param document
+        *            the document to scan
+        * @param offset
+        *            the offset of the document range to scan
+        * @param length
+        *            the length of the document range to scan
+        */
+       public final void setRange(IDocument document, int offset, int length) {
+
+               fDocument = document;
+               fRangeOffset = offset;
+               fRangeLength = length;
+
+               String[] delimiters = document.getLegalLineDelimiters();
+               fDelimiters = new char[delimiters.length][];
+               for (int i = 0; i < delimiters.length; i++)
+                       fDelimiters[i] = delimiters[i].toCharArray();
+
+               updateBuffer(offset);
+               fOffset = 0;
+       }
+
+       /*
+        * @see ICharacterScanner#read()
+        */
+       public final int read() {
+
+               if (fOffset == fBufferLength) {
+                       if (fBufferOffset + fBufferLength == fDocument.getLength())
+                               return EOF;
+                       else {
+                               updateBuffer(fBufferOffset + fBufferLength);
+                               fOffset = 0;
+                       }
+               }
+               try {
+                       return fBuffer[fOffset++];
+               } catch (ArrayIndexOutOfBoundsException e) {
+                       System.out.println("Offset:" + fOffset);
+                       System.out.println("Buffer:" + fBuffer.toString());
+                       throw e;
+               }
+       }
+
+       /*
+        * @see ICharacterScanner#unread
+        */
+       public final void unread() {
+
+               if (fOffset == 0) {
+                       if (fBufferOffset == fRangeOffset) {
+                               // error: BOF
+                       } else {
+                               updateBuffer(fBufferOffset - fBuffer.length);
+                               fOffset = fBuffer.length - 1;
+                       }
+               } else {
+                       --fOffset;
+               }
+       }
+
+       /*
+        * @see ICharacterScanner#getColumn()
+        */
+       public final int getColumn() {
+
+               try {
+                       final int offset = fBufferOffset + fOffset;
+                       final int line = fDocument.getLineOfOffset(offset);
+                       final int start = fDocument.getLineOffset(line);
+                       return offset - start;
+               } catch (BadLocationException e) {
+               }
+
+               return -1;
+       }
+
+       /*
+        * @see ICharacterScanner#getLegalLineDelimiters()
+        */
+       public final char[][] getLegalLineDelimiters() {
+               return fDelimiters;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CombinedWordRule.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CombinedWordRule.java
new file mode 100644 (file)
index 0000000..dedad70
--- /dev/null
@@ -0,0 +1,408 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * An implementation of <code>IRule</code> capable of detecting words.
+ * <p>
+ * Word rules also allow for the association of tokens with specific words. That
+ * is, not only can the rule be used to provide tokens for exact matches, but
+ * also for the generalized notion of a word in the context in which it is used.
+ * A word rules uses a word detector to determine what a word is.
+ * </p>
+ * <p>
+ * This word rule allows a word detector to be shared among different word
+ * matchers. Its up to the word matchers to decide if a word matches and, in
+ * this a case, which token is associated with that word.
+ * </p>
+ * 
+ * @see IWordDetector
+ * @since 3.0
+ */
+public class CombinedWordRule implements IRule {
+
+       /**
+        * Word matcher, that associates matched words with tokens.
+        */
+       public static class WordMatcher {
+
+               /** The table of predefined words and token for this matcher */
+               private Map fWords = new HashMap();
+
+               /**
+                * Adds a word and the token to be returned if it is detected.
+                * 
+                * @param word
+                *            the word this rule will search for, may not be
+                *            <code>null</code>
+                * @param token
+                *            the token to be returned if the word has been found, may
+                *            not be <code>null</code>
+                */
+               public void addWord(String word, IToken token) {
+                       Assert.isNotNull(word);
+                       Assert.isNotNull(token);
+
+                       fWords.put(new CharacterBuffer(word), token);
+               }
+
+               /**
+                * Returns the token associated to the given word and the scanner state.
+                * 
+                * @param scanner
+                *            the scanner
+                * @param word
+                *            the word
+                * @return the token or <code>null</code> if none is associated by
+                *         this matcher
+                */
+               public IToken evaluate(ICharacterScanner scanner, CharacterBuffer word) {
+                       IToken token = (IToken) fWords.get(word);
+                       if (token != null)
+                               return token;
+                       return Token.UNDEFINED;
+               }
+
+               /**
+                * Removes all words.
+                */
+               public void clearWords() {
+                       fWords.clear();
+               }
+       }
+
+       /**
+        * Character buffer, mutable <b>or</b> suitable for use as key in hash
+        * maps.
+        */
+       public static class CharacterBuffer {
+
+               /** Buffer content */
+               private char[] fContent;
+
+               /** Buffer content size */
+               private int fLength = 0;
+
+               /** Is hash code cached? */
+               private boolean fIsHashCached = false;
+
+               /** The hash code */
+               private int fHashCode;
+
+               /**
+                * Initialize with the given capacity.
+                * 
+                * @param capacity
+                *            the initial capacity
+                */
+               public CharacterBuffer(int capacity) {
+                       fContent = new char[capacity];
+               }
+
+               /**
+                * Initialize with the given content.
+                * 
+                * @param string
+                *            the initial content
+                */
+               public CharacterBuffer(String content) {
+                       fContent = content.toCharArray();
+                       fLength = content.length();
+               }
+
+               /**
+                * Empties this buffer.
+                */
+               public void clear() {
+                       fIsHashCached = false;
+                       fLength = 0;
+               }
+
+               /**
+                * Appends the given character to the buffer.
+                * 
+                * @param c
+                *            the character
+                */
+               public void append(char c) {
+                       fIsHashCached = false;
+                       if (fLength == fContent.length) {
+                               char[] old = fContent;
+                               fContent = new char[old.length << 1];
+                               System.arraycopy(old, 0, fContent, 0, old.length);
+                       }
+                       fContent[fLength++] = c;
+               }
+
+               /**
+                * Returns the length of the content.
+                * 
+                * @return the length
+                */
+               public int length() {
+                       return fLength;
+               }
+
+               /**
+                * Returns the content as string.
+                * 
+                * @return the content
+                */
+               public String toString() {
+                       return new String(fContent, 0, fLength);
+               }
+
+               /**
+                * Returns the character at the given position.
+                * 
+                * @param i
+                *            the position
+                * @return the character at position <code>i</code>
+                */
+               public char charAt(int i) {
+                       return fContent[i];
+               }
+
+               /*
+                * @see java.lang.Object#hashCode()
+                */
+               public int hashCode() {
+                       if (fIsHashCached)
+                               return fHashCode;
+
+                       int hash = 0;
+                       for (int i = 0, n = fLength; i < n; i++)
+                               hash = 29 * hash + fContent[i];
+                       fHashCode = hash;
+                       fIsHashCached = true;
+                       return hash;
+               }
+
+               /*
+                * @see java.lang.Object#equals(java.lang.Object)
+                */
+               public boolean equals(Object obj) {
+                       if (obj == this)
+                               return true;
+                       if (!(obj instanceof CharacterBuffer))
+                               return false;
+                       CharacterBuffer buffer = (CharacterBuffer) obj;
+                       int length = buffer.length();
+                       if (length != fLength)
+                               return false;
+                       for (int i = 0; i < length; i++)
+                               if (buffer.charAt(i) != fContent[i])
+                                       return false;
+                       return true;
+               }
+
+               /**
+                * Is the content equal to the given string?
+                * 
+                * @param string
+                *            the string
+                * @return <code>true</code> iff the content is the same character
+                *         sequence as in the string
+                */
+               public boolean equals(String string) {
+                       int length = string.length();
+                       if (length != fLength)
+                               return false;
+                       for (int i = 0; i < length; i++)
+                               if (string.charAt(i) != fContent[i])
+                                       return false;
+                       return true;
+               }
+       }
+
+       /** Internal setting for the uninitialized column constraint */
+       private static final int UNDEFINED = -1;
+
+       /** The word detector used by this rule */
+       private IWordDetector fDetector;
+
+       /**
+        * The default token to be returned on success and if nothing else has been
+        * specified.
+        */
+       private IToken fDefaultToken;
+
+       /** The column constraint */
+       private int fColumn = UNDEFINED;
+
+       /** Buffer used for pattern detection */
+       private CharacterBuffer fBuffer = new CharacterBuffer(16);
+
+       /** List of word matchers */
+       private List fMatchers = new ArrayList();
+
+       /**
+        * Creates a rule which, with the help of an word detector, will return the
+        * token associated with the detected word. If no token has been associated,
+        * the scanner will be rolled back and an undefined token will be returned
+        * in order to allow any subsequent rules to analyze the characters.
+        * 
+        * @param detector
+        *            the word detector to be used by this rule, may not be
+        *            <code>null</code>
+        * 
+        * @see #addWord(String, IToken)
+        */
+       public CombinedWordRule(IWordDetector detector) {
+               this(detector, null, Token.UNDEFINED);
+       }
+
+       /**
+        * Creates a rule which, with the help of an word detector, will return the
+        * token associated with the detected word. If no token has been associated,
+        * the specified default token will be returned.
+        * 
+        * @param detector
+        *            the word detector to be used by this rule, may not be
+        *            <code>null</code>
+        * @param defaultToken
+        *            the default token to be returned on success if nothing else is
+        *            specified, may not be <code>null</code>
+        * 
+        * @see #addWord(String, IToken)
+        */
+       public CombinedWordRule(IWordDetector detector, IToken defaultToken) {
+               this(detector, null, defaultToken);
+       }
+
+       /**
+        * Creates a rule which, with the help of an word detector, will return the
+        * token associated with the detected word. If no token has been associated,
+        * the scanner will be rolled back and an undefined token will be returned
+        * in order to allow any subsequent rules to analyze the characters.
+        * 
+        * @param detector
+        *            the word detector to be used by this rule, may not be
+        *            <code>null</code>
+        * @param matcher
+        *            the initial word matcher
+        * 
+        * @see #addWord(String, IToken)
+        */
+       public CombinedWordRule(IWordDetector detector, WordMatcher matcher) {
+               this(detector, matcher, Token.UNDEFINED);
+       }
+
+       /**
+        * Creates a rule which, with the help of an word detector, will return the
+        * token associated with the detected word. If no token has been associated,
+        * the specified default token will be returned.
+        * 
+        * @param detector
+        *            the word detector to be used by this rule, may not be
+        *            <code>null</code>
+        * @param matcher
+        *            the initial word matcher
+        * @param defaultToken
+        *            the default token to be returned on success if nothing else is
+        *            specified, may not be <code>null</code>
+        * 
+        * @see #addWord(String, IToken)
+        */
+       public CombinedWordRule(IWordDetector detector, WordMatcher matcher,
+                       IToken defaultToken) {
+
+               Assert.isNotNull(detector);
+               Assert.isNotNull(defaultToken);
+
+               fDetector = detector;
+               fDefaultToken = defaultToken;
+               if (matcher != null)
+                       addWordMatcher(matcher);
+       }
+
+       /**
+        * Adds the given matcher.
+        * 
+        * @param matcher
+        *            the matcher
+        */
+       public void addWordMatcher(WordMatcher matcher) {
+               fMatchers.add(matcher);
+       }
+
+       /**
+        * Sets a column constraint for this rule. If set, the rule's token will
+        * only be returned if the pattern is detected starting at the specified
+        * column. If the column is smaller then 0, the column constraint is
+        * considered removed.
+        * 
+        * @param column
+        *            the column in which the pattern starts
+        */
+       public void setColumnConstraint(int column) {
+               if (column < 0)
+                       column = UNDEFINED;
+               fColumn = column;
+       }
+
+       /*
+        * @see IRule#evaluate(ICharacterScanner)
+        */
+       public IToken evaluate(ICharacterScanner scanner) {
+               int c = scanner.read();
+               if (fDetector.isWordStart((char) c)) {
+                       if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
+
+                               fBuffer.clear();
+                               do {
+                                       fBuffer.append((char) c);
+                                       c = scanner.read();
+                               } while (c != ICharacterScanner.EOF
+                                               && fDetector.isWordPart((char) c));
+                               scanner.unread();
+
+                               for (int i = 0, n = fMatchers.size(); i < n; i++) {
+                                       IToken token = ((WordMatcher) fMatchers.get(i)).evaluate(
+                                                       scanner, fBuffer);
+                                       if (!token.isUndefined())
+                                               return token;
+                               }
+
+                               if (fDefaultToken.isUndefined())
+                                       unreadBuffer(scanner);
+
+                               return fDefaultToken;
+                       }
+               }
+
+               scanner.unread();
+               return Token.UNDEFINED;
+       }
+
+       /**
+        * Returns the characters in the buffer to the scanner.
+        * 
+        * @param scanner
+        *            the scanner to be used
+        */
+       private void unreadBuffer(ICharacterScanner scanner) {
+               for (int i = fBuffer.length() - 1; i >= 0; i--)
+                       scanner.unread();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CompositeReconcilingStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CompositeReconcilingStrategy.java
new file mode 100644 (file)
index 0000000..5733b4f
--- /dev/null
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
+
+/**
+ * A reconciling strategy consisting of a sequence of internal reconciling
+ * strategies. By default, all requests are passed on to the contained
+ * strategies.
+ * 
+ * @since 3.0
+ */
+public class CompositeReconcilingStrategy implements IReconcilingStrategy,
+               IReconcilingStrategyExtension {
+
+       /** The list of internal reconciling strategies. */
+       private IReconcilingStrategy[] fStrategies;
+
+       /**
+        * Creates a new, empty composite reconciling strategy.
+        */
+       public CompositeReconcilingStrategy() {
+       }
+
+       /**
+        * Sets the reconciling strategies for this composite strategy.
+        * 
+        * @param strategies
+        *            the strategies to be set or <code>null</code>
+        */
+       public void setReconcilingStrategies(IReconcilingStrategy[] strategies) {
+               fStrategies = strategies;
+       }
+
+       /**
+        * Returns the previously set stratgies or <code>null</code>.
+        * 
+        * @return the contained strategies or <code>null</code>
+        */
+       public IReconcilingStrategy[] getReconcilingStrategies() {
+               return fStrategies;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
+        */
+       public void setDocument(IDocument document) {
+               if (fStrategies == null)
+                       return;
+
+               for (int i = 0; i < fStrategies.length; i++)
+                       fStrategies[i].setDocument(document);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion,
+        *      org.eclipse.jface.text.IRegion)
+        */
+       public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+               if (fStrategies == null)
+                       return;
+
+               for (int i = 0; i < fStrategies.length; i++)
+                       fStrategies[i].reconcile(dirtyRegion, subRegion);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
+        */
+       public void reconcile(IRegion partition) {
+               if (fStrategies == null)
+                       return;
+
+               for (int i = 0; i < fStrategies.length; i++)
+                       fStrategies[i].reconcile(partition);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
+        */
+       public void setProgressMonitor(IProgressMonitor monitor) {
+               if (fStrategies == null)
+                       return;
+
+               for (int i = 0; i < fStrategies.length; i++) {
+                       if (fStrategies[i] instanceof IReconcilingStrategyExtension) {
+                               IReconcilingStrategyExtension extension = (IReconcilingStrategyExtension) fStrategies[i];
+                               extension.setProgressMonitor(monitor);
+                       }
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
+        */
+       public void initialReconcile() {
+               if (fStrategies == null)
+                       return;
+
+               for (int i = 0; i < fStrategies.length; i++) {
+                       if (fStrategies[i] instanceof IReconcilingStrategyExtension) {
+                               IReconcilingStrategyExtension extension = (IReconcilingStrategyExtension) fStrategies[i];
+                               extension.initialReconcile();
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/ContentAssistPreference.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/ContentAssistPreference.java
new file mode 100644 (file)
index 0000000..b391165
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.php.HTMLCompletionProcessor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPCompletionProcessor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+
+public class ContentAssistPreference {
+
+       /** Preference key for content assist auto activation */
+       private final static String AUTOACTIVATION = PreferenceConstants.CODEASSIST_AUTOACTIVATION;
+
+       /** Preference key for content assist auto activation delay */
+       private final static String AUTOACTIVATION_DELAY = PreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY;
+
+       /** Preference key for content assist proposal color */
+       private final static String PROPOSALS_FOREGROUND = PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND;
+
+       /** Preference key for content assist proposal color */
+       private final static String PROPOSALS_BACKGROUND = PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND;
+
+       /** Preference key for content assist parameters color */
+       private final static String PARAMETERS_FOREGROUND = PreferenceConstants.CODEASSIST_PARAMETERS_FOREGROUND;
+
+       /** Preference key for content assist parameters color */
+       private final static String PARAMETERS_BACKGROUND = PreferenceConstants.CODEASSIST_PARAMETERS_BACKGROUND;
+
+       /** Preference key for content assist completion replacement color */
+       private final static String COMPLETION_REPLACEMENT_FOREGROUND = PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND;
+
+       /** Preference key for content assist completion replacement color */
+       private final static String COMPLETION_REPLACEMENT_BACKGROUND = PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND;
+
+       /** Preference key for content assist auto insert */
+       private final static String AUTOINSERT = PreferenceConstants.CODEASSIST_AUTOINSERT;
+
+       /** Preference key for php content assist auto activation triggers */
+       private final static String AUTOACTIVATION_TRIGGERS_JAVA = PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVA;
+
+       /** Preference key for phpdoc content assist auto activation triggers */
+       private final static String AUTOACTIVATION_TRIGGERS_JAVADOC = PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVADOC;
+
+       /** Preference key for html content assist auto activation triggers */
+       private final static String AUTOACTIVATION_TRIGGERS_HTML = PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_HTML;
+
+       /** Preference key for visibility of proposals */
+       private final static String SHOW_VISIBLE_PROPOSALS = PreferenceConstants.CODEASSIST_SHOW_VISIBLE_PROPOSALS;
+
+       /** Preference key for alphabetic ordering of proposals */
+       private final static String ORDER_PROPOSALS = PreferenceConstants.CODEASSIST_ORDER_PROPOSALS;
+
+       /** Preference key for case sensitivity of propsals */
+       private final static String CASE_SENSITIVITY = PreferenceConstants.CODEASSIST_CASE_SENSITIVITY;
+
+       /** Preference key for adding imports on code assist */
+       private final static String ADD_IMPORT = PreferenceConstants.CODEASSIST_ADDIMPORT;
+
+       /** Preference key for inserting content assist */
+       private static final String INSERT_COMPLETION = PreferenceConstants.CODEASSIST_INSERT_COMPLETION;
+
+       /** Preference key for filling argument names on method completion */
+       private static final String FILL_METHOD_ARGUMENTS = PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES;
+
+       /** Preference key for guessing argument names on method completion */
+       private static final String GUESS_METHOD_ARGUMENTS = PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS;
+
+       private static Color getColor(IPreferenceStore store, String key,
+                       IColorManager manager) {
+               RGB rgb = PreferenceConverter.getColor(store, key);
+               return manager.getColor(rgb);
+       }
+
+       private static Color getColor(IPreferenceStore store, String key) {
+               JavaTextTools textTools = WebUI.getDefault()
+                               .getJavaTextTools();
+               return getColor(store, key, textTools.getColorManager());
+       }
+
+       private static PHPCompletionProcessor getJavaProcessor(
+                       ContentAssistant assistant) {
+               IContentAssistProcessor p = assistant
+                               .getContentAssistProcessor(IPHPPartitions.PHP_PARTITIONING);
+               if (p instanceof PHPCompletionProcessor)
+                       return (PHPCompletionProcessor) p;
+               return null;
+       }
+
+       private static PHPDocCompletionProcessor getJavaDocProcessor(
+                       ContentAssistant assistant) {
+               IContentAssistProcessor p = assistant
+                               .getContentAssistProcessor(IPHPPartitions.PHP_PHPDOC_COMMENT);
+               if (p instanceof PHPDocCompletionProcessor)
+                       return (PHPDocCompletionProcessor) p;
+               return null;
+       }
+
+       private static HTMLCompletionProcessor getHTMLProcessor(
+                       ContentAssistant assistant) {
+               IContentAssistProcessor p = assistant
+                               .getContentAssistProcessor(IPHPPartitions.HTML);
+               if (p instanceof HTMLCompletionProcessor)
+                       return (HTMLCompletionProcessor) p;
+               return null;
+       }
+
+       private static void configureJavaProcessor(ContentAssistant assistant,
+                       IPreferenceStore store) {
+               PHPCompletionProcessor pcp = getJavaProcessor(assistant);
+               if (pcp == null)
+                       return;
+
+               String triggers = store.getString(AUTOACTIVATION_TRIGGERS_JAVA);
+               if (triggers != null)
+                       pcp.setCompletionProposalAutoActivationCharacters(triggers
+                                       .toCharArray());
+               boolean enabled;
+               // boolean enabled= store.getBoolean(SHOW_VISIBLE_PROPOSALS);
+               // jcp.restrictProposalsToVisibility(enabled);
+               //              
+               // enabled= store.getBoolean(CASE_SENSITIVITY);
+               // jcp.restrictProposalsToMatchingCases(enabled);
+               //              
+               enabled = store.getBoolean(ORDER_PROPOSALS);
+               pcp.orderProposalsAlphabetically(enabled);
+               //              
+               // enabled= store.getBoolean(ADD_IMPORT);
+               // jcp.allowAddingImports(enabled);
+       }
+
+       private static void configureJavaDocProcessor(ContentAssistant assistant,
+                       IPreferenceStore store) {
+               PHPDocCompletionProcessor pdcp = getJavaDocProcessor(assistant);
+               if (pdcp == null)
+                       return;
+
+               String triggers = store.getString(AUTOACTIVATION_TRIGGERS_JAVADOC);
+               if (triggers != null)
+                       pdcp.setCompletionProposalAutoActivationCharacters(triggers
+                                       .toCharArray());
+
+               boolean enabled = store.getBoolean(CASE_SENSITIVITY);
+               pdcp.restrictProposalsToMatchingCases(enabled);
+
+               enabled = store.getBoolean(ORDER_PROPOSALS);
+               pdcp.orderProposalsAlphabetically(enabled);
+       }
+
+       private static void configureHTMLProcessor(ContentAssistant assistant,
+                       IPreferenceStore store) {
+               HTMLCompletionProcessor hcp = getHTMLProcessor(assistant);
+               if (hcp == null)
+                       return;
+
+               String triggers = store.getString(AUTOACTIVATION_TRIGGERS_HTML);
+               if (triggers != null)
+                       hcp.setCompletionProposalAutoActivationCharacters(triggers
+                                       .toCharArray());
+
+               boolean enabled;
+               // boolean enabled = store.getBoolean(CASE_SENSITIVITY);
+               // jdcp.restrictProposalsToMatchingCases(enabled);
+
+               enabled = store.getBoolean(ORDER_PROPOSALS);
+               hcp.orderProposalsAlphabetically(enabled);
+       }
+
+       /**
+        * Configure the given content assistant from the given store.
+        */
+       public static void configure(ContentAssistant assistant,
+                       IPreferenceStore store) {
+
+               JavaTextTools textTools = WebUI.getDefault()
+                               .getJavaTextTools();
+               IColorManager manager = textTools.getColorManager();
+
+               boolean enabled = store.getBoolean(AUTOACTIVATION);
+               assistant.enableAutoActivation(enabled);
+
+               int delay = store.getInt(AUTOACTIVATION_DELAY);
+               assistant.setAutoActivationDelay(delay);
+
+               Color c = getColor(store, PROPOSALS_FOREGROUND, manager);
+               assistant.setProposalSelectorForeground(c);
+
+               c = getColor(store, PROPOSALS_BACKGROUND, manager);
+               assistant.setProposalSelectorBackground(c);
+
+               c = getColor(store, PARAMETERS_FOREGROUND, manager);
+               assistant.setContextInformationPopupForeground(c);
+               assistant.setContextSelectorForeground(c);
+
+               c = getColor(store, PARAMETERS_BACKGROUND, manager);
+               assistant.setContextInformationPopupBackground(c);
+               assistant.setContextSelectorBackground(c);
+
+               enabled = store.getBoolean(AUTOINSERT);
+               assistant.enableAutoInsert(enabled);
+
+               configureJavaProcessor(assistant, store);
+               configureJavaDocProcessor(assistant, store);
+               configureHTMLProcessor(assistant, store);
+       }
+
+       private static void changeJavaProcessor(ContentAssistant assistant,
+                       IPreferenceStore store, String key) {
+               PHPCompletionProcessor jcp = getJavaProcessor(assistant);
+               if (jcp == null)
+                       return;
+
+               if (AUTOACTIVATION_TRIGGERS_JAVA.equals(key)) {
+                       String triggers = store.getString(AUTOACTIVATION_TRIGGERS_JAVA);
+                       if (triggers != null)
+                               jcp.setCompletionProposalAutoActivationCharacters(triggers
+                                               .toCharArray());
+               }
+               // else if (SHOW_VISIBLE_PROPOSALS.equals(key)) {
+               // boolean enabled= store.getBoolean(SHOW_VISIBLE_PROPOSALS);
+               // jcp.restrictProposalsToVisibility(enabled);
+               // } else if (CASE_SENSITIVITY.equals(key)) {
+               // boolean enabled= store.getBoolean(CASE_SENSITIVITY);
+               // jcp.restrictProposalsToMatchingCases(enabled); }
+               else if (ORDER_PROPOSALS.equals(key)) {
+                       boolean enable = store.getBoolean(ORDER_PROPOSALS);
+                       jcp.orderProposalsAlphabetically(enable);
+                       // } else if (ADD_IMPORT.equals(key)) {
+                       // boolean enabled= store.getBoolean(ADD_IMPORT);
+                       // jcp.allowAddingImports(enabled);
+               }
+       }
+
+       private static void changeJavaDocProcessor(ContentAssistant assistant,
+                       IPreferenceStore store, String key) {
+               PHPDocCompletionProcessor jdcp = getJavaDocProcessor(assistant);
+               if (jdcp == null)
+                       return;
+
+               if (AUTOACTIVATION_TRIGGERS_JAVADOC.equals(key)) {
+                       String triggers = store.getString(AUTOACTIVATION_TRIGGERS_JAVADOC);
+                       if (triggers != null)
+                               jdcp.setCompletionProposalAutoActivationCharacters(triggers
+                                               .toCharArray());
+               } else if (CASE_SENSITIVITY.equals(key)) {
+                       boolean enabled = store.getBoolean(CASE_SENSITIVITY);
+                       jdcp.restrictProposalsToMatchingCases(enabled);
+               } else if (ORDER_PROPOSALS.equals(key)) {
+                       boolean enable = store.getBoolean(ORDER_PROPOSALS);
+                       jdcp.orderProposalsAlphabetically(enable);
+               }
+       }
+
+       private static void changeHTMLProcessor(ContentAssistant assistant,
+                       IPreferenceStore store, String key) {
+               HTMLCompletionProcessor jdcp = getHTMLProcessor(assistant);
+               if (jdcp == null)
+                       return;
+
+               if (AUTOACTIVATION_TRIGGERS_HTML.equals(key)) {
+                       String triggers = store.getString(AUTOACTIVATION_TRIGGERS_HTML);
+                       if (triggers != null)
+                               jdcp.setCompletionProposalAutoActivationCharacters(triggers
+                                               .toCharArray());
+                       // } else if (CASE_SENSITIVITY.equals(key)) {
+                       // boolean enabled = store.getBoolean(CASE_SENSITIVITY);
+                       // jdcp.restrictProposalsToMatchingCases(enabled);
+               } else if (ORDER_PROPOSALS.equals(key)) {
+                       boolean enable = store.getBoolean(ORDER_PROPOSALS);
+                       jdcp.orderProposalsAlphabetically(enable);
+               }
+       }
+
+       /**
+        * Changes the configuration of the given content assistant according to the
+        * given property change event and the given preference store.
+        */
+       public static void changeConfiguration(ContentAssistant assistant,
+                       IPreferenceStore store, PropertyChangeEvent event) {
+
+               String p = event.getProperty();
+
+               if (AUTOACTIVATION.equals(p)) {
+                       boolean enabled = store.getBoolean(AUTOACTIVATION);
+                       assistant.enableAutoActivation(enabled);
+               } else if (AUTOACTIVATION_DELAY.equals(p)) {
+                       int delay = store.getInt(AUTOACTIVATION_DELAY);
+                       assistant.setAutoActivationDelay(delay);
+               } else if (PROPOSALS_FOREGROUND.equals(p)) {
+                       Color c = getColor(store, PROPOSALS_FOREGROUND);
+                       assistant.setProposalSelectorForeground(c);
+               } else if (PROPOSALS_BACKGROUND.equals(p)) {
+                       Color c = getColor(store, PROPOSALS_BACKGROUND);
+                       assistant.setProposalSelectorBackground(c);
+               } else if (PARAMETERS_FOREGROUND.equals(p)) {
+                       Color c = getColor(store, PARAMETERS_FOREGROUND);
+                       assistant.setContextInformationPopupForeground(c);
+                       assistant.setContextSelectorForeground(c);
+               } else if (PARAMETERS_BACKGROUND.equals(p)) {
+                       Color c = getColor(store, PARAMETERS_BACKGROUND);
+                       assistant.setContextInformationPopupBackground(c);
+                       assistant.setContextSelectorBackground(c);
+               } else if (AUTOINSERT.equals(p)) {
+                       boolean enabled = store.getBoolean(AUTOINSERT);
+                       assistant.enableAutoInsert(enabled);
+               }
+
+               changeJavaProcessor(assistant, store, p);
+               changeJavaDocProcessor(assistant, store, p);
+               changeHTMLProcessor(assistant, store, p);
+       }
+
+       public static boolean fillArgumentsOnMethodCompletion(IPreferenceStore store) {
+               return store.getBoolean(FILL_METHOD_ARGUMENTS);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CustomSourceInformationControl.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/CustomSourceInformationControl.java
new file mode 100644 (file)
index 0000000..3f3c40a
--- /dev/null
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.internal.ui.text.java.hover.SourceViewerInformationControl;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Source viewer used to display quick diff hovers.
+ * 
+ * @since 3.0
+ */
+public class CustomSourceInformationControl extends
+               SourceViewerInformationControl {
+
+       /** The font name for the viewer font - the same as the java editor's. */
+       private static final String SYMBOLIC_FONT_NAME = "net.sourceforge.phpdt.ui.editors.textfont"; //$NON-NLS-1$
+
+       /**
+        * The maximum width of the control, set in
+        * <code>setSizeConstraints(int, int)</code>.
+        */
+       int fMaxWidth = Integer.MAX_VALUE;
+
+       /**
+        * The maximum height of the control, set in
+        * <code>setSizeConstraints(int, int)</code>.
+        */
+       int fMaxHeight = Integer.MAX_VALUE;
+
+       /**
+        * The partition type to be used as the starting partition type by the
+        * paritition scanner.
+        */
+       private String fPartition;
+
+       /** The horizontal scroll index. */
+       private int fHorizontalScrollPixel;
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int,
+        *      int)
+        */
+       public void setSizeConstraints(int maxWidth, int maxHeight) {
+               fMaxWidth = maxWidth;
+               fMaxHeight = maxHeight;
+       }
+
+       /**
+        * Creates a new information control.
+        * 
+        * @param parent
+        *            the shell that is the parent of this hover / control
+        * @param partition
+        *            the initial partition type to be used for the underlying
+        *            viewer
+        */
+       public CustomSourceInformationControl(Shell parent, String partition) {
+               super(parent);
+               setViewerFont();
+               setStartingPartitionType(partition);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
+        */
+       public Point computeSizeHint() {
+               Point size = super.computeSizeHint();
+               size.x = Math.min(size.x, fMaxWidth);
+               size.y = Math.min(size.y, fMaxHeight);
+               return size;
+       }
+
+       /**
+        * Sets the font for this viewer sustaining selection and scroll position.
+        */
+       private void setViewerFont() {
+               Font font = JFaceResources.getFont(SYMBOLIC_FONT_NAME);
+
+               if (getViewer().getDocument() != null) {
+
+                       Point selection = getViewer().getSelectedRange();
+                       int topIndex = getViewer().getTopIndex();
+
+                       StyledText styledText = getViewer().getTextWidget();
+                       Control parent = styledText;
+                       if (getViewer() instanceof ITextViewerExtension) {
+                               ITextViewerExtension extension = (ITextViewerExtension) getViewer();
+                               parent = extension.getControl();
+                       }
+
+                       parent.setRedraw(false);
+
+                       styledText.setFont(font);
+
+                       getViewer().setSelectedRange(selection.x, selection.y);
+                       getViewer().setTopIndex(topIndex);
+
+                       if (parent instanceof Composite) {
+                               Composite composite = (Composite) parent;
+                               composite.layout(true);
+                       }
+
+                       parent.setRedraw(true);
+
+               } else {
+                       StyledText styledText = getViewer().getTextWidget();
+                       styledText.setFont(font);
+               }
+       }
+
+       /**
+        * Sets the initial partition for the underlying source viewer.
+        * 
+        * @param partition
+        *            the partition type
+        */
+       public void setStartingPartitionType(String partition) {
+               if (partition == null)
+                       fPartition = IDocument.DEFAULT_CONTENT_TYPE;
+               else
+                       fPartition = partition;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
+        */
+       public void setInformation(String content) {
+               super.setInformation(content);
+               IDocument doc = getViewer().getDocument();
+               if (doc == null)
+                       return;
+
+               // ensure that we can scroll enough
+               ensureScrollable();
+
+               String start = null;
+               if (IPHPPartitions.PHP_PHPDOC_COMMENT.equals(fPartition)) {
+                       start = "/**" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
+               } else if (IPHPPartitions.PHP_MULTILINE_COMMENT.equals(fPartition)) {
+                       start = "/*" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
+               }
+               if (start != null) {
+                       try {
+                               doc.replace(0, 0, start);
+                               int startLen = start.length();
+                               getViewer().setDocument(doc, startLen,
+                                               doc.getLength() - startLen);
+                       } catch (BadLocationException e) {
+                               // impossible
+                               Assert.isTrue(false);
+                       }
+               }
+
+               getViewer().getTextWidget().setHorizontalPixel(fHorizontalScrollPixel);
+       }
+
+       /**
+        * Ensures that the control can be scrolled at least to
+        * <code>fHorizontalScrollPixel</code> and adjusts <code>fMaxWidth</code>
+        * accordingly.
+        */
+       private void ensureScrollable() {
+               IDocument doc = getViewer().getDocument();
+               if (doc == null)
+                       return;
+
+               StyledText widget = getViewer().getTextWidget();
+               if (widget == null || widget.isDisposed())
+                       return;
+
+               int last = doc.getNumberOfLines() - 1;
+               GC gc = new GC(widget);
+               gc.setFont(widget.getFont());
+               int maxWidth = 0;
+               String content = new String();
+
+               try {
+                       for (int i = 0; i <= last; i++) {
+                               IRegion line;
+                               line = doc.getLineInformation(i);
+                               content = doc.get(line.getOffset(), line.getLength());
+                               int width = gc.textExtent(content).x;
+                               if (width > maxWidth) {
+                                       maxWidth = width;
+                               }
+                       }
+               } catch (BadLocationException e) {
+                       return;
+               } finally {
+                       gc.dispose();
+               }
+
+               // limit the size of the window to the maximum width minus scrolling,
+               // but never more than the configured max size (viewport size).
+               fMaxWidth = Math.max(0, Math.min(fMaxWidth, maxWidth
+                               - fHorizontalScrollPixel + 8));
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.java.hover.SourceViewerInformationControl#hasContents()
+        */
+       public boolean hasContents() {
+               return super.hasContents() && fMaxWidth > 0;
+       }
+
+       /**
+        * Sets the horizontal scroll index in pixels.
+        * 
+        * @param scrollIndex
+        *            the new horizontal scroll index
+        */
+       public void setHorizontalScrollPixel(int scrollIndex) {
+               scrollIndex = Math.max(0, scrollIndex);
+               fHorizontalScrollPixel = scrollIndex;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/DocumentCharacterIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/DocumentCharacterIterator.java
new file mode 100644 (file)
index 0000000..416ddaf
--- /dev/null
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.text;
+
+import java.text.CharacterIterator;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * An <code>IDocument</code> based implementation of
+ * <code>CharacterIterator</code> and <code>CharSequence</code>. Note that
+ * the supplied document is not copied; if the document is modified during the
+ * lifetime of a <code>DocumentCharacterIterator</code>, the methods
+ * returning document content may not always return the same values. Also, if
+ * accessing the document fails with a {@link BadLocationException}, any of
+ * <code>CharacterIterator</code> methods as well as <code>charAt</code>may
+ * return {@link CharacterIterator#DONE}.
+ * 
+ * @since 3.0
+ */
+public class DocumentCharacterIterator implements CharacterIterator,
+               CharSequence {
+
+       private int fIndex = -1;
+
+       private final IDocument fDocument;
+
+       private final int fFirst;
+
+       private final int fLast;
+
+       private void invariant() {
+               Assert.isTrue(fIndex >= fFirst);
+               Assert.isTrue(fIndex <= fLast);
+       }
+
+       /**
+        * Creates an iterator for the entire document.
+        * 
+        * @param document
+        *            the document backing this iterator
+        */
+       public DocumentCharacterIterator(IDocument document) {
+               this(document, 0);
+       }
+
+       /**
+        * Creates an iterator, starting at offset <code>first</code>.
+        * 
+        * @param document
+        *            the document backing this iterator
+        * @param first
+        *            the first character to consider
+        * @throws IllegalArgumentException
+        *             if the indices are out of bounds
+        */
+       public DocumentCharacterIterator(IDocument document, int first)
+                       throws IllegalArgumentException {
+               this(document, first, document.getLength());
+       }
+
+       /**
+        * Creates an iterator for the document contents from <code>first</code>
+        * (inclusive) to <code>last</code> (exclusive).
+        * 
+        * @param document
+        *            the document backing this iterator
+        * @param first
+        *            the first character to consider
+        * @param last
+        *            the last character index to consider
+        * @throws IllegalArgumentException
+        *             if the indices are out of bounds
+        */
+       public DocumentCharacterIterator(IDocument document, int first, int last)
+                       throws IllegalArgumentException {
+               if (document == null)
+                       throw new NullPointerException();
+               if (first < 0 || first > last)
+                       throw new IllegalArgumentException();
+               if (last > document.getLength())
+                       throw new IllegalArgumentException();
+               fDocument = document;
+               fFirst = first;
+               fLast = last;
+               fIndex = first;
+               invariant();
+       }
+
+       /*
+        * @see java.text.CharacterIterator#first()
+        */
+       public char first() {
+               return setIndex(getBeginIndex());
+       }
+
+       /*
+        * @see java.text.CharacterIterator#last()
+        */
+       public char last() {
+               if (fFirst == fLast)
+                       return setIndex(getEndIndex());
+               else
+                       return setIndex(getEndIndex() - 1);
+       }
+
+       /*
+        * @see java.text.CharacterIterator#current()
+        */
+       public char current() {
+               if (fIndex >= fFirst && fIndex < fLast)
+                       try {
+                               return fDocument.getChar(fIndex);
+                       } catch (BadLocationException e) {
+                               // ignore
+                       }
+               return DONE;
+       }
+
+       /*
+        * @see java.text.CharacterIterator#next()
+        */
+       public char next() {
+               return setIndex(Math.min(fIndex + 1, getEndIndex()));
+       }
+
+       /*
+        * @see java.text.CharacterIterator#previous()
+        */
+       public char previous() {
+               if (fIndex > getBeginIndex()) {
+                       return setIndex(fIndex - 1);
+               } else {
+                       return DONE;
+               }
+       }
+
+       /*
+        * @see java.text.CharacterIterator#setIndex(int)
+        */
+       public char setIndex(int position) {
+               if (position >= getBeginIndex() && position <= getEndIndex())
+                       fIndex = position;
+               else
+                       throw new IllegalArgumentException();
+
+               invariant();
+               return current();
+       }
+
+       /*
+        * @see java.text.CharacterIterator#getBeginIndex()
+        */
+       public int getBeginIndex() {
+               return fFirst;
+       }
+
+       /*
+        * @see java.text.CharacterIterator#getEndIndex()
+        */
+       public int getEndIndex() {
+               return fLast;
+       }
+
+       /*
+        * @see java.text.CharacterIterator#getIndex()
+        */
+       public int getIndex() {
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.CharacterIterator#clone()
+        */
+       public Object clone() {
+               try {
+                       return super.clone();
+               } catch (CloneNotSupportedException e) {
+                       throw new InternalError();
+               }
+       }
+
+       /*
+        * @see java.lang.CharSequence#length()
+        */
+       public int length() {
+               return getEndIndex() - getBeginIndex();
+       }
+
+       /**
+        * {@inheritDoc}
+        * <p>
+        * Note that, if the document is modified concurrently, this method may
+        * return {@link CharacterIterator#DONE} if a {@link BadLocationException}
+        * was thrown when accessing the backing document.
+        * </p>
+        * 
+        * @param index
+        *            {@inheritDoc}
+        * @return {@inheritDoc}
+        */
+       public char charAt(int index) {
+               if (index >= 0 && index < length())
+                       try {
+                               return fDocument.getChar(getBeginIndex() + index);
+                       } catch (BadLocationException e) {
+                               // ignore and return DONE
+                               return DONE;
+                       }
+               else
+                       throw new IndexOutOfBoundsException();
+       }
+
+       /*
+        * @see java.lang.CharSequence#subSequence(int, int)
+        */
+       public CharSequence subSequence(int start, int end) {
+               if (start < 0)
+                       throw new IndexOutOfBoundsException();
+               if (end < start)
+                       throw new IndexOutOfBoundsException();
+               if (end > length())
+                       throw new IndexOutOfBoundsException();
+               return new DocumentCharacterIterator(fDocument,
+                               getBeginIndex() + start, getBeginIndex() + end);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/FastJavaPartitionScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/FastJavaPartitionScanner.java
new file mode 100644 (file)
index 0000000..8653b77
--- /dev/null
@@ -0,0 +1,632 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpeclipse.ui.text.rules.AbstractPartitioner;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * This scanner recognizes the JavaDoc comments, Java multi line comments, Java
+ * single line comments, Java strings.
+ */
+public class FastJavaPartitionScanner implements IPartitionTokenScanner,
+               IPHPPartitions {
+
+       // states
+       private static final int PHP = 0;
+
+       private static final int SINGLE_LINE_COMMENT = 1;
+
+       private static final int MULTI_LINE_COMMENT = 2;
+
+       private static final int PHPDOC = 3;
+
+       private static final int STRING_DQ = 4;
+
+       private static final int STRING_SQ = 5;
+
+       private static final int STRING_HEREDOC = 6;
+
+       // beginning of prefixes and postfixes
+       private static final int NONE = 0;
+
+       private static final int BACKSLASH = 1; // postfix for STRING_DQ and
+                                                                                       // CHARACTER
+
+       private static final int SLASH = 2; // prefix for SINGLE_LINE or MULTI_LINE
+                                                                               // or
+
+       // JAVADOC
+
+       private static final int SLASH_STAR = 3; // prefix for MULTI_LINE_COMMENT
+                                                                                               // or
+
+       // JAVADOC
+
+       private static final int SLASH_STAR_STAR = 4; // prefix for
+                                                                                                       // MULTI_LINE_COMMENT
+
+       // or JAVADOC
+
+       private static final int STAR = 5; // postfix for MULTI_LINE_COMMENT or
+
+       // JAVADOC
+
+       private static final int CARRIAGE_RETURN = 6; // postfix for STRING_DQ,
+
+       // CHARACTER and
+       // SINGLE_LINE_COMMENT
+
+       // private static final int HEREDOC = 7;
+
+       /** The scanner. */
+       private final BufferedDocumentScanner fScanner = new BufferedDocumentScanner(
+                       1000); // faster
+
+       // implementation
+
+       /** The offset of the last returned token. */
+       private int fTokenOffset;
+
+       /** The length of the last returned token. */
+       private int fTokenLength;
+
+       /** The state of the scanner. */
+       private int fState;
+
+       /** The last significant characters read. */
+       private int fLast;
+
+       /** The amount of characters already read on first call to nextToken(). */
+       private int fPrefixLength;
+
+       // emulate JavaPartitionScanner
+       private boolean fEmulate = false;
+
+       private int fJavaOffset;
+
+       private int fJavaLength;
+
+       private final IToken[] fTokens = new IToken[] { new Token(null),
+                       new Token(PHP_SINGLELINE_COMMENT),
+                       new Token(PHP_MULTILINE_COMMENT), new Token(PHP_PHPDOC_COMMENT),
+                       new Token(PHP_STRING_DQ), new Token(PHP_STRING_SQ),
+                       new Token(PHP_STRING_HEREDOC) };
+
+       public FastJavaPartitionScanner(boolean emulate) {
+               fEmulate = emulate;
+       }
+
+       public FastJavaPartitionScanner() {
+               this(false);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+        */
+       public IToken nextToken() {
+
+               // emulate JavaPartitionScanner
+               if (fEmulate) {
+                       if (fJavaOffset != -1
+                                       && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) {
+                               fTokenOffset += fTokenLength;
+                               return fTokens[PHP];
+                       } else {
+                               fJavaOffset = -1;
+                               fJavaLength = 0;
+                       }
+               }
+
+               fTokenOffset += fTokenLength;
+               fTokenLength = fPrefixLength;
+
+               while (true) {
+                       final int ch = fScanner.read();
+
+                       // characters
+                       switch (ch) {
+                       case ICharacterScanner.EOF:
+                               if (fTokenLength > 0) {
+                                       fLast = NONE; // ignore last
+                                       return preFix(fState, PHP, NONE, 0);
+
+                               } else {
+                                       fLast = NONE;
+                                       fPrefixLength = 0;
+                                       return Token.EOF;
+                               }
+
+                       case '\r':
+                               // emulate JavaPartitionScanner
+                               if (!fEmulate && fLast != CARRIAGE_RETURN) {
+                                       fLast = CARRIAGE_RETURN;
+                                       fTokenLength++;
+                                       continue;
+
+                               } else {
+
+                                       switch (fState) {
+                                       case SINGLE_LINE_COMMENT:
+                                               // case CHARACTER:
+                                               // case STRING_DQ:
+                                               // case STRING_SQ:
+                                               if (fTokenLength > 0) {
+                                                       IToken token = fTokens[fState];
+
+                                                       // emulate JavaPartitionScanner
+                                                       if (fEmulate) {
+                                                               fTokenLength++;
+                                                               fLast = NONE;
+                                                               fPrefixLength = 0;
+                                                       } else {
+                                                               fLast = CARRIAGE_RETURN;
+                                                               fPrefixLength = 1;
+                                                       }
+
+                                                       fState = PHP;
+                                                       return token;
+
+                                               } else {
+                                                       consume();
+                                                       continue;
+                                               }
+
+                                       default:
+                                               consume();
+                                               continue;
+                                       }
+                               }
+
+                       case '\n':
+                               switch (fState) {
+                               case SINGLE_LINE_COMMENT:
+                                       // case CHARACTER:
+                                       // case STRING_DQ:
+                                       // case STRING_SQ:
+                                       // assert(fTokenLength > 0);
+                                       return postFix(fState);
+
+                               default:
+                                       consume();
+                                       continue;
+                               }
+
+                       case '?':
+                               if (fState == SINGLE_LINE_COMMENT) {
+                                       int nextch = fScanner.read();
+                                       if (nextch == '>') {
+                                               // <h1>This is an <?php # echo 'simple' ?> example.</h1>
+                                               fTokenLength--;
+                                               fScanner.unread();
+                                               fScanner.unread();
+                                               return postFix(fState);
+                                       } else {
+                                               // bug #1404228: Crash on <?php // comment ?>
+                                               if (nextch != ICharacterScanner.EOF) {
+                                                       fScanner.unread();
+                                               }
+                                       }
+                               }
+
+                       default:
+                               if (!fEmulate && fLast == CARRIAGE_RETURN) {
+                                       switch (fState) {
+                                       case SINGLE_LINE_COMMENT:
+                                               // case CHARACTER:
+                                               // case STRING_DQ:
+                                               // case STRING_SQ:
+                                               int last;
+                                               int newState;
+                                               switch (ch) {
+                                               case '/':
+                                                       last = SLASH;
+                                                       newState = PHP;
+                                                       break;
+
+                                               case '*':
+                                                       last = STAR;
+                                                       newState = PHP;
+                                                       break;
+
+                                               case '\'':
+                                                       last = NONE;
+                                                       newState = STRING_SQ;
+                                                       break;
+
+                                               case '"':
+                                                       last = NONE;
+                                                       newState = STRING_DQ;
+                                                       break;
+
+                                               case '\r':
+                                                       last = CARRIAGE_RETURN;
+                                                       newState = PHP;
+                                                       break;
+
+                                               case '\\':
+                                                       last = BACKSLASH;
+                                                       newState = PHP;
+                                                       break;
+
+                                               default:
+                                                       last = NONE;
+                                                       newState = PHP;
+                                                       break;
+                                               }
+
+                                               fLast = NONE; // ignore fLast
+                                               return preFix(fState, newState, last, 1);
+
+                                       default:
+                                               break;
+                                       }
+                               }
+                       }
+
+                       // states
+                       switch (fState) {
+                       case PHP:
+                               switch (ch) {
+                               case '#':
+                                       if (fTokenLength > 0) {
+                                               return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 1);
+                                       } else {
+                                               preFix(PHP, SINGLE_LINE_COMMENT, NONE, 1);
+                                               fTokenOffset += fTokenLength;
+                                               fTokenLength = fPrefixLength;
+                                               break;
+                                       }
+                               case '/':
+                                       if (fLast == SLASH) {
+                                               if (fTokenLength - getLastLength(fLast) > 0) {
+                                                       return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
+                                               } else {
+                                                       preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
+                                                       fTokenOffset += fTokenLength;
+                                                       fTokenLength = fPrefixLength;
+                                                       break;
+                                               }
+
+                                       } else {
+                                               fTokenLength++;
+                                               fLast = SLASH;
+                                               break;
+                                       }
+
+                               case '*':
+                                       if (fLast == SLASH) {
+                                               if (fTokenLength - getLastLength(fLast) > 0)
+                                                       return preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR,
+                                                                       2);
+                                               else {
+                                                       preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+                                                       fTokenOffset += fTokenLength;
+                                                       fTokenLength = fPrefixLength;
+                                                       break;
+                                               }
+
+                                       } else {
+                                               consume();
+                                               break;
+                                       }
+
+                               case '\'':
+                                       fLast = NONE; // ignore fLast
+                                       if (fTokenLength > 0)
+                                               return preFix(PHP, STRING_SQ, NONE, 1);
+                                       else {
+                                               preFix(PHP, STRING_SQ, NONE, 1);
+                                               fTokenOffset += fTokenLength;
+                                               fTokenLength = fPrefixLength;
+                                               break;
+                                       }
+
+                               case '"':
+                                       fLast = NONE; // ignore fLast
+                                       if (fTokenLength > 0)
+                                               return preFix(PHP, STRING_DQ, NONE, 1);
+                                       else {
+                                               preFix(PHP, STRING_DQ, NONE, 1);
+                                               fTokenOffset += fTokenLength;
+                                               fTokenLength = fPrefixLength;
+                                               break;
+                                       }
+
+                               default:
+                                       consume();
+                                       break;
+                               }
+                               break;
+
+                       case SINGLE_LINE_COMMENT:
+                               consume();
+                               break;
+
+                       case PHPDOC:
+                               switch (ch) {
+                               case '/':
+                                       switch (fLast) {
+                                       case SLASH_STAR_STAR:
+                                               return postFix(MULTI_LINE_COMMENT);
+
+                                       case STAR:
+                                               return postFix(PHPDOC);
+
+                                       default:
+                                               consume();
+                                               break;
+                                       }
+                                       break;
+
+                               case '*':
+                                       fTokenLength++;
+                                       fLast = STAR;
+                                       break;
+
+                               default:
+                                       consume();
+                                       break;
+                               }
+                               break;
+
+                       case MULTI_LINE_COMMENT:
+                               switch (ch) {
+                               case '*':
+                                       if (fLast == SLASH_STAR) {
+                                               fLast = SLASH_STAR_STAR;
+                                               fTokenLength++;
+                                               fState = PHPDOC;
+                                       } else {
+                                               fTokenLength++;
+                                               fLast = STAR;
+                                       }
+                                       break;
+
+                               case '/':
+                                       if (fLast == STAR) {
+                                               return postFix(MULTI_LINE_COMMENT);
+                                       } else {
+                                               consume();
+                                               break;
+                                       }
+
+                               default:
+                                       consume();
+                                       break;
+                               }
+                               break;
+
+                       case STRING_DQ:
+                               switch (ch) {
+                               case '\\':
+                                       fLast = (fLast == BACKSLASH) ? NONE : BACKSLASH;
+                                       fTokenLength++;
+                                       break;
+
+                               case '\"':
+                                       if (fLast != BACKSLASH) {
+                                               return postFix(STRING_DQ);
+
+                                       } else {
+                                               consume();
+                                               break;
+                                       }
+
+                               default:
+                                       consume();
+                                       break;
+                               }
+                               break;
+                       case STRING_SQ:
+                               switch (ch) {
+                               case '\\':
+                                       fLast = (fLast == BACKSLASH) ? NONE : BACKSLASH;
+                                       fTokenLength++;
+                                       break;
+
+                               case '\'':
+                                       if (fLast != BACKSLASH) {
+                                               return postFix(STRING_SQ);
+
+                                       } else {
+                                               consume();
+                                               break;
+                                       }
+
+                               default:
+                                       consume();
+                                       break;
+                               }
+                               break;
+                       // case CHARACTER:
+                       // switch (ch) {
+                       // case '\\':
+                       // fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+                       // fTokenLength++;
+                       // break;
+                       //
+                       // case '\'':
+                       // if (fLast != BACKSLASH) {
+                       // return postFix(CHARACTER);
+                       //
+                       // } else {
+                       // consume();
+                       // break;
+                       // }
+                       //
+                       // default:
+                       // consume();
+                       // break;
+                       // }
+                       // break;
+                       }
+               }
+       }
+
+       private static final int getLastLength(int last) {
+               switch (last) {
+               default:
+                       return -1;
+
+               case NONE:
+                       return 0;
+
+               case CARRIAGE_RETURN:
+               case BACKSLASH:
+               case SLASH:
+               case STAR:
+                       return 1;
+
+               case SLASH_STAR:
+                       return 2;
+
+               case SLASH_STAR_STAR:
+                       return 3;
+               }
+       }
+
+       private final void consume() {
+               fTokenLength++;
+               fLast = NONE;
+       }
+
+       private final IToken postFix(int state) {
+               fTokenLength++;
+               fLast = NONE;
+               fState = PHP;
+               fPrefixLength = 0;
+               return fTokens[state];
+       }
+
+       private final IToken preFix(int state, int newState, int last,
+                       int prefixLength) {
+               // emulate JavaPartitionScanner
+               if (fEmulate && state == PHP
+                               && (fTokenLength - getLastLength(fLast) > 0)) {
+                       fTokenLength -= getLastLength(fLast);
+                       fJavaOffset = fTokenOffset;
+                       fJavaLength = fTokenLength;
+                       fTokenLength = 1;
+                       fState = newState;
+                       fPrefixLength = prefixLength;
+                       fLast = last;
+                       return fTokens[state];
+
+               } else {
+                       fTokenLength -= getLastLength(fLast);
+                       fLast = last;
+                       fPrefixLength = prefixLength;
+                       IToken token = fTokens[state];
+                       fState = newState;
+                       return token;
+               }
+       }
+
+       private static int getState(String contentType) {
+
+               if (contentType == null)
+                       return PHP;
+
+               else if (contentType.equals(PHP_SINGLELINE_COMMENT))
+                       return SINGLE_LINE_COMMENT;
+
+               else if (contentType.equals(PHP_MULTILINE_COMMENT))
+                       return MULTI_LINE_COMMENT;
+
+               else if (contentType.equals(PHP_PHPDOC_COMMENT))
+                       return PHPDOC;
+
+               else if (contentType.equals(PHP_STRING_DQ))
+                       return STRING_DQ;
+
+               else if (contentType.equals(PHP_STRING_SQ))
+                       return STRING_SQ;
+
+               else if (contentType.equals(PHP_STRING_HEREDOC))
+                       return STRING_HEREDOC;
+
+               // else if (contentType.equals(JAVA_CHARACTER))
+               // return CHARACTER;
+
+               else
+                       return PHP;
+       }
+
+       /*
+        * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String,
+        *      int)
+        */
+       public void setPartialRange(IDocument document, int offset, int length,
+                       String contentType, int partitionOffset) {
+               fScanner.setRange(document, offset, length);
+               setRange(document, offset, length);
+               fTokenOffset = partitionOffset;
+               fTokenLength = 0;
+               fPrefixLength = offset - partitionOffset;
+               fLast = NONE;
+
+               if (offset == partitionOffset) {
+                       // restart at beginning of partition
+                       fState = PHP;
+               } else {
+                       fState = getState(contentType);
+               }
+
+               // emulate JavaPartitionScanner
+               if (fEmulate) {
+                       fJavaOffset = -1;
+                       fJavaLength = 0;
+               }
+       }
+
+       /*
+        * @see ITokenScanner#setRange(IDocument, int, int)
+        */
+       public void setRange(IDocument document, int offset, int length) {
+               fScanner.setRange(document, offset, length);
+               fTokenOffset = offset;
+               fTokenLength = 0;
+               fPrefixLength = 0;
+               fLast = NONE;
+               fState = PHP;
+
+               // emulate JavaPartitionScanner
+               if (fEmulate) {
+                       fJavaOffset = -1;
+                       fJavaLength = 0;
+               }
+       }
+
+       /*
+        * @see ITokenScanner#getTokenLength()
+        */
+       public int getTokenLength() {
+               return fTokenLength;
+       }
+
+       /*
+        * @see ITokenScanner#getTokenOffset()
+        */
+       public int getTokenOffset() {
+               if (AbstractPartitioner.DEBUG) {
+                       Assert.isTrue(fTokenOffset >= 0, Integer.toString(fTokenOffset));
+               }
+               return fTokenOffset;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTML2TextReader.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTML2TextReader.java
new file mode 100644 (file)
index 0000000..1fe8811
--- /dev/null
@@ -0,0 +1,301 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+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 net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+
+/**
+ * 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 LINE_DELIM = System.getProperty(
+                       "line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+
+       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("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$
+
+               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;
+
+       /**
+        * Transforms the html text from the reader to formatted text.
+        * 
+        * @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 SubstitutionTextReader#computeSubstitution(char)
+        */
+       protected String computeSubstitution(int c) throws IOException {
+
+               if (c == '<')
+                       return processHTMLTag();
+               else if (c == '&')
+                       return processEntity();
+               else if (fIsPreformattedText)
+                       return processPreformattedText(c);
+
+               return null;
+       }
+
+       private String html2Text(String html) {
+
+               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 ("h5".equals(html) || "dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$
+                       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$
+                       return LINE_DELIM
+                                       + "\t" + PHPUIMessages.getString("HTML2TextReader.dash"); //$NON-NLS-1$ //$NON-NLS-2$
+
+               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)) //$NON-NLS-1$
+                       return LINE_DELIM;
+
+               if ("/p".equals(html)) { //$NON-NLS-1$
+                       boolean inParagraph = fInParagraph;
+                       fInParagraph = false;
+                       return inParagraph ? EMPTY_STRING : LINE_DELIM;
+               }
+
+               if ("/h5".equals(html) || "/dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$
+                       stopBold();
+                       return LINE_DELIM;
+               }
+
+               if ("/dd".equals(html)) //$NON-NLS-1$
+                       return LINE_DELIM;
+
+               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 - 3)))) { //$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/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTMLPrinter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTMLPrinter.java
new file mode 100644 (file)
index 0000000..47484da
--- /dev/null
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Provides a set of convenience methods for creating HTML pages.
+ */
+public class HTMLPrinter {
+
+       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, '<', "&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) {
+               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 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) {
+               RGB bgColor = null;
+               IWorkbenchWindow window = PlatformUI.getWorkbench()
+                               .getActiveWorkbenchWindow();
+               if (window != null) {
+                       Display display = window.getShell().getDisplay();
+                       if (display != null && !display.isDisposed())
+                               bgColor = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)
+                                               .getRGB();
+               }
+               if (bgColor == null)
+                       bgColor = new RGB(255, 255, 225); // RGB value of info bg color on
+                                                                                               // WindowsXP
+
+               insertPageProlog(buffer, position, bgColor); //$NON-NLS-1$
+       }
+
+       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);
+               }
+       }
+
+       public static void addParagraph(StringBuffer buffer, Reader paragraphReader) {
+               if (paragraphReader != null)
+                       addParagraph(buffer, read(paragraphReader));
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTMLTextPresenter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/HTMLTextPresenter.java
new file mode 100644 (file)
index 0000000..aa21538
--- /dev/null
@@ -0,0 +1,196 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Display;
+
+public class HTMLTextPresenter implements
+               DefaultInformationControl.IInformationPresenter {
+
+       private static final String LINE_DELIM = System.getProperty(
+                       "line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+
+       private int fCounter;
+
+       private boolean fEnforceUpperLineLimit;
+
+       public HTMLTextPresenter(boolean enforceUpperLineLimit) {
+               super();
+               fEnforceUpperLineLimit = enforceUpperLineLimit;
+       }
+
+       public HTMLTextPresenter() {
+               this(true);
+       }
+
+       protected Reader 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) {
+
+               if (hoverInfo == null)
+                       return null;
+
+               GC gc = new GC(display);
+               try {
+
+                       StringBuffer buffer = new StringBuffer();
+                       int maxNumberOfLines = Math.round(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) {
+                               append(buffer, LINE_DELIM, lineFormatted ? presentation : null);
+                               append(buffer, PHPUIMessages
+                                               .getString("HTMLTextPresenter.ellipsis"), presentation); //$NON-NLS-1$
+                       }
+
+                       return trim(buffer, presentation);
+
+               } catch (IOException e) {
+
+                       WebUI.log(e);
+                       return null;
+
+               } finally {
+                       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/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/IPHPPartitions.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/IPHPPartitions.java
new file mode 100644 (file)
index 0000000..18b2e2a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Created on 05.03.2003
+ *
+ */
+package net.sourceforge.phpdt.internal.ui.text;
+
+/**
+ * @author Stefan Langer (musk)
+ * 
+ */
+public interface IPHPPartitions {
+       public final static String PHP_PARTITIONING = "___php_partitioning"; //$NON-NLS-1$
+
+       public final static String PHP_PHPDOC_COMMENT = "__php_phpdoc_comment"; //$NON-NLS-1$
+
+       public final static String PHP_SINGLELINE_COMMENT = "__php_singleline_comment"; //$NON-NLS-1$
+
+       public final static String PHP_MULTILINE_COMMENT = "__php_multiline_comment"; //$NON-NLS-1$
+
+       public final static String PHP_STRING_DQ = "__php_string"; //$NON-NLS-1$
+
+       public final static String PHP_STRING_SQ = "__php_string_sq"; //$NON-NLS-1$
+
+       public final static String PHP_STRING_HEREDOC = "__php_string_heredoc"; //$NON-NLS-1$
+
+       public final static String JAVASCRIPT = "__javascript"; //$NON-NLS-1$
+
+       public final static String JS_MULTILINE_COMMENT = "__js_multiline_comment"; //$NON-NLS-1$
+
+       public final static String CSS = "__css"; //$NON-NLS-1$
+
+       public final static String CSS_MULTILINE_COMMENT = "__css_multiline_comment"; //$NON-NLS-1$
+
+       public final static String HTML = "__html"; //$NON-NLS-1$
+
+       public final static String HTML_MULTILINE_COMMENT = "__html_multiline_comment"; //$NON-NLS-1$
+
+       public final static String SMARTY = "__smarty"; //$NON-NLS-1$
+
+       public final static String SMARTY_MULTILINE_COMMENT = "__smarty_multiline_comment"; //$NON-NLS-1$
+
+       public final static int PHP_FILE = 1;
+
+       public final static int HTML_FILE = 2;
+
+       public final static int XML_FILE = 3;
+
+       public final static int SMARTY_FILE = 4;
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/ITypingRunListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/ITypingRunListener.java
new file mode 100644 (file)
index 0000000..a1e35a5
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.internal.ui.text.TypingRun.ChangeType;
+
+/**
+ * Listener for <code>TypingRun</code> events.
+ * 
+ * @since 3.0
+ */
+public interface ITypingRunListener {
+       /**
+        * Called when a new <code>TypingRun</code> is started.
+        * 
+        * @param run
+        *            the newly started run
+        */
+       void typingRunStarted(TypingRun run);
+
+       /**
+        * Called whenever a <code>TypingRun</code> is ended.
+        * 
+        * @param run
+        *            the ended run
+        * @param reason
+        *            the type of change that caused the end of the run
+        */
+       void typingRunEnded(TypingRun run, ChangeType reason);
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaAnnotationHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaAnnotationHover.java
new file mode 100644 (file)
index 0000000..3b564d5
--- /dev/null
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.corext.Assert;
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+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.ui.editors.text.EditorsUI;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+
+/**
+ * Determines all markers for the given line and collects, concatenates, and
+ * formates their messages.
+ */
+public class JavaAnnotationHover implements IAnnotationHover {
+       private static class JavaAnnotationHoverType {
+       }
+
+       public static final JavaAnnotationHoverType OVERVIEW_RULER_HOVER = new JavaAnnotationHoverType();
+
+       public static final JavaAnnotationHoverType TEXT_RULER_HOVER = new JavaAnnotationHoverType();
+
+       public static final JavaAnnotationHoverType VERTICAL_RULER_HOVER = new JavaAnnotationHoverType();
+
+       // private IPreferenceStore fStore =
+       // PHPeclipsePlugin.getDefault().getPreferenceStore();
+       private IPreferenceStore fStore = EditorsUI.getPreferenceStore();
+
+       private JavaAnnotationHoverType fType;
+
+       public JavaAnnotationHover(JavaAnnotationHoverType type) {
+               Assert.isTrue(OVERVIEW_RULER_HOVER.equals(type)
+                               || TEXT_RULER_HOVER.equals(type)
+                               || VERTICAL_RULER_HOVER.equals(type));
+               fType = type;
+       }
+
+       /**
+        * Returns the distance to the ruler line.
+        */
+       protected int compareRulerLine(Position position, IDocument document,
+                       int line) {
+
+               if (position.getOffset() > -1 && position.getLength() > -1) {
+                       try {
+                               int javaAnnotationLine = document.getLineOfOffset(position
+                                               .getOffset());
+                               if (line == javaAnnotationLine)
+                                       return 1;
+                               if (javaAnnotationLine <= line
+                                               && line <= document.getLineOfOffset(position
+                                                               .getOffset()
+                                                               + position.getLength()))
+                                       return 2;
+                       } catch (BadLocationException x) {
+                       }
+               }
+
+               return 0;
+       }
+
+       /**
+        * Selects a set of markers from the two lists. By default, it just returns
+        * the set of exact matches.
+        */
+       protected List select(List exactMatch, List including) {
+               return exactMatch;
+       }
+
+       /**
+        * Returns one marker which includes the ruler's line of activity.
+        */
+       protected List getJavaAnnotationsForLine(ISourceViewer viewer, int line) {
+
+               IDocument document = viewer.getDocument();
+               IAnnotationModel model = viewer.getAnnotationModel();
+
+               if (model == null)
+                       return null;
+
+               List exact = new ArrayList();
+               List including = new ArrayList();
+
+               Iterator e = model.getAnnotationIterator();
+               HashMap messagesAtPosition = new HashMap();
+               while (e.hasNext()) {
+                       Annotation annotation = (Annotation) e.next();
+
+                       if (annotation.getText() == null)
+                               continue;
+
+                       Position position = model.getPosition(annotation);
+                       if (position == null)
+                               continue;
+
+                       AnnotationPreference preference = getAnnotationPreference(annotation);
+                       if (preference == null)
+                               continue;
+
+                       if (OVERVIEW_RULER_HOVER.equals(fType)) {
+                               String key = preference.getOverviewRulerPreferenceKey();
+                               if (key == null || !fStore.getBoolean(key))
+                                       continue;
+                       } else if (TEXT_RULER_HOVER.equals(fType)) {
+                               String key = preference.getTextPreferenceKey();
+                               if (key != null) {
+                                       if (!fStore.getBoolean(key))
+                                               continue;
+                               } else {
+                                       key = preference.getHighlightPreferenceKey();
+                                       if (key == null || !fStore.getBoolean(key))
+                                               continue;
+                               }
+                       } else if (VERTICAL_RULER_HOVER.equals(fType)) {
+                               String key = preference.getVerticalRulerPreferenceKey();
+                               // backward compatibility
+                               if (key != null && !fStore.getBoolean(key))
+                                       continue;
+                       }
+
+                       if (isDuplicateJavaAnnotation(messagesAtPosition, position,
+                                       annotation.getText()))
+                               continue;
+
+                       switch (compareRulerLine(position, document, line)) {
+                       case 1:
+                               exact.add(annotation);
+                               break;
+                       case 2:
+                               including.add(annotation);
+                               break;
+                       }
+               }
+
+               return select(exact, including);
+       }
+
+       // /**
+       // * Returns one marker which includes the ruler's line of activity.
+       // */
+       // protected List getJavaAnnotationsForLine(ISourceViewer viewer, int line)
+       // {
+       //              
+       // IDocument document= viewer.getDocument();
+       // IAnnotationModel model= viewer.getAnnotationModel();
+       //              
+       // if (model == null)
+       // return null;
+       //                      
+       // List exact= new ArrayList();
+       // List including= new ArrayList();
+       //              
+       // Iterator e= model.getAnnotationIterator();
+       // HashMap messagesAtPosition= new HashMap();
+       // while (e.hasNext()) {
+       // Object o= e.next();
+       // if (o instanceof IJavaAnnotation) {
+       // IJavaAnnotation a= (IJavaAnnotation)o;
+       // if (!a.hasOverlay()) {
+       // Position position= model.getPosition((Annotation)a);
+       // if (position == null)
+       // continue;
+       //
+       // if (isDuplicateJavaAnnotation(messagesAtPosition, position,
+       // a.getMessage()))
+       // continue;
+       //      
+       // switch (compareRulerLine(position, document, line)) {
+       // case 1:
+       // exact.add(a);
+       // break;
+       // case 2:
+       // including.add(a);
+       // break;
+       // }
+       // }
+       // }
+       // }
+       //              
+       // return select(exact, including);
+       // }
+
+       private boolean isDuplicateJavaAnnotation(Map messagesAtPosition,
+                       Position position, String message) {
+               if (messagesAtPosition.containsKey(position)) {
+                       Object value = messagesAtPosition.get(position);
+                       if (message.equals(value))
+                               return true;
+
+                       if (value instanceof List) {
+                               List messages = (List) value;
+                               if (messages.contains(message))
+                                       return true;
+                               else
+                                       messages.add(message);
+                       } else {
+                               ArrayList messages = new ArrayList();
+                               messages.add(value);
+                               messages.add(message);
+                               messagesAtPosition.put(position, messages);
+                       }
+               } else
+                       messagesAtPosition.put(position, message);
+               return false;
+       }
+
+       /*
+        * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
+        */
+       public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+               List javaAnnotations = getJavaAnnotationsForLine(sourceViewer,
+                               lineNumber);
+               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 messages = new ArrayList();
+
+                               Iterator e = javaAnnotations.iterator();
+                               while (e.hasNext()) {
+                                       Annotation annotation = (Annotation) e.next();
+                                       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;
+       }
+
+       /*
+        * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
+        */
+       // public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+       // List javaAnnotations= getJavaAnnotationsForLine(sourceViewer,
+       // lineNumber);
+       // if (javaAnnotations != null) {
+       //                      
+       // if (javaAnnotations.size() == 1) {
+       //                              
+       // // optimization
+       // IJavaAnnotation javaAnnotation= (IJavaAnnotation) javaAnnotations.get(0);
+       // String message= javaAnnotation.getMessage();
+       // if (message != null && message.trim().length() > 0)
+       // return formatSingleMessage(message);
+       //                                      
+       // } else {
+       //                                      
+       // List messages= new ArrayList();
+       //                              
+       // Iterator e= javaAnnotations.iterator();
+       // while (e.hasNext()) {
+       // IJavaAnnotation javaAnnotation= (IJavaAnnotation) e.next();
+       // String message= javaAnnotation.getMessage();
+       // 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.
+        */
+       private String formatSingleMessage(String message) {
+               StringBuffer buffer = new StringBuffer();
+               HTMLPrinter.addPageProlog(buffer);
+               HTMLPrinter.addParagraph(buffer, HTMLPrinter
+                               .convertToHTMLContent(message));
+               HTMLPrinter.addPageEpilog(buffer);
+               return buffer.toString();
+       }
+
+       /*
+        * Formats several message as HTML text.
+        */
+       private String formatMultipleMessages(List messages) {
+               StringBuffer buffer = new StringBuffer();
+               HTMLPrinter.addPageProlog(buffer);
+               HTMLPrinter
+                               .addParagraph(
+                                               buffer,
+                                               HTMLPrinter
+                                                               .convertToHTMLContent(PHPUIMessages
+                                                                               .getString("JavaAnnotationHover.multipleMarkersAtThisLine"))); //$NON-NLS-1$
+
+               HTMLPrinter.startBulletList(buffer);
+               Iterator e = messages.iterator();
+               while (e.hasNext())
+                       HTMLPrinter.addBullet(buffer, HTMLPrinter
+                                       .convertToHTMLContent((String) e.next()));
+               HTMLPrinter.endBulletList(buffer);
+
+               HTMLPrinter.addPageEpilog(buffer);
+               return buffer.toString();
+       }
+
+       /**
+        * Returns the annotation preference for the given annotation.
+        * 
+        * @param annotation
+        *            the annotation
+        * @return the annotation preference or <code>null</code> if none
+        */
+       private AnnotationPreference getAnnotationPreference(Annotation annotation) {
+               return EditorsUI.getAnnotationPreferenceLookup()
+                               .getAnnotationPreference(annotation);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaBreakIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaBreakIterator.java
new file mode 100644 (file)
index 0000000..f80d88a
--- /dev/null
@@ -0,0 +1,444 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.Assert;
+
+/**
+ * A java break iterator. It returns all breaks, including before and after
+ * whitespace, and it returns all camelcase breaks.
+ * <p>
+ * A line break may be any of "\n", "\r", "\r\n", "\n\r".
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class JavaBreakIterator extends BreakIterator {
+
+       /**
+        * A run of common characters.
+        */
+       protected static abstract class Run {
+               /** The length of this run. */
+               protected int length;
+
+               public Run() {
+                       init();
+               }
+
+               /**
+                * Returns <code>true</code> if this run consumes <code>ch</code>,
+                * <code>false</code> otherwise. If <code>true</code> is returned,
+                * the length of the receiver is adjusted accordingly.
+                * 
+                * @param ch
+                *            the character to test
+                * @return <code>true</code> if <code>ch</code> was consumed
+                */
+               protected boolean consume(char ch) {
+                       if (isValid(ch)) {
+                               length++;
+                               return true;
+                       }
+                       return false;
+               }
+
+               /**
+                * Whether this run accepts that character; does not update state.
+                * Called from the default implementation of <code>consume</code>.
+                * 
+                * @param ch
+                *            the character to test
+                * @return <code>true</code> if <code>ch</code> is accepted
+                */
+               protected abstract boolean isValid(char ch);
+
+               /**
+                * Resets this run to the initial state.
+                */
+               protected void init() {
+                       length = 0;
+               }
+       }
+
+       static final class Whitespace extends Run {
+               protected boolean isValid(char ch) {
+                       return Character.isWhitespace(ch) && ch != '\n' && ch != '\r';
+               }
+       }
+
+       static final class LineDelimiter extends Run {
+               /** State: INIT -> delimiter -> EXIT. */
+               private char fState;
+
+               private static final char INIT = '\0';
+
+               private static final char EXIT = '\1';
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaBreakIterator.Run#init()
+                */
+               protected void init() {
+                       super.init();
+                       fState = INIT;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaBreakIterator.Run#consume(char)
+                */
+               protected boolean consume(char ch) {
+                       if (!isValid(ch) || fState == EXIT)
+                               return false;
+
+                       if (fState == INIT) {
+                               fState = ch;
+                               length++;
+                               return true;
+                       } else if (fState != ch) {
+                               fState = EXIT;
+                               length++;
+                               return true;
+                       } else {
+                               return false;
+                       }
+               }
+
+               protected boolean isValid(char ch) {
+                       return ch == '\n' || ch == '\r';
+               }
+       }
+
+       static final class Identifier extends Run {
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaBreakIterator.Run#isValid(char)
+                */
+               protected boolean isValid(char ch) {
+                       return Scanner.isPHPIdentifierPart(ch);
+               }
+       }
+
+       static final class CamelCaseIdentifier extends Run {
+               /* states */
+               private static final int S_INIT = 0;
+
+               private static final int S_LOWER = 1;
+
+               private static final int S_ONE_CAP = 2;
+
+               private static final int S_ALL_CAPS = 3;
+
+               private static final int S_EXIT = 4;
+
+               private static final int S_EXIT_MINUS_ONE = 5;
+
+               /* character types */
+               private static final int K_INVALID = 0;
+
+               private static final int K_LOWER = 1;
+
+               private static final int K_UPPER = 2;
+
+               private static final int K_OTHER = 3;
+
+               private int fState;
+
+               private final static int[][] MATRIX = new int[][] {
+               // K_INVALID, K_LOWER, K_UPPER, K_OTHER
+                               { S_EXIT, S_LOWER, S_ONE_CAP, S_LOWER }, // S_INIT
+                               { S_EXIT, S_LOWER, S_EXIT, S_LOWER }, // S_LOWER
+                               { S_EXIT, S_LOWER, S_ALL_CAPS, S_LOWER }, // S_ONE_CAP
+                               { S_EXIT, S_EXIT_MINUS_ONE, S_ALL_CAPS, S_LOWER }, // S_ALL_CAPS
+               };
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaBreakIterator.Run#init()
+                */
+               protected void init() {
+                       super.init();
+                       fState = S_INIT;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaBreakIterator.Run#consumes(char)
+                */
+               protected boolean consume(char ch) {
+                       int kind = getKind(ch);
+                       fState = MATRIX[fState][kind];
+                       switch (fState) {
+                       case S_LOWER:
+                       case S_ONE_CAP:
+                       case S_ALL_CAPS:
+                               length++;
+                               return true;
+                       case S_EXIT:
+                               return false;
+                       case S_EXIT_MINUS_ONE:
+                               length--;
+                               return false;
+                       default:
+                               Assert.isTrue(false);
+                               return false;
+                       }
+               }
+
+               /**
+                * Determines the kind of a character.
+                * 
+                * @param ch
+                *            the character to test
+                */
+               private int getKind(char ch) {
+                       if (Character.isUpperCase(ch))
+                               return K_UPPER;
+                       if (Character.isLowerCase(ch))
+                               return K_LOWER;
+                       if (Scanner.isPHPIdentifierPart(ch)) // _, digits...
+                               return K_OTHER;
+                       return K_INVALID;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaBreakIterator.Run#isValid(char)
+                */
+               protected boolean isValid(char ch) {
+                       return Scanner.isPHPIdentifierPart(ch);
+               }
+       }
+
+       static final class Other extends Run {
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaBreakIterator.Run#isValid(char)
+                */
+               protected boolean isValid(char ch) {
+                       return !Character.isWhitespace(ch)
+                                       && !Scanner.isPHPIdentifierPart(ch);
+               }
+       }
+
+       private static final Run WHITESPACE = new Whitespace();
+
+       private static final Run DELIMITER = new LineDelimiter();
+
+       private static final Run CAMELCASE = new CamelCaseIdentifier(); // new
+                                                                                                                                       // Identifier();
+
+       private static final Run OTHER = new Other();
+
+       /** The platform break iterator (word instance) used as a base. */
+       protected final BreakIterator fIterator;
+
+       /** The text we operate on. */
+       protected CharSequence fText;
+
+       /** our current position for the stateful methods. */
+       private int fIndex;
+
+       /**
+        * Creates a new break iterator.
+        */
+       public JavaBreakIterator() {
+               fIterator = BreakIterator.getWordInstance();
+               fIndex = fIterator.current();
+       }
+
+       /*
+        * @see java.text.BreakIterator#current()
+        */
+       public int current() {
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#first()
+        */
+       public int first() {
+               fIndex = fIterator.first();
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#following(int)
+        */
+       public int following(int offset) {
+               // work around too eager IAEs in standard impl
+               if (offset == getText().getEndIndex())
+                       return DONE;
+
+               int next = fIterator.following(offset);
+               if (next == DONE)
+                       return DONE;
+
+               // TODO deal with complex script word boundaries
+               // Math.min(offset + run.length, next) does not work
+               // since wordinstance considers _ as boundaries
+               // seems to work fine, however
+               Run run = consumeRun(offset);
+               return offset + run.length;
+
+       }
+
+       /**
+        * Consumes a run of characters at the limits of which we introduce a break.
+        * 
+        * @param offset
+        *            the offset to start at
+        * @return the run that was consumed
+        */
+       private Run consumeRun(int offset) {
+               // assert offset < length
+
+               char ch = fText.charAt(offset);
+               int length = fText.length();
+               Run run = getRun(ch);
+               while (run.consume(ch) && offset < length - 1) {
+                       offset++;
+                       ch = fText.charAt(offset);
+               }
+
+               return run;
+       }
+
+       /**
+        * Retunrs a run based on a character.
+        * 
+        * @param ch
+        *            the character to test
+        * @return the correct character given <code>ch</code>
+        */
+       private Run getRun(char ch) {
+               Run run;
+               if (WHITESPACE.isValid(ch))
+                       run = WHITESPACE;
+               else if (DELIMITER.isValid(ch))
+                       run = DELIMITER;
+               else if (CAMELCASE.isValid(ch))
+                       run = CAMELCASE;
+               else if (OTHER.isValid(ch))
+                       run = OTHER;
+               else {
+                       Assert.isTrue(false);
+                       return null;
+               }
+
+               run.init();
+               return run;
+       }
+
+       /*
+        * @see java.text.BreakIterator#getText()
+        */
+       public CharacterIterator getText() {
+               return fIterator.getText();
+       }
+
+       /*
+        * @see java.text.BreakIterator#isBoundary(int)
+        */
+       public boolean isBoundary(int offset) {
+               if (offset == getText().getBeginIndex())
+                       return true;
+               else
+                       return following(offset - 1) == offset;
+       }
+
+       /*
+        * @see java.text.BreakIterator#last()
+        */
+       public int last() {
+               fIndex = fIterator.last();
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#next()
+        */
+       public int next() {
+               fIndex = following(fIndex);
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#next(int)
+        */
+       public int next(int n) {
+               return fIterator.next(n);
+       }
+
+       /*
+        * @see java.text.BreakIterator#preceding(int)
+        */
+       public int preceding(int offset) {
+               if (offset == getText().getBeginIndex())
+                       return DONE;
+
+               if (isBoundary(offset - 1))
+                       return offset - 1;
+
+               int previous = offset - 1;
+               do {
+                       previous = fIterator.preceding(previous);
+               } while (!isBoundary(previous));
+
+               int last = DONE;
+               while (previous < offset) {
+                       last = previous;
+                       previous = following(previous);
+               }
+
+               return last;
+       }
+
+       /*
+        * @see java.text.BreakIterator#previous()
+        */
+       public int previous() {
+               fIndex = preceding(fIndex);
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#setText(java.lang.String)
+        */
+       public void setText(String newText) {
+               setText((CharSequence) newText);
+       }
+
+       /**
+        * Creates a break iterator given a char sequence.
+        * 
+        * @param newText
+        *            the new text
+        */
+       public void setText(CharSequence newText) {
+               fText = newText;
+               fIterator.setText(new SequenceCharacterIterator(newText));
+               first();
+       }
+
+       /*
+        * @see java.text.BreakIterator#setText(java.text.CharacterIterator)
+        */
+       public void setText(CharacterIterator newText) {
+               if (newText instanceof CharSequence) {
+                       fText = (CharSequence) newText;
+                       fIterator.setText(newText);
+                       first();
+               } else {
+                       throw new UnsupportedOperationException(
+                                       "CharacterIterator not supported"); //$NON-NLS-1$
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaColorManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaColorManager.java
new file mode 100644 (file)
index 0000000..7578353
--- /dev/null
@@ -0,0 +1,137 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpdt.ui.text.IColorManagerExtension;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Java color manager.
+ */
+public class JavaColorManager implements IColorManager, IColorManagerExtension {
+       protected Map fKeyTable = new HashMap(10);
+
+       protected Map fDisplayTable = new HashMap(2);
+
+       /**
+        * Flag which tells if the colors are automatically disposed when the
+        * current display gets disposed.
+        */
+       private boolean fAutoDisposeOnDisplayDispose;
+
+       /**
+        * Creates a new Java color manager which automatically disposes the
+        * allocated colors when the current display gets disposed.
+        */
+       public JavaColorManager() {
+               this(true);
+       }
+
+       /**
+        * Creates a new Java color manager.
+        * 
+        * @param autoDisposeOnDisplayDispose
+        *            if <code>true</code> the color manager automatically
+        *            disposes all managed colors when the current display gets
+        *            disposed and all calls to
+        *            {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()}
+        *            are ignored.
+        * 
+        * @since 2.1
+        */
+       public JavaColorManager(boolean autoDisposeOnDisplayDispose) {
+               fAutoDisposeOnDisplayDispose = autoDisposeOnDisplayDispose;
+       }
+
+       public void dispose(Display display) {
+               Map colorTable = (Map) fDisplayTable.get(display);
+               if (colorTable != null) {
+                       Iterator e = colorTable.values().iterator();
+                       while (e.hasNext()) {
+                               Color color = (Color) e.next();
+                               if (color != null && !color.isDisposed())
+                                       color.dispose();
+                       }
+               }
+       }
+
+       /*
+        * @see IColorManager#getColor(RGB)
+        */
+       public Color getColor(RGB rgb) {
+
+               if (rgb == null)
+                       return null;
+
+               final Display display = Display.getCurrent();
+               Map colorTable = (Map) fDisplayTable.get(display);
+               if (colorTable == null) {
+                       colorTable = new HashMap(10);
+                       fDisplayTable.put(display, colorTable);
+                       if (fAutoDisposeOnDisplayDispose) {
+                               display.disposeExec(new Runnable() {
+                                       public void run() {
+                                               dispose(display);
+                                       }
+                               });
+                       }
+               }
+
+               Color color = (Color) colorTable.get(rgb);
+               if (color == null) {
+                       color = new Color(Display.getCurrent(), rgb);
+                       colorTable.put(rgb, color);
+               }
+
+               return color;
+       }
+
+       /*
+        * @see IColorManager#dispose
+        */
+       public void dispose() {
+               if (!fAutoDisposeOnDisplayDispose)
+                       dispose(Display.getCurrent());
+       }
+
+       /*
+        * @see IColorManager#getColor(String)
+        */
+       public Color getColor(String key) {
+
+               if (key == null)
+                       return null;
+
+               RGB rgb = (RGB) fKeyTable.get(key);
+               return getColor(rgb);
+       }
+
+       /*
+        * @see IColorManagerExtension#bindColor(String, RGB)
+        */
+       public void bindColor(String key, RGB rgb) {
+               Object value = fKeyTable.get(key);
+               if (value != null)
+                       throw new UnsupportedOperationException();
+
+               fKeyTable.put(key, rgb);
+       }
+
+       /*
+        * @see IColorManagerExtension#unbindColor(String)
+        */
+       public void unbindColor(String key) {
+               fKeyTable.remove(key);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaCompositeReconcilingStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaCompositeReconcilingStrategy.java
new file mode 100644 (file)
index 0000000..77423a6
--- /dev/null
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.internal.ui.text.java.IProblemRequestorExtension;
+import net.sourceforge.phpdt.internal.ui.text.java.JavaReconcilingStrategy;
+import net.sourceforge.phpdt.internal.ui.text.spelling.SpellReconcileStrategy;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Reconciling strategy for Java code. This is a composite strategy containing
+ * the regular java model reconciler and the comment spell checking strategy.
+ * 
+ * @since 3.0
+ */
+public class JavaCompositeReconcilingStrategy extends
+               CompositeReconcilingStrategy {
+
+       private ITextEditor fEditor;
+
+       private JavaReconcilingStrategy fJavaStrategy;
+
+       /**
+        * Creates a new Java reconciling strategy.
+        * 
+        * @param editor
+        *            the editor of the strategy's reconciler
+        * @param documentPartitioning
+        *            the document partitioning this strategy uses for configuration
+        */
+       public JavaCompositeReconcilingStrategy(ITextEditor editor,
+                       String documentPartitioning) {
+               fEditor = editor;
+               fJavaStrategy = new JavaReconcilingStrategy(editor);
+               setReconcilingStrategies(new IReconcilingStrategy[] {
+                               fJavaStrategy,
+                               new SpellReconcileStrategy(editor, documentPartitioning,
+                                               PreferenceConstants.getPreferenceStore()) });
+       }
+
+       /**
+        * Returns the problem requestor for the editor's input element.
+        * 
+        * @return the problem requestor for the editor's input element
+        */
+       private IProblemRequestorExtension getProblemRequestorExtension() {
+               IDocumentProvider p = fEditor.getDocumentProvider();
+               if (p == null) {
+                       try {
+                               // work around for
+                               // https://bugs.eclipse.org/bugs/show_bug.cgi?id=51522
+                               p = WebUI.getDefault()
+                                               .getCompilationUnitDocumentProvider();
+                       } catch (NullPointerException npe) {
+                               return null;
+                       }
+               }
+               IAnnotationModel m = p.getAnnotationModel(fEditor.getEditorInput());
+               if (m instanceof IProblemRequestorExtension)
+                       return (IProblemRequestorExtension) m;
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.CompositeReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion,
+        *      org.eclipse.jface.text.IRegion)
+        */
+       public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+               IProblemRequestorExtension e = getProblemRequestorExtension();
+               if (e != null) {
+                       try {
+                               e.beginReportingSequence();
+                               super.reconcile(dirtyRegion, subRegion);
+                       } finally {
+                               e.endReportingSequence();
+                       }
+               } else {
+                       super.reconcile(dirtyRegion, subRegion);
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.CompositeReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
+        */
+       public void reconcile(IRegion partition) {
+               IProblemRequestorExtension e = getProblemRequestorExtension();
+               if (e != null) {
+                       try {
+                               e.beginReportingSequence();
+                               super.reconcile(partition);
+                       } finally {
+                               e.endReportingSequence();
+                       }
+               } else {
+                       super.reconcile(partition);
+               }
+       }
+
+       /**
+        * Tells this strategy whether to inform its listeners.
+        * 
+        * @param notify
+        *            <code>true</code> if listeners should be notified
+        */
+       public void notifyListeners(boolean notify) {
+               fJavaStrategy.notifyListeners(notify);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.CompositeReconcilingStrategy#initialReconcile()
+        */
+       public void initialReconcile() {
+               IProblemRequestorExtension e = getProblemRequestorExtension();
+               if (e != null) {
+                       try {
+                               e.beginReportingSequence();
+                               super.initialReconcile();
+                       } finally {
+                               e.endReportingSequence();
+                       }
+               } else {
+                       super.initialReconcile();
+               }
+       }
+
+       /**
+        * Called before reconciling is started.
+        * 
+        * @since 3.0
+        */
+       public void aboutToBeReconciled() {
+               fJavaStrategy.aboutToBeReconciled();
+
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaElementProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaElementProvider.java
new file mode 100644 (file)
index 0000000..db4ef87
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.information.IInformationProvider;
+import org.eclipse.jface.text.information.IInformationProviderExtension;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Provides a Java element to be displayed in by an information presenter.
+ */
+public class JavaElementProvider implements IInformationProvider,
+               IInformationProviderExtension {
+
+       private PHPEditor fEditor;
+
+       private boolean fUseCodeResolve;
+
+       public JavaElementProvider(IEditorPart editor) {
+               fUseCodeResolve = false;
+               if (editor instanceof PHPEditor)
+                       fEditor = (PHPEditor) editor;
+       }
+
+       public JavaElementProvider(IEditorPart editor, boolean useCodeResolve) {
+               this(editor);
+               fUseCodeResolve = useCodeResolve;
+       }
+
+       /*
+        * @see IInformationProvider#getSubject(ITextViewer, int)
+        */
+       public IRegion getSubject(ITextViewer textViewer, int offset) {
+               if (textViewer != null && fEditor != null) {
+                       IRegion region = JavaWordFinder.findWord(textViewer.getDocument(),
+                                       offset);
+                       if (region != null)
+                               return region;
+                       else
+                               return new Region(offset, 0);
+               }
+               return null;
+       }
+
+       /*
+        * @see IInformationProvider#getInformation(ITextViewer, IRegion)
+        */
+       public String getInformation(ITextViewer textViewer, IRegion subject) {
+               return getInformation2(textViewer, subject).toString();
+       }
+
+       /*
+        * @see IInformationProviderExtension#getElement(ITextViewer, IRegion)
+        */
+       public Object getInformation2(ITextViewer textViewer, IRegion subject) {
+               if (fEditor == null)
+                       return null;
+
+               try {
+                       if (fUseCodeResolve) {
+                               IStructuredSelection sel = SelectionConverter
+                                               .getStructuredSelection(fEditor);
+                               if (!sel.isEmpty())
+                                       return sel.getFirstElement();
+                       }
+                       IJavaElement element = SelectionConverter
+                                       .getElementAtOffset(fEditor);
+                       if (element != null)
+                               return element;
+                       return SelectionConverter.getInput(fEditor);
+               } catch (JavaModelException e) {
+                       return null;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaHeuristicScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaHeuristicScanner.java
new file mode 100644 (file)
index 0000000..0ca33ab
--- /dev/null
@@ -0,0 +1,1030 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.Arrays;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextUtilities;
+
+/**
+ * Utility methods for heuristic based Java manipulations in an incomplete Java
+ * source file.
+ * 
+ * <p>
+ * An instance holds some internal position in the document and is therefore not
+ * threadsafe.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class JavaHeuristicScanner implements Symbols {
+       /**
+        * Returned by all methods when the requested position could not be found,
+        * or if a {@link BadLocationException} was thrown while scanning.
+        */
+       public static final int NOT_FOUND = -1;
+
+       /**
+        * Special bound parameter that means either -1 (backward scanning) or
+        * <code>fDocument.getLength()</code> (forward scanning).
+        */
+       public static final int UNBOUND = -2;
+
+       /* character constants */
+       private static final char LBRACE = '{';
+
+       private static final char RBRACE = '}';
+
+       private static final char LPAREN = '(';
+
+       private static final char RPAREN = ')';
+
+       private static final char SEMICOLON = ';';
+
+       private static final char COLON = ':';
+
+       private static final char COMMA = ',';
+
+       private static final char LBRACKET = '[';
+
+       private static final char RBRACKET = ']';
+
+       private static final char QUESTIONMARK = '?';
+
+       private static final char EQUAL = '=';
+
+       /**
+        * Specifies the stop condition, upon which the <code>scanXXX</code>
+        * methods will decide whether to keep scanning or not. This interface may
+        * implemented by clients.
+        */
+       public interface StopCondition {
+               /**
+                * Instructs the scanner to return the current position.
+                * 
+                * @param ch
+                *            the char at the current position
+                * @param position
+                *            the current position
+                * @param forward
+                *            the iteration direction
+                * @return <code>true</code> if the stop condition is met.
+                */
+               boolean stop(char ch, int position, boolean forward);
+       }
+
+       /**
+        * Stops upon a non-whitespace (as defined by
+        * {@link Character#isWhitespace(char)}) character.
+        */
+       private static class NonWhitespace implements StopCondition {
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
+                */
+               public boolean stop(char ch, int position, boolean forward) {
+                       return !Character.isWhitespace(ch);
+               }
+       }
+
+       /**
+        * Stops upon a non-whitespace character in the default partition.
+        * 
+        * @see NonWhitespace
+        */
+       private class NonWhitespaceDefaultPartition extends NonWhitespace {
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
+                */
+               public boolean stop(char ch, int position, boolean forward) {
+                       return super.stop(ch, position, true)
+                                       && isDefaultPartition(position);
+               }
+       }
+
+       /**
+        * Stops upon a non-java identifier (as defined by
+        * {@link Scanner#isPHPIdentifierPart(char)}) character.
+        */
+       private static class NonJavaIdentifierPart implements StopCondition {
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
+                */
+               public boolean stop(char ch, int position, boolean forward) {
+                       return !Scanner.isPHPIdentifierPart(ch);
+               }
+       }
+
+       /**
+        * Stops upon a non-java identifier character in the default partition.
+        * 
+        * @see NonJavaIdentifierPart
+        */
+       private class NonJavaIdentifierPartDefaultPartition extends
+                       NonJavaIdentifierPart {
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
+                */
+               public boolean stop(char ch, int position, boolean forward) {
+                       return super.stop(ch, position, true)
+                                       || !isDefaultPartition(position);
+               }
+       }
+
+       /**
+        * Stops upon a character in the default partition that matches the given
+        * character list.
+        */
+       private class CharacterMatch implements StopCondition {
+               private final char[] fChars;
+
+               /**
+                * Creates a new instance.
+                * 
+                * @param ch
+                *            the single character to match
+                */
+               public CharacterMatch(char ch) {
+                       this(new char[] { ch });
+               }
+
+               /**
+                * Creates a new instance.
+                * 
+                * @param chars
+                *            the chars to match.
+                */
+               public CharacterMatch(char[] chars) {
+                       Assert.isNotNull(chars);
+                       Assert.isTrue(chars.length > 0);
+                       fChars = chars;
+                       Arrays.sort(chars);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char,
+                *      int)
+                */
+               public boolean stop(char ch, int position, boolean forward) {
+                       return Arrays.binarySearch(fChars, ch) >= 0
+                                       && isDefaultPartition(position);
+               }
+       }
+
+       /**
+        * Acts like character match, but skips all scopes introduced by
+        * parenthesis, brackets, and braces.
+        */
+       protected class SkippingScopeMatch extends CharacterMatch {
+               private char fOpening, fClosing;
+
+               private int fDepth = 0;
+
+               /**
+                * Creates a new instance.
+                * 
+                * @param ch
+                *            the single character to match
+                */
+               public SkippingScopeMatch(char ch) {
+                       super(ch);
+               }
+
+               /**
+                * Creates a new instance.
+                * 
+                * @param chars
+                *            the chars to match.
+                */
+               public SkippingScopeMatch(char[] chars) {
+                       super(chars);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char,
+                *      int)
+                */
+               public boolean stop(char ch, int position, boolean forward) {
+
+                       if (fDepth == 0 && super.stop(ch, position, true))
+                               return true;
+                       else if (ch == fOpening)
+                               fDepth++;
+                       else if (ch == fClosing) {
+                               fDepth--;
+                               if (fDepth == 0) {
+                                       fOpening = 0;
+                                       fClosing = 0;
+                               }
+                       } else if (fDepth == 0) {
+                               fDepth = 1;
+                               if (forward) {
+
+                                       switch (ch) {
+                                       case LBRACE:
+                                               fOpening = LBRACE;
+                                               fClosing = RBRACE;
+                                               break;
+                                       case LPAREN:
+                                               fOpening = LPAREN;
+                                               fClosing = RPAREN;
+                                               break;
+                                       case LBRACKET:
+                                               fOpening = LBRACKET;
+                                               fClosing = RBRACKET;
+                                               break;
+                                       }
+
+                               } else {
+                                       switch (ch) {
+                                       case RBRACE:
+                                               fOpening = RBRACE;
+                                               fClosing = LBRACE;
+                                               break;
+                                       case RPAREN:
+                                               fOpening = RPAREN;
+                                               fClosing = LPAREN;
+                                               break;
+                                       case RBRACKET:
+                                               fOpening = RBRACKET;
+                                               fClosing = LBRACKET;
+                                               break;
+                                       }
+
+                               }
+                       }
+
+                       return false;
+
+               }
+
+       }
+
+       /** The document being scanned. */
+       private IDocument fDocument;
+
+       /** The partitioning being used for scanning. */
+       private String fPartitioning;
+
+       /** The partition to scan in. */
+       private String fPartition;
+
+       /* internal scan state */
+
+       /** the most recently read character. */
+       private char fChar;
+
+       /** the most recently read position. */
+       private int fPos;
+
+       /* preset stop conditions */
+       private final StopCondition fNonWSDefaultPart = new NonWhitespaceDefaultPartition();
+
+       private final static StopCondition fNonWS = new NonWhitespace();
+
+       private final StopCondition fNonIdent = new NonJavaIdentifierPartDefaultPartition();
+
+       /**
+        * Creates a new instance.
+        * 
+        * @param document
+        *            the document to scan
+        * @param partitioning
+        *            the partitioning to use for scanning
+        * @param partition
+        *            the partition to scan in
+        */
+       public JavaHeuristicScanner(IDocument document, String partitioning,
+                       String partition) {
+               Assert.isNotNull(document);
+               Assert.isNotNull(partitioning);
+               Assert.isNotNull(partition);
+               fDocument = document;
+               fPartitioning = partitioning;
+               fPartition = partition;
+       }
+
+       /**
+        * Calls
+        * <code>this(document, IJavaPartitions.JAVA_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE)</code>.
+        * 
+        * @param document
+        *            the document to scan.
+        */
+       public JavaHeuristicScanner(IDocument document) {
+//             this(document, IPHPPartitions.PHP_PARTITIONING,
+//                             IDocument.DEFAULT_CONTENT_TYPE);
+               this(document, IPHPPartitions.PHP_PARTITIONING,
+                               PHPDocumentPartitioner.PHP_SCRIPT_CODE);
+       }
+
+       /**
+        * Returns the most recent internal scan position.
+        * 
+        * @return the most recent internal scan position.
+        */
+       public int getPosition() {
+               return fPos;
+       }
+
+       /**
+        * Returns the next token in forward direction, starting at
+        * <code>start</code>, and not extending further than <code>bound</code>.
+        * The return value is one of the constants defined in {@link Symbols}.
+        * After a call, {@link #getPosition()} will return the position just after
+        * the scanned token (i.e. the next position that will be scanned).
+        * 
+        * @param start
+        *            the first character position in the document to consider
+        * @param bound
+        *            the first position not to consider any more
+        * @return a constant from {@link Symbols} describing the next token
+        */
+       public int nextToken(int start, int bound) {
+               int pos = scanForward(start, bound, fNonWSDefaultPart);
+               if (pos == NOT_FOUND)
+                       return TokenEOF;
+
+               fPos++;
+
+               switch (fChar) {
+               case LBRACE:
+                       return TokenLBRACE;
+               case RBRACE:
+                       return TokenRBRACE;
+               case LBRACKET:
+                       return TokenLBRACKET;
+               case RBRACKET:
+                       return TokenRBRACKET;
+               case LPAREN:
+                       return TokenLPAREN;
+               case RPAREN:
+                       return TokenRPAREN;
+               case SEMICOLON:
+                       return TokenSEMICOLON;
+               case COMMA:
+                       return TokenCOMMA;
+               case QUESTIONMARK:
+                       return TokenQUESTIONMARK;
+               case EQUAL:
+                       try {
+                               if (fDocument.getChar(fPos) == '>') {
+                                       fPos++;
+                                       return TokenOTHER;
+                               }
+                       } catch (BadLocationException e) {
+                       }
+                       return TokenEQUAL;
+               case '<':
+                       try {
+                               if (fDocument.get(fPos, 4).equalsIgnoreCase("?php")) {
+                                       fPos += 4;
+                                       return TokenEOF;
+                               } else if (fDocument.getChar(fPos) == '?') {
+                                       fPos++;
+                                       return TokenEOF;
+                               }
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               // else
+               if (Scanner.isPHPIdentifierPart(fChar)) {
+                       // assume an ident or keyword
+                       int from = pos, to;
+                       pos = scanForward(pos + 1, bound, fNonIdent);
+                       if (pos == NOT_FOUND)
+                               to = bound == UNBOUND ? fDocument.getLength() : bound;
+                       else
+                               to = pos;
+
+                       String identOrKeyword;
+                       try {
+                               identOrKeyword = fDocument.get(from, to - from);
+                       } catch (BadLocationException e) {
+                               return TokenEOF;
+                       }
+
+                       return getToken(identOrKeyword);
+
+               } else {
+                       // operators, number literals etc
+                       return TokenOTHER;
+               }
+       }
+
+       /**
+        * Returns the next token in backward direction, starting at
+        * <code>start</code>, and not extending further than <code>bound</code>.
+        * The return value is one of the constants defined in {@link Symbols}.
+        * After a call, {@link #getPosition()} will return the position just before
+        * the scanned token starts (i.e. the next position that will be scanned).
+        * 
+        * @param start
+        *            the first character position in the document to consider
+        * @param bound
+        *            the first position not to consider any more
+        * @return a constant from {@link Symbols} describing the previous token
+        */
+       public int previousToken(int start, int bound) {
+               int pos = scanBackward(start, bound, fNonWSDefaultPart);
+               if (pos == NOT_FOUND)
+                       return TokenEOF;
+
+               fPos--;
+
+               switch (fChar) {
+               case LBRACE:
+                       return TokenLBRACE;
+               case RBRACE:
+                       return TokenRBRACE;
+               case LBRACKET:
+                       return TokenLBRACKET;
+               case RBRACKET:
+                       return TokenRBRACKET;
+               case LPAREN:
+                       return TokenLPAREN;
+               case RPAREN:
+                       return TokenRPAREN;
+               case SEMICOLON:
+                       return TokenSEMICOLON;
+               case COLON:
+                       return TokenCOLON;
+               case COMMA:
+                       return TokenCOMMA;
+               case QUESTIONMARK:
+                       return TokenQUESTIONMARK;
+               case EQUAL:
+                       return TokenEQUAL;
+               case '>':
+                       try {
+                               switch (fDocument.getChar(fPos)) {
+                               case '=':
+                                       fPos--;
+                                       return TokenOTHER;
+                               case '?':
+                                       fPos--;
+                                       return TokenEOF;
+                               }
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               // else
+               if (Scanner.isPHPIdentifierPart(fChar)) {
+                       // assume an ident or keyword
+                       int from, to = pos + 1;
+                       pos = scanBackward(pos - 1, bound, fNonIdent);
+                       if (pos == NOT_FOUND)
+                               from = bound == UNBOUND ? 0 : bound + 1;
+                       else
+                               from = pos + 1;
+
+                       String identOrKeyword;
+                       try {
+                               identOrKeyword = fDocument.get(from, to - from);
+                       } catch (BadLocationException e) {
+                               return TokenEOF;
+                       }
+
+                       return getToken(identOrKeyword);
+
+               } else {
+                       // operators, number literals etc
+                       return TokenOTHER;
+               }
+
+       }
+
+       /**
+        * Returns one of the keyword constants or <code>TokenIDENT</code> for a
+        * scanned identifier.
+        * 
+        * @param s
+        *            a scanned identifier
+        * @return one of the constants defined in {@link Symbols}
+        */
+       private int getToken(String s) {
+               Assert.isNotNull(s);
+
+               switch (s.length()) {
+               case 2:
+                       if ("if".equals(s)) //$NON-NLS-1$
+                               return TokenIF;
+                       if ("do".equals(s)) //$NON-NLS-1$
+                               return TokenDO;
+                       break;
+               case 3:
+                       if ("for".equals(s)) //$NON-NLS-1$
+                               return TokenFOR;
+                       if ("try".equals(s)) //$NON-NLS-1$
+                               return TokenTRY;
+                       if ("new".equals(s)) //$NON-NLS-1$
+                               return TokenNEW;
+                       break;
+               case 4:
+                       if ("case".equals(s)) //$NON-NLS-1$
+                               return TokenCASE;
+                       if ("else".equals(s)) //$NON-NLS-1$
+                               return TokenELSE;
+                       if ("goto".equals(s)) //$NON-NLS-1$
+                               return TokenGOTO;
+                       break;
+               case 5:
+                       if ("break".equals(s)) //$NON-NLS-1$
+                               return TokenBREAK;
+                       if ("catch".equals(s)) //$NON-NLS-1$
+                               return TokenCATCH;
+                       if ("while".equals(s)) //$NON-NLS-1$
+                               return TokenWHILE;
+                       break;
+               case 6:
+                       if ("return".equals(s)) //$NON-NLS-1$
+                               return TokenRETURN;
+                       if ("static".equals(s)) //$NON-NLS-1$
+                               return TokenSTATIC;
+                       if ("switch".equals(s)) //$NON-NLS-1$
+                               return TokenSWITCH;
+                       break;
+               case 7:
+                       if ("default".equals(s)) //$NON-NLS-1$
+                               return TokenDEFAULT;
+                       if ("finally".equals(s)) //$NON-NLS-1$
+                               return TokenFINALLY;
+                       break;
+               case 12:
+                       if ("synchronized".equals(s)) //$NON-NLS-1$
+                               return TokenSYNCHRONIZED;
+                       break;
+               }
+               return TokenIDENT;
+       }
+
+       /**
+        * Returns the position of the closing peer character (forward search). Any
+        * scopes introduced by opening peers are skipped. All peers accounted for
+        * must reside in the default partition.
+        * 
+        * <p>
+        * Note that <code>start</code> must not point to the opening peer, but to
+        * the first character being searched.
+        * </p>
+        * 
+        * @param start
+        *            the start position
+        * @param openingPeer
+        *            the opening peer character (e.g. '{')
+        * @param closingPeer
+        *            the closing peer character (e.g. '}')
+        * @return the matching peer character position, or <code>NOT_FOUND</code>
+        */
+       public int findClosingPeer(int start, final char openingPeer,
+                       final char closingPeer) {
+               Assert.isNotNull(fDocument);
+               Assert.isTrue(start >= 0);
+
+               try {
+                       int depth = 1;
+                       start -= 1;
+                       while (true) {
+                               start = scanForward(start + 1, UNBOUND, new CharacterMatch(
+                                               new char[] { openingPeer, closingPeer }));
+                               if (start == NOT_FOUND)
+                                       return NOT_FOUND;
+
+                               if (fDocument.getChar(start) == openingPeer)
+                                       depth++;
+                               else
+                                       depth--;
+
+                               if (depth == 0)
+                                       return start;
+                       }
+
+               } catch (BadLocationException e) {
+                       return NOT_FOUND;
+               }
+       }
+
+       /**
+        * Returns the position of the opening peer character (backward search). Any
+        * scopes introduced by closing peers are skipped. All peers accounted for
+        * must reside in the default partition.
+        * 
+        * <p>
+        * Note that <code>start</code> must not point to the closing peer, but to
+        * the first character being searched.
+        * </p>
+        * 
+        * @param start
+        *            the start position
+        * @param openingPeer
+        *            the opening peer character (e.g. '{')
+        * @param closingPeer
+        *            the closing peer character (e.g. '}')
+        * @return the matching peer character position, or <code>NOT_FOUND</code>
+        */
+       public int findOpeningPeer(int start, char openingPeer, char closingPeer) {
+               Assert.isTrue(start < fDocument.getLength());
+
+               try {
+                       int depth = 1;
+                       start += 1;
+                       while (true) {
+                               start = scanBackward(start - 1, UNBOUND, new CharacterMatch(
+                                               new char[] { openingPeer, closingPeer }));
+                               if (start == NOT_FOUND)
+                                       return NOT_FOUND;
+
+                               if (fDocument.getChar(start) == closingPeer)
+                                       depth++;
+                               else
+                                       depth--;
+
+                               if (depth == 0)
+                                       return start;
+                       }
+
+               } catch (BadLocationException e) {
+                       return NOT_FOUND;
+               }
+       }
+
+       /**
+        * Computes the surrounding block around <code>offset</code>. The search
+        * is started at the beginning of <code>offset</code>, i.e. an opening
+        * brace at <code>offset</code> will not be part of the surrounding block,
+        * but a closing brace will.
+        * 
+        * @param offset
+        *            the offset for which the surrounding block is computed
+        * @return a region describing the surrounding block, or <code>null</code>
+        *         if none can be found
+        */
+       public IRegion findSurroundingBlock(int offset) {
+               if (offset < 1 || offset >= fDocument.getLength())
+                       return null;
+
+               int begin = findOpeningPeer(offset - 1, LBRACE, RBRACE);
+               int end = findClosingPeer(offset, LBRACE, RBRACE);
+               if (begin == NOT_FOUND || end == NOT_FOUND)
+                       return null;
+               return new Region(begin, end + 1 - begin);
+       }
+
+       /**
+        * Finds the smallest position in <code>fDocument</code> such that the
+        * position is &gt;= <code>position</code> and &lt; <code>bound</code>
+        * and <code>Character.isWhitespace(fDocument.getChar(pos))</code>
+        * evaluates to <code>false</code> and the position is in the default
+        * partition.
+        * 
+        * @param position
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &gt; <code>position</code>,
+        *            or <code>UNBOUND</code>
+        * @return the smallest position of a non-whitespace character in [<code>position</code>,
+        *         <code>bound</code>) that resides in a Java partition, or
+        *         <code>NOT_FOUND</code> if none can be found
+        */
+       public int findNonWhitespaceForward(int position, int bound) {
+               return scanForward(position, bound, fNonWSDefaultPart);
+       }
+
+       /**
+        * Finds the smallest position in <code>fDocument</code> such that the
+        * position is &gt;= <code>position</code> and &lt; <code>bound</code>
+        * and <code>Character.isWhitespace(fDocument.getChar(pos))</code>
+        * evaluates to <code>false</code>.
+        * 
+        * @param position
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &gt; <code>position</code>,
+        *            or <code>UNBOUND</code>
+        * @return the smallest position of a non-whitespace character in [<code>position</code>,
+        *         <code>bound</code>), or <code>NOT_FOUND</code> if none can
+        *         be found
+        */
+       public int findNonWhitespaceForwardInAnyPartition(int position, int bound) {
+               return scanForward(position, bound, fNonWS);
+       }
+
+       /**
+        * Finds the highest position in <code>fDocument</code> such that the
+        * position is &lt;= <code>position</code> and &gt; <code>bound</code>
+        * and <code>Character.isWhitespace(fDocument.getChar(pos))</code>
+        * evaluates to <code>false</code> and the position is in the default
+        * partition.
+        * 
+        * @param position
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &lt; <code>position</code>,
+        *            or <code>UNBOUND</code>
+        * @return the highest position of a non-whitespace character in (<code>bound</code>,
+        *         <code>position</code>] that resides in a Java partition, or
+        *         <code>NOT_FOUND</code> if none can be found
+        */
+       public int findNonWhitespaceBackward(int position, int bound) {
+               return scanBackward(position, bound, fNonWSDefaultPart);
+       }
+
+       /**
+        * Finds the lowest position <code>p</code> in <code>fDocument</code>
+        * such that <code>start</code> &lt;= p &lt; <code>bound</code> and
+        * <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to
+        * <code>true</code>.
+        * 
+        * @param start
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &gt; <code>start</code>,
+        *            or <code>UNBOUND</code>
+        * @param condition
+        *            the <code>StopCondition</code> to check
+        * @return the lowest position in [<code>start</code>,
+        *         <code>bound</code>) for which <code>condition</code> holds,
+        *         or <code>NOT_FOUND</code> if none can be found
+        */
+       public int scanForward(int start, int bound, StopCondition condition) {
+               Assert.isTrue(start >= 0);
+
+               if (bound == UNBOUND)
+                       bound = fDocument.getLength();
+
+               Assert.isTrue(bound <= fDocument.getLength());
+
+               try {
+                       fPos = start;
+                       while (fPos < bound) {
+
+                               fChar = fDocument.getChar(fPos);
+                               // omit closing tag
+                               if (fChar == '?') {
+                                       if (fPos < fDocument.getLength() - 1) {
+                                               if (fDocument.get(fPos - 1, 2).equalsIgnoreCase("?>")) {
+                                                       fPos++;
+                                                       return NOT_FOUND;
+                                               }
+                                       }
+                               }
+                               if (condition.stop(fChar, fPos, true))
+                                       return fPos;
+
+                               fPos++;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return NOT_FOUND;
+       }
+
+       /**
+        * Finds the lowest position in <code>fDocument</code> such that the
+        * position is &gt;= <code>position</code> and &lt; <code>bound</code>
+        * and <code>fDocument.getChar(position) == ch</code> evaluates to
+        * <code>true</code> and the position is in the default partition.
+        * 
+        * @param position
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &gt; <code>position</code>,
+        *            or <code>UNBOUND</code>
+        * @param ch
+        *            the <code>char</code> to search for
+        * @return the lowest position of <code>ch</code> in (<code>bound</code>,
+        *         <code>position</code>] that resides in a Java partition, or
+        *         <code>NOT_FOUND</code> if none can be found
+        */
+       public int scanForward(int position, int bound, char ch) {
+               return scanForward(position, bound, new CharacterMatch(ch));
+       }
+
+       /**
+        * Finds the lowest position in <code>fDocument</code> such that the
+        * position is &gt;= <code>position</code> and &lt; <code>bound</code>
+        * and <code>fDocument.getChar(position) == ch</code> evaluates to
+        * <code>true</code> for at least one ch in <code>chars</code> and the
+        * position is in the default partition.
+        * 
+        * @param position
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &gt; <code>position</code>,
+        *            or <code>UNBOUND</code>
+        * @param chars
+        *            an array of <code>char</code> to search for
+        * @return the lowest position of a non-whitespace character in [<code>position</code>,
+        *         <code>bound</code>) that resides in a Java partition, or
+        *         <code>NOT_FOUND</code> if none can be found
+        */
+       public int scanForward(int position, int bound, char[] chars) {
+               return scanForward(position, bound, new CharacterMatch(chars));
+       }
+
+       /**
+        * Finds the highest position <code>p</code> in <code>fDocument</code>
+        * such that <code>bound</code> &lt; <code>p</code> &lt;=
+        * <code>start</code> and
+        * <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to
+        * <code>true</code>.
+        * 
+        * @param start
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &lt; <code>start</code>,
+        *            or <code>UNBOUND</code>
+        * @param condition
+        *            the <code>StopCondition</code> to check
+        * @return the highest position in (<code>bound</code>,
+        *         <code>start</code> for which <code>condition</code> holds, or
+        *         <code>NOT_FOUND</code> if none can be found
+        */
+       public int scanBackward(int start, int bound, StopCondition condition) {
+               if (bound == UNBOUND)
+                       bound = -1;
+
+               Assert.isTrue(bound >= -1);
+               Assert.isTrue(start < fDocument.getLength());
+
+               try {
+                       fPos = start;
+                       while (fPos > bound) {
+
+                               fChar = fDocument.getChar(fPos);
+                               // omit opening tag
+                               if (fChar == 'p' || fChar == 'P') {
+                                       if (fPos >= 4) {
+                                               if (fDocument.get(fPos - 4, 5).equalsIgnoreCase("<?php")) {
+                                                       fPos -= 4;
+                                                       return NOT_FOUND;
+                                               }
+                                       }
+                               } else if (fChar == '?') {
+                                       if (fPos >= 1) {
+                                               if (fDocument.get(fPos - 1, 2).equalsIgnoreCase("<?")) {
+                                                       fPos--;
+                                                       return NOT_FOUND;
+                                               }
+                                       }
+                               }
+                               if (condition.stop(fChar, fPos, false))
+                                       return fPos;
+
+                               fPos--;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return NOT_FOUND;
+       }
+
+       /**
+        * Finds the highest position in <code>fDocument</code> such that the
+        * position is &lt;= <code>position</code> and &gt; <code>bound</code>
+        * and <code>fDocument.getChar(position) == ch</code> evaluates to
+        * <code>true</code> for at least one ch in <code>chars</code> and the
+        * position is in the default partition.
+        * 
+        * @param position
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &lt; <code>position</code>,
+        *            or <code>UNBOUND</code>
+        * @param ch
+        *            the <code>char</code> to search for
+        * @return the highest position of one element in <code>chars</code> in (<code>bound</code>,
+        *         <code>position</code>] that resides in a Java partition, or
+        *         <code>NOT_FOUND</code> if none can be found
+        */
+       public int scanBackward(int position, int bound, char ch) {
+               return scanBackward(position, bound, new CharacterMatch(ch));
+       }
+
+       /**
+        * Finds the highest position in <code>fDocument</code> such that the
+        * position is &lt;= <code>position</code> and &gt; <code>bound</code>
+        * and <code>fDocument.getChar(position) == ch</code> evaluates to
+        * <code>true</code> for at least one ch in <code>chars</code> and the
+        * position is in the default partition.
+        * 
+        * @param position
+        *            the first character position in <code>fDocument</code> to be
+        *            considered
+        * @param bound
+        *            the first position in <code>fDocument</code> to not consider
+        *            any more, with <code>bound</code> &lt; <code>position</code>,
+        *            or <code>UNBOUND</code>
+        * @param chars
+        *            an array of <code>char</code> to search for
+        * @return the highest position of one element in <code>chars</code> in (<code>bound</code>,
+        *         <code>position</code>] that resides in a Java partition, or
+        *         <code>NOT_FOUND</code> if none can be found
+        */
+       public int scanBackward(int position, int bound, char[] chars) {
+               return scanBackward(position, bound, new CharacterMatch(chars));
+       }
+
+       /**
+        * Checks whether <code>position</code> resides in a default (Java)
+        * partition of <code>fDocument</code>.
+        * 
+        * @param position
+        *            the position to be checked
+        * @return <code>true</code> if <code>position</code> is in the default
+        *         partition of <code>fDocument</code>, <code>false</code>
+        *         otherwise
+        */
+       public boolean isDefaultPartition(int position) {
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(position <= fDocument.getLength());
+
+               try {
+                       ITypedRegion region = TextUtilities.getPartition(fDocument,
+                                       fPartitioning, position, false);
+                       return region.getType().equals(fPartition);
+
+               } catch (BadLocationException e) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Checks if the line seems to be an open condition not followed by a block
+        * (i.e. an if, while, or for statement with just one following statement,
+        * see example below).
+        * 
+        * <pre>
+        * if (condition)
+        *      doStuff();
+        * </pre>
+        * 
+        * <p>
+        * Algorithm: if the last non-WS, non-Comment code on the line is an if
+        * (condition), while (condition), for( expression), do, else, and there is
+        * no statement after that
+        * </p>
+        * 
+        * @param position
+        *            the insert position of the new character
+        * @param bound
+        *            the lowest position to consider
+        * @return <code>true</code> if the code is a conditional statement or
+        *         loop without a block, <code>false</code> otherwise
+        */
+       public boolean isBracelessBlockStart(int position, int bound) {
+               if (position < 1)
+                       return false;
+
+               switch (previousToken(position, bound)) {
+               case TokenDO:
+               case TokenELSE:
+                       return true;
+               case TokenRPAREN:
+                       position = findOpeningPeer(fPos, LPAREN, RPAREN);
+                       if (position > 0) {
+                               switch (previousToken(position - 1, bound)) {
+                               case TokenIF:
+                               case TokenFOR:
+                               case TokenWHILE:
+                                       return true;
+                               }
+                       }
+               }
+
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java
new file mode 100644 (file)
index 0000000..ef0c4ae
--- /dev/null
@@ -0,0 +1,1519 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.formatter.DefaultCodeFormatterConstants;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+
+/**
+ * Uses the {@link net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner}to
+ * get the indentation level for a certain position in a document.
+ * 
+ * <p>
+ * An instance holds some internal position in the document and is therefore not
+ * threadsafe.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class JavaIndenter {
+
+       /** The document being scanned. */
+       private IDocument fDocument;
+
+       /** The indentation accumulated by <code>findPreviousIndenationUnit</code>. */
+       private int fIndent;
+
+       /**
+        * The absolute (character-counted) indentation offset for special cases
+        * (method defs, array initializers)
+        */
+       private int fAlign;
+
+       /** The stateful scanposition for the indentation methods. */
+       private int fPosition;
+
+       /** The previous position. */
+       private int fPreviousPos;
+
+       /** The most recent token. */
+       private int fToken;
+
+       /** The line of <code>fPosition</code>. */
+       private int fLine;
+
+       /**
+        * The scanner we will use to scan the document. It has to be installed on
+        * the same document as the one we get.
+        */
+       private JavaHeuristicScanner fScanner;
+
+       /**
+        * Creates a new instance.
+        * 
+        * @param document
+        *            the document to scan
+        * @param scanner
+        *            the {@link JavaHeuristicScanner} to be used for scanning the
+        *            document. It must be installed on the same
+        *            <code>IDocument</code>.
+        */
+       public JavaIndenter(IDocument document, JavaHeuristicScanner scanner) {
+               Assert.isNotNull(document);
+               Assert.isNotNull(scanner);
+               fDocument = document;
+               fScanner = scanner;
+       }
+
+       /**
+        * Computes the indentation at the reference point of <code>position</code>.
+        * 
+        * @param offset
+        *            the offset in the document
+        * @return a String which reflects the indentation at the line in which the
+        *         reference position to <code>offset</code> resides, or
+        *         <code>null</code> if it cannot be determined
+        */
+       public StringBuffer getReferenceIndentation(int offset) {
+               return getReferenceIndentation(offset, false);
+       }
+
+       /**
+        * Computes the indentation at the reference point of <code>position</code>.
+        * 
+        * @param offset
+        *            the offset in the document
+        * @param assumeOpeningBrace
+        *            <code>true</code> if an opening brace should be assumed
+        * @return a String which reflects the indentation at the line in which the
+        *         reference position to <code>offset</code> resides, or
+        *         <code>null</code> if it cannot be determined
+        */
+       private StringBuffer getReferenceIndentation(int offset,
+                       boolean assumeOpeningBrace) {
+
+               int unit;
+               if (assumeOpeningBrace)
+                       unit = findReferencePosition(offset, Symbols.TokenLBRACE);
+               else
+                       unit = findReferencePosition(offset, peekChar(offset));
+
+               // if we were unable to find anything, return null
+               if (unit == JavaHeuristicScanner.NOT_FOUND)
+                       return null;
+
+               return getLeadingWhitespace(unit);
+
+       }
+
+       /**
+        * Computes the indentation at <code>offset</code>.
+        * 
+        * @param offset
+        *            the offset in the document
+        * @return a String which reflects the correct indentation for the line in
+        *         which offset resides, or <code>null</code> if it cannot be
+        *         determined
+        */
+       public StringBuffer computeIndentation(int offset) {
+               return computeIndentation(offset, false);
+       }
+
+       /**
+        * Computes the indentation at <code>offset</code>.
+        * 
+        * @param offset
+        *            the offset in the document
+        * @param assumeOpeningBrace
+        *            <code>true</code> if an opening brace should be assumed
+        * @return a String which reflects the correct indentation for the line in
+        *         which offset resides, or <code>null</code> if it cannot be
+        *         determined
+        */
+       public StringBuffer computeIndentation(int offset,
+                       boolean assumeOpeningBrace) {
+
+               StringBuffer indent = getReferenceIndentation(offset,
+                               assumeOpeningBrace);
+
+               // handle special alignment
+               if (fAlign != JavaHeuristicScanner.NOT_FOUND) {
+                       try {
+                               // a special case has been detected.
+                               IRegion line = fDocument.getLineInformationOfOffset(fAlign);
+                               int lineOffset = line.getOffset();
+                               return createIndent(lineOffset, fAlign);
+                       } catch (BadLocationException e) {
+                               return null;
+                       }
+               }
+
+               if (indent == null)
+                       return null;
+
+               // add additional indent
+               //indent.append(createIndent(fIndent));
+               indent.insert(0, createIndent(fIndent));
+               if (fIndent < 0)
+                       unindent(indent);
+
+               return indent;
+       }
+
+       /**
+        * Returns the indentation of the line at <code>offset</code> as a
+        * <code>StringBuffer</code>. If the offset is not valid, the empty
+        * string is returned.
+        * 
+        * @param offset
+        *            the offset in the document
+        * @return the indentation (leading whitespace) of the line in which
+        *         <code>offset</code> is located
+        */
+       private StringBuffer getLeadingWhitespace(int offset) {
+               StringBuffer indent = new StringBuffer();
+               try {
+                       IRegion line = fDocument.getLineInformationOfOffset(offset);
+                       int lineOffset = line.getOffset();
+                       int nonWS = fScanner.findNonWhitespaceForwardInAnyPartition(
+                                       lineOffset, lineOffset + line.getLength());
+                       indent.append(fDocument.get(lineOffset, nonWS - lineOffset));
+                       return indent;
+               } catch (BadLocationException e) {
+                       return indent;
+               }
+       }
+
+       /**
+        * Reduces indentation in <code>indent</code> by one indentation unit.
+        * 
+        * @param indent
+        *            the indentation to be modified
+        */
+       private void unindent(StringBuffer indent) {
+               CharSequence oneIndent = createIndent();
+               int i = indent.lastIndexOf(oneIndent.toString()); //$NON-NLS-1$
+               if (i != -1) {
+                       indent.delete(i, i + oneIndent.length());
+               }
+       }
+
+       /**
+        * Creates an indentation string of the length indent - start + 1,
+        * consisting of the content in <code>fDocument</code> in the range
+        * [start, indent), with every character replaced by a space except for
+        * tabs, which are kept as such.
+        * 
+        * <p>
+        * Every run of the number of spaces that make up a tab are replaced by a
+        * tab character.
+        * </p>
+        * 
+        * @return the indentation corresponding to the document content specified
+        *         by <code>start</code> and <code>indent</code>
+        */
+       private StringBuffer createIndent(int start, int indent) {
+               final int tabLen = prefTabLength();
+               StringBuffer ret = new StringBuffer();
+               try {
+                       int spaces = 0;
+                       while (start < indent) {
+
+                               char ch = fDocument.getChar(start);
+                               if (ch == '\t') {
+                                       ret.append('\t');
+                                       spaces = 0;
+                               } else if (tabLen == -1) {
+                                       ret.append(' ');
+                               } else {
+                                       spaces++;
+                                       if (spaces == tabLen) {
+                                               ret.append('\t');
+                                               spaces = 0;
+                                       }
+                               }
+
+                               start++;
+                       }
+                       // remainder
+                       if (spaces == tabLen)
+                               ret.append('\t');
+                       else
+                               while (spaces-- > 0)
+                                       ret.append(' ');
+
+               } catch (BadLocationException e) {
+               }
+
+               return ret;
+       }
+
+       /**
+        * Creates a string that represents the given number of indents (can be
+        * spaces or tabs..)
+        * 
+        * @param indent
+        *            the requested indentation level.
+        * 
+        * @return the indentation specified by <code>indent</code>
+        */
+       public StringBuffer createIndent(int indent) {
+               StringBuffer oneIndent = createIndent();
+
+               StringBuffer ret = new StringBuffer();
+               while (indent-- > 0)
+                       ret.append(oneIndent);
+
+               return ret;
+       }
+
+       /**
+        * Creates a string that represents one indent (can be spaces or tabs..)
+        * 
+        * @return one indentation
+        */
+       private StringBuffer createIndent() {
+               // get a sensible default when running without the infrastructure for
+               // testing
+               StringBuffer oneIndent = new StringBuffer();
+               // JavaCore plugin= JavaCore.getJavaCore();
+               WebUI plugin = WebUI.getDefault();
+               if (plugin == null) {
+                       oneIndent.append('\t');
+               } else {
+                       if (JavaCore.SPACE
+                                       .equals(JavaCore
+                                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR))) {
+                               int tabLen = Integer
+                                               .parseInt(JavaCore
+                                                               .getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE));
+                               for (int i = 0; i < tabLen; i++)
+                                       oneIndent.append(' ');
+                       } else if (JavaCore.TAB
+                                       .equals(JavaCore
+                                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR)))
+                               oneIndent.append('\t');
+                       else
+                               oneIndent.append('\t'); // default
+               }
+               return oneIndent;
+       }
+
+       /**
+        * Returns the reference position regarding to indentation for
+        * <code>offset</code>, or <code>NOT_FOUND</code>. This method calls
+        * {@link #findReferencePosition(int, int) findReferencePosition(offset, nextChar)}
+        * where <code>nextChar</code> is the next character after
+        * <code>offset</code>.
+        * 
+        * @param offset
+        *            the offset for which the reference is computed
+        * @return the reference statement relative to which <code>offset</code>
+        *         should be indented, or {@link JavaHeuristicScanner#NOT_FOUND}
+        */
+       public int findReferencePosition(int offset) {
+               return findReferencePosition(offset, peekChar(offset));
+       }
+
+       /**
+        * Peeks the next char in the document that comes after <code>offset</code>
+        * on the same line as <code>offset</code>.
+        * 
+        * @param offset
+        *            the offset into document
+        * @return the token symbol of the next element, or TokenEOF if there is
+        *         none
+        */
+       private int peekChar(int offset) {
+               if (offset < fDocument.getLength()) {
+                       try {
+                               IRegion line = fDocument.getLineInformationOfOffset(offset);
+                               int lineOffset = line.getOffset();
+                               int next = fScanner.nextToken(offset, lineOffset
+                                               + line.getLength());
+                               return next;
+                       } catch (BadLocationException e) {
+                       }
+               }
+               return Symbols.TokenEOF;
+       }
+
+       /**
+        * Returns the reference position regarding to indentation for
+        * <code>position</code>, or <code>NOT_FOUND</code>.
+        * 
+        * <p>
+        * If <code>peekNextChar</code> is <code>true</code>, the next token
+        * after <code>offset</code> is read and taken into account when computing
+        * the indentation. Currently, if the next token is the first token on the
+        * line (i.e. only preceded by whitespace), the following tokens are
+        * specially handled:
+        * <ul>
+        * <li><code>switch</code> labels are indented relative to the switch
+        * block</li>
+        * <li>opening curly braces are aligned correctly with the introducing code</li>
+        * <li>closing curly braces are aligned properly with the introducing code
+        * of the matching opening brace</li>
+        * <li>closing parenthesis' are aligned with their opening peer</li>
+        * <li>the <code>else</code> keyword is aligned with its <code>if</code>,
+        * anything else is aligned normally (i.e. with the base of any introducing
+        * statements).</li>
+        * <li>if there is no token on the same line after <code>offset</code>,
+        * the indentation is the same as for an <code>else</code> keyword</li>
+        * </ul>
+        * 
+        * @param offset
+        *            the offset for which the reference is computed
+        * @param nextToken
+        *            the next token to assume in the document
+        * @return the reference statement relative to which <code>offset</code>
+        *         should be indented, or {@link JavaHeuristicScanner#NOT_FOUND}
+        */
+       public int findReferencePosition(int offset, int nextToken) {
+               boolean danglingElse = false;
+               boolean unindent = false;
+               boolean indent = false;
+               boolean matchBrace = false;
+               boolean matchParen = false;
+               boolean matchCase = false;
+
+               // account for unindenation characters already typed in, but after
+               // position
+               // if they are on a line by themselves, the indentation gets adjusted
+               // accordingly
+               //
+               // also account for a dangling else
+               if (offset < fDocument.getLength()) {
+                       try {
+                               IRegion line = fDocument.getLineInformationOfOffset(offset);
+                               int lineOffset = line.getOffset();
+                               int prevPos = Math.max(offset - 1, 0);
+                               boolean isFirstTokenOnLine = fDocument.get(lineOffset,
+                                               prevPos + 1 - lineOffset).trim().length() == 0;
+                               int prevToken = fScanner.previousToken(prevPos,
+                                               JavaHeuristicScanner.UNBOUND);
+                               if (prevToken == Symbols.TokenEOF && nextToken == Symbols.TokenEOF) {
+                                       ITypedRegion partition = TextUtilities.getPartition(fDocument, IPHPPartitions.PHP_PARTITIONING, offset, true);
+                                       if (partition.getType().equals(IPHPPartitions.PHP_SINGLELINE_COMMENT)) {
+                                               fAlign = fScanner.getPosition();
+                                       } else {
+                                               fAlign = JavaHeuristicScanner.NOT_FOUND;
+                                       }
+                                       return JavaHeuristicScanner.NOT_FOUND;
+                               }
+                               boolean bracelessBlockStart = fScanner.isBracelessBlockStart(
+                                               prevPos, JavaHeuristicScanner.UNBOUND);
+
+                               switch (nextToken) {
+                               case Symbols.TokenEOF:
+                               case Symbols.TokenELSE:
+                                       danglingElse = true;
+                                       break;
+                               case Symbols.TokenCASE:
+                               case Symbols.TokenDEFAULT:
+                                       if (isFirstTokenOnLine)
+                                               matchCase = true;
+                                       break;
+                               case Symbols.TokenLBRACE: // for opening-brace-on-new-line
+                                                                                       // style
+                               // if (bracelessBlockStart && !prefIndentBracesForBlocks())
+                               // unindent= true;
+                               // else if ((prevToken == Symbols.TokenCOLON || prevToken ==
+                               // Symbols.TokenEQUAL || prevToken == Symbols.TokenRBRACKET) &&
+                               // !prefIndentBracesForArrays())
+                               // unindent= true;
+                               // else if (!bracelessBlockStart &&
+                               // prefIndentBracesForMethods())
+                               // indent= true;
+                               // break;
+                                       if (bracelessBlockStart)
+                                               unindent = true;
+                                       else if ((prevToken == Symbols.TokenCOLON
+                                                       || prevToken == Symbols.TokenEQUAL || prevToken == Symbols.TokenRBRACKET))
+                                               unindent = true;
+                                       else if (!bracelessBlockStart)
+                                               indent = true;
+                                       break;
+                               case Symbols.TokenRBRACE: // closing braces get unindented
+                                       if (isFirstTokenOnLine)
+                                               matchBrace = true;
+                                       break;
+                               case Symbols.TokenRPAREN:
+                                       if (isFirstTokenOnLine)
+                                               matchParen = true;
+                                       break;
+                               }
+                       } catch (BadLocationException e) {
+                       }
+               } else {
+                       // assume an else could come if we are at the end of file
+                       danglingElse = true;
+               }
+
+               int ref = findReferencePosition(offset, danglingElse, matchBrace,
+                               matchParen, matchCase);
+               if (unindent)
+                       fIndent--;
+               if (indent)
+                       fIndent++;
+               return ref;
+       }
+
+       /**
+        * Returns the reference position regarding to indentation for
+        * <code>position</code>, or <code>NOT_FOUND</code>.<code>fIndent</code>
+        * will contain the relative indentation (in indentation units, not
+        * characters) after the call. If there is a special alignment (e.g. for a
+        * method declaration where parameters should be aligned),
+        * <code>fAlign</code> will contain the absolute position of the alignment
+        * reference in <code>fDocument</code>, otherwise <code>fAlign</code>
+        * is set to <code>JavaHeuristicScanner.NOT_FOUND</code>.
+        * 
+        * @param offset
+        *            the offset for which the reference is computed
+        * @param danglingElse
+        *            whether a dangling else should be assumed at
+        *            <code>position</code>
+        * @param matchBrace
+        *            whether the position of the matching brace should be returned
+        *            instead of doing code analysis
+        * @param matchParen
+        *            whether the position of the matching parenthesis should be
+        *            returned instead of doing code analysis
+        * @param matchCase
+        *            whether the position of a switch statement reference should be
+        *            returned (either an earlier case statement or the switch block
+        *            brace)
+        * @return the reference statement relative to which <code>position</code>
+        *         should be indented, or {@link JavaHeuristicScanner#NOT_FOUND}
+        */
+       public int findReferencePosition(int offset, boolean danglingElse,
+                       boolean matchBrace, boolean matchParen, boolean matchCase) {
+               fIndent = 0; // the indentation modification
+               fAlign = JavaHeuristicScanner.NOT_FOUND;
+               fPosition = offset;
+
+               // forward cases
+               // an unindentation happens sometimes if the next token is special,
+               // namely on braces, parens and case labels
+               // align braces, but handle the case where we align with the method
+               // declaration start instead of
+               // the opening brace.
+               if (matchBrace) {
+                       if (skipScope(Symbols.TokenLBRACE, Symbols.TokenRBRACE)) {
+                               try {
+                                       // align with the opening brace that is on a line by its own
+                                       int lineOffset = fDocument.getLineOffset(fLine);
+                                       if (lineOffset <= fPosition
+                                                       && fDocument
+                                                                       .get(lineOffset, fPosition - lineOffset)
+                                                                       .trim().length() == 0)
+                                               return fPosition;
+                               } catch (BadLocationException e) {
+                                       // concurrent modification - walk default path
+                               }
+                               // if the opening brace is not on the start of the line, skip to
+                               // the start
+                               int pos = skipToStatementStart(true, true);
+                               fIndent = 0; // indent is aligned with reference position
+                               return pos;
+                       } else {
+                               // if we can't find the matching brace, the heuristic is to
+                               // unindent
+                               // by one against the normal position
+                               int pos = findReferencePosition(offset, danglingElse, false,
+                                               matchParen, matchCase);
+                               fIndent--;
+                               return pos;
+                       }
+               }
+
+               // align parenthesis'
+               if (matchParen) {
+                       if (skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN))
+                               return fPosition;
+                       else {
+                               // if we can't find the matching paren, the heuristic is to
+                               // unindent
+                               // by one against the normal position
+                               int pos = findReferencePosition(offset, danglingElse,
+                                               matchBrace, false, matchCase);
+                               fIndent--;
+                               return pos;
+                       }
+               }
+
+               // the only reliable way to get case labels aligned (due to many
+               // different styles of using braces in a block)
+               // is to go for another case statement, or the scope opening brace
+               if (matchCase) {
+                       return matchCaseAlignment();
+               }
+
+               nextToken();
+               switch (fToken) {
+               case Symbols.TokenRBRACE:
+                       // skip the block and fall through
+                       // if we can't complete the scope, reset the scan position
+                       int pos = fPosition;
+                       if (!skipScope())
+                               fPosition = pos;
+               case Symbols.TokenSEMICOLON:
+                       // this is the 90% case: after a statement block
+                       // the end of the previous statement / block previous.end
+                       // search to the end of the statement / block before the previous;
+                       // the token just after that is previous.start
+                       return skipToStatementStart(danglingElse, false);
+
+                       // scope introduction: special treat who special is
+               case Symbols.TokenLPAREN:
+               case Symbols.TokenLBRACE:
+               case Symbols.TokenLBRACKET:
+                       return handleScopeIntroduction(offset + 1);
+
+               case Symbols.TokenEOF:
+                       // trap when hitting start of document
+                       return 0;
+
+               case Symbols.TokenEQUAL:
+                       // indent assignments
+                       fIndent = prefAssignmentIndent();
+                       return fPosition;
+
+               case Symbols.TokenCOLON:
+                       // TODO handle ternary deep indentation
+                       fIndent = prefCaseBlockIndent();
+                       return fPosition;
+
+               case Symbols.TokenQUESTIONMARK:
+                       if (prefTernaryDeepAlign()) {
+                               setFirstElementAlignment(fPosition, offset + 1);
+                               return fPosition;
+                       } else {
+                               fIndent = prefTernaryIndent();
+                               return fPosition;
+                       }
+
+                       // indentation for blockless introducers:
+               case Symbols.TokenDO:
+               case Symbols.TokenWHILE:
+               case Symbols.TokenELSE:
+                       fIndent = prefSimpleIndent();
+                       return fPosition;
+               case Symbols.TokenRPAREN:
+                       int line = fLine;
+                       if (skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN)) {
+                               int scope = fPosition;
+                               nextToken();
+                               if (fToken == Symbols.TokenIF || fToken == Symbols.TokenWHILE
+                                               || fToken == Symbols.TokenFOR) {
+                                       fIndent = prefSimpleIndent();
+                                       return fPosition;
+                               }
+                               fPosition = scope;
+                               if (looksLikeMethodDecl()) {
+                                       return skipToStatementStart(danglingElse, false);
+                               }
+                       }
+                       // restore
+                       fPosition = offset;
+                       fLine = line;
+                       // else: fall through to default
+
+               case Symbols.TokenCOMMA:
+                       // inside a list of some type
+                       // easy if there is already a list item before with its own
+                       // indentation - we just align
+                       // if not: take the start of the list ( LPAREN, LBRACE, LBRACKET )
+                       // and either align or
+                       // indent by list-indent
+               default:
+                       // inside whatever we don't know about: similar to the list case:
+                       // if we are inside a continued expression, then either align with a
+                       // previous line that has indentation
+                       // or indent from the expression start line (either a scope
+                       // introducer or the start of the expr).
+                       return skipToPreviousListItemOrListStart();
+
+               }
+       }
+
+       /**
+        * Skips to the start of a statement that ends at the current position.
+        * 
+        * @param danglingElse
+        *            whether to indent aligned with the last <code>if</code>
+        * @param isInBlock
+        *            whether the current position is inside a block, which limits
+        *            the search scope to the next scope introducer
+        * @return the reference offset of the start of the statement
+        */
+       private int skipToStatementStart(boolean danglingElse, boolean isInBlock) {
+               while (true) {
+                       nextToken();
+
+                       if (isInBlock) {
+                               switch (fToken) {
+                               // exit on all block introducers
+                               case Symbols.TokenIF:
+                               case Symbols.TokenELSE:
+                               case Symbols.TokenSYNCHRONIZED:
+                               case Symbols.TokenCOLON:
+                               case Symbols.TokenSTATIC:
+                               case Symbols.TokenCATCH:
+                               case Symbols.TokenDO:
+                               case Symbols.TokenWHILE:
+                               case Symbols.TokenFINALLY:
+                               case Symbols.TokenFOR:
+                               case Symbols.TokenTRY:
+                                       return fPosition;
+
+                               case Symbols.TokenSWITCH:
+                                       fIndent = prefCaseIndent();
+                                       return fPosition;
+                               }
+                       }
+
+                       switch (fToken) {
+                       // scope introduction through: LPAREN, LBRACE, LBRACKET
+                       // search stop on SEMICOLON, RBRACE, COLON, EOF
+                       // -> the next token is the start of the statement (i.e. previousPos
+                       // when backward scanning)
+                       case Symbols.TokenLPAREN:
+                       case Symbols.TokenLBRACE:
+                       case Symbols.TokenLBRACKET:
+                       case Symbols.TokenSEMICOLON:
+                       case Symbols.TokenEOF:
+                               return fPreviousPos;
+
+                       case Symbols.TokenCOLON:
+                               int pos = fPreviousPos;
+                               if (!isConditional())
+                                       return pos;
+                               break;
+
+                       case Symbols.TokenRBRACE:
+                               // RBRACE is a little tricky: it can be the end of an array
+                               // definition, but
+                               // usually it is the end of a previous block
+                               pos = fPreviousPos; // store state
+                               if (skipScope() && looksLikeArrayInitializerIntro())
+                                       continue; // it's an array
+                               else
+                                       return pos; // it's not - do as with all the above
+
+                               // scopes: skip them
+                       case Symbols.TokenRPAREN:
+                       case Symbols.TokenRBRACKET:
+                               pos = fPreviousPos;
+                               if (skipScope())
+                                       break;
+                               else
+                                       return pos;
+
+                               // IF / ELSE: align the position after the conditional block
+                               // with the if
+                               // so we are ready for an else, except if danglingElse is false
+                               // in order for this to work, we must skip an else to its if
+                       case Symbols.TokenIF:
+                               if (danglingElse)
+                                       return fPosition;
+                               else
+                                       break;
+                       case Symbols.TokenELSE:
+                               // skip behind the next if, as we have that one covered
+                               pos = fPosition;
+                               if (skipNextIF())
+                                       break;
+                               else
+                                       return pos;
+
+                       case Symbols.TokenDO:
+                               // align the WHILE position with its do
+                               return fPosition;
+
+                       case Symbols.TokenWHILE:
+                               // this one is tricky: while can be the start of a while loop
+                               // or the end of a do - while
+                               pos = fPosition;
+                               if (hasMatchingDo()) {
+                                       // continue searching from the DO on
+                                       break;
+                               } else {
+                                       // continue searching from the WHILE on
+                                       fPosition = pos;
+                                       break;
+                               }
+                       default:
+                               // keep searching
+
+                       }
+
+               }
+       }
+
+       /**
+        * Returns true if the colon at the current position is part of a
+        * conditional (ternary) expression, false otherwise.
+        * 
+        * @return true if the colon at the current position is part of a
+        *         conditional
+        */
+       private boolean isConditional() {
+               while (true) {
+                       nextToken();
+                       switch (fToken) {
+
+                       // search for case, otherwise return true
+                       case Symbols.TokenIDENT:
+                               continue;
+                       case Symbols.TokenCASE:
+                               return false;
+
+                       default:
+                               return true;
+                       }
+               }
+       }
+
+       /**
+        * Returns as a reference any previous <code>switch</code> labels (<code>case</code>
+        * or <code>default</code>) or the offset of the brace that scopes the
+        * switch statement. Sets <code>fIndent</code> to
+        * <code>prefCaseIndent</code> upon a match.
+        * 
+        * @return the reference offset for a <code>switch</code> label
+        */
+       private int matchCaseAlignment() {
+               while (true) {
+                       nextToken();
+                       switch (fToken) {
+                       // invalid cases: another case label or an LBRACE must come before a
+                       // case
+                       // -> bail out with the current position
+                       case Symbols.TokenLPAREN:
+                       case Symbols.TokenLBRACKET:
+                       case Symbols.TokenEOF:
+                               return fPosition;
+                       case Symbols.TokenLBRACE:
+                               // opening brace of switch statement
+                               fIndent = 1; //prefCaseIndent() is for Java
+                               return fPosition;
+                       case Symbols.TokenCASE:
+                       case Symbols.TokenDEFAULT:
+                               // align with previous label
+                               fIndent = 0;
+                               return fPosition;
+                       // scopes: skip them
+                       case Symbols.TokenRPAREN:
+                       case Symbols.TokenRBRACKET:
+                       case Symbols.TokenRBRACE:
+                               skipScope();
+                               break;
+                       default:
+                               // keep searching
+                               continue;
+                       }
+               }
+       }
+
+        /**
+        * Returns the reference position for a list element. The algorithm tries to
+        * match any previous indentation on the same list. If there is none, the
+        * reference position returned is determined depending on the type of list:
+        * The indentation will either match the list scope introducer (e.g. for
+        * method declarations), so called deep indents, or simply increase the
+        * indentation by a number of standard indents. See also
+        * {@link #handleScopeIntroduction(int)}.
+        * 
+        * @return the reference position for a list item: either a previous list
+        *         item that has its own indentation, or the list introduction
+        *         start.
+        */
+       private int skipToPreviousListItemOrListStart() {
+               int startLine = fLine;
+               int startPosition = fPosition;
+               while (true) {
+                       nextToken();
+
+                       // if any line item comes with its own indentation, adapt to it
+                       if (fLine < startLine) {
+                               try {
+                                       int lineOffset = fDocument.getLineOffset(startLine);
+                                       int bound = Math.min(fDocument.getLength(),
+                                                       startPosition + 1);
+                                       fAlign = fScanner.findNonWhitespaceForwardInAnyPartition(
+                                                       lineOffset, bound);
+                               } catch (BadLocationException e) {
+                                       // ignore and return just the position
+                               }
+                               return startPosition;
+                       }
+
+                       switch (fToken) {
+                       // scopes: skip them
+                       case Symbols.TokenRPAREN:
+                       case Symbols.TokenRBRACKET:
+                       case Symbols.TokenRBRACE:
+                               skipScope();
+                               break;
+
+                       // scope introduction: special treat who special is
+                       case Symbols.TokenLPAREN:
+                       case Symbols.TokenLBRACE:
+                       case Symbols.TokenLBRACKET:
+                               return handleScopeIntroduction(startPosition + 1);
+
+                       case Symbols.TokenSEMICOLON:
+                               return fPosition;
+                       case Symbols.TokenQUESTIONMARK:
+                               if (prefTernaryDeepAlign()) {
+                                       setFirstElementAlignment(fPosition - 1, fPosition + 1);
+                               } else {
+                                       fIndent = prefTernaryIndent();
+                               }
+                               return fPosition;
+                       case Symbols.TokenEOF:
+                               return 0;
+
+                       case Symbols.TokenEQUAL:
+                               // indent assignments
+                               fIndent= prefAssignmentIndent();
+                               return fPosition;
+                       }
+               }
+       }
+
+       /**
+        * Skips a scope and positions the cursor (<code>fPosition</code>) on
+        * the token that opens the scope. Returns <code>true</code> if a matching
+        * peer could be found, <code>false</code> otherwise. The current token
+        * when calling must be one out of <code>Symbols.TokenRPAREN</code>,
+        * <code>Symbols.TokenRBRACE</code>, and
+        * <code>Symbols.TokenRBRACKET</code>.
+        * 
+        * @return <code>true</code> if a matching peer was found,
+        *         <code>false</code> otherwise
+        */
+       private boolean skipScope() {
+               switch (fToken) {
+               case Symbols.TokenRPAREN:
+                       return skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN);
+               case Symbols.TokenRBRACKET:
+                       return skipScope(Symbols.TokenLBRACKET, Symbols.TokenRBRACKET);
+               case Symbols.TokenRBRACE:
+                       return skipScope(Symbols.TokenLBRACE, Symbols.TokenRBRACE);
+               default:
+                       Assert.isTrue(false);
+                       return false;
+               }
+       }
+
+       /**
+        * Handles the introduction of a new scope. The current token must be one
+        * out of <code>Symbols.TokenLPAREN</code>,
+        * <code>Symbols.TokenLBRACE</code>, and
+        * <code>Symbols.TokenLBRACKET</code>. Returns as the reference position
+        * either the token introducing the scope or - if available - the first java
+        * token after that.
+        * 
+        * <p>
+        * Depending on the type of scope introduction, the indentation will align
+        * (deep indenting) with the reference position (<code>fAlign</code> will
+        * be set to the reference position) or <code>fIndent</code> will be set
+        * to the number of indentation units.
+        * </p>
+        * 
+        * @param bound
+        *            the bound for the search for the first token after the scope
+        *            introduction.
+        * @return
+        */
+       private int handleScopeIntroduction(int bound) {
+               switch (fToken) {
+               // scope introduction: special treat who special is
+               case Symbols.TokenLPAREN:
+                       int pos = fPosition; // store
+
+                       // special: method declaration deep indentation
+                       if (looksLikeMethodDecl()) {
+                               if (prefMethodDeclDeepIndent())
+                                       return setFirstElementAlignment(pos, bound);
+                               else {
+                                       fIndent = prefMethodDeclIndent();
+                                       return pos;
+                               }
+                       } else {
+                               fPosition = pos;
+                               if (looksLikeMethodCall()) {
+                                       if (prefMethodCallDeepIndent())
+                                               return setFirstElementAlignment(pos, bound);
+                                       else {
+                                               fIndent = prefMethodCallIndent();
+                                               return pos;
+                                       }
+                               } else if (prefParenthesisDeepIndent())
+                                       return setFirstElementAlignment(pos, bound);
+                       }
+
+                       // normal: return the parenthesis as reference
+                       fIndent = prefParenthesisIndent();
+                       return pos;
+
+               case Symbols.TokenLBRACE:
+                       pos = fPosition; // store
+
+                       // special: array initializer
+                       if (looksLikeArrayInitializerIntro())
+                               if (prefArrayDeepIndent())
+                                       return setFirstElementAlignment(pos, bound);
+                               else
+                                       fIndent = prefArrayIndent();
+                       else
+                               fIndent = prefBlockIndent();
+
+                       // normal: skip to the statement start before the scope introducer
+                       // opening braces are often on differently ending indents than e.g.
+                       // a method definition
+                       fPosition = pos; // restore
+                       return skipToStatementStart(true, true); // set to true to match
+                                                                                                               // the first if
+
+               case Symbols.TokenLBRACKET:
+                       pos = fPosition; // store
+
+                       // special: method declaration deep indentation
+                       if (prefArrayDimensionsDeepIndent()) {
+                               return setFirstElementAlignment(pos, bound);
+                       }
+
+                       // normal: return the bracket as reference
+                       fIndent = prefBracketIndent();
+                       return pos; // restore
+
+               default:
+                       Assert.isTrue(false);
+                       return -1; // dummy
+               }
+       }
+
+       /**
+        * Sets the deep indent offset (<code>fAlign</code>) to either the
+        * offset right after <code>scopeIntroducerOffset</code> or - if available -
+        * the first Java token after <code>scopeIntroducerOffset</code>, but
+        * before <code>bound</code>.
+        * 
+        * @param scopeIntroducerOffset
+        *            the offset of the scope introducer
+        * @param bound
+        *            the bound for the search for another element
+        * @return the reference position
+        */
+       private int setFirstElementAlignment(int scopeIntroducerOffset, int bound) {
+               int firstPossible = scopeIntroducerOffset + 1; // align with the first
+                                                                                                               // position after the
+                                                                                                               // scope intro
+               fAlign = fScanner.findNonWhitespaceForwardInAnyPartition(firstPossible,
+                               bound);
+               if (fAlign == JavaHeuristicScanner.NOT_FOUND)
+                       fAlign = firstPossible;
+               return fAlign;
+       }
+
+       /**
+        * Returns <code>true</code> if the next token received after calling
+        * <code>nextToken</code> is either an equal sign or an array designator
+        * ('[]').
+        * 
+        * @return <code>true</code> if the next elements look like the start of
+        *         an array definition
+        */
+       private boolean looksLikeArrayInitializerIntro() {
+               nextToken();
+               if (fToken == Symbols.TokenEQUAL || skipBrackets()) {
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Skips over the next <code>if</code> keyword. The current token when
+        * calling this method must be an <code>else</code> keyword. Returns
+        * <code>true</code> if a matching <code>if</code> could be found,
+        * <code>false</code> otherwise. The cursor (<code>fPosition</code>)
+        * is set to the offset of the <code>if</code> token.
+        * 
+        * @return <code>true</code> if a matching <code>if</code> token was
+        *         found, <code>false</code> otherwise
+        */
+       private boolean skipNextIF() {
+               Assert.isTrue(fToken == Symbols.TokenELSE);
+
+               while (true) {
+                       nextToken();
+                       switch (fToken) {
+                       // scopes: skip them
+                       case Symbols.TokenRPAREN:
+                       case Symbols.TokenRBRACKET:
+                       case Symbols.TokenRBRACE:
+                               skipScope();
+                               break;
+
+                       case Symbols.TokenIF:
+                               // found it, return
+                               return true;
+                       case Symbols.TokenELSE:
+                               // recursively skip else-if blocks
+                               skipNextIF();
+                               break;
+
+                       // shortcut scope starts
+                       case Symbols.TokenLPAREN:
+                       case Symbols.TokenLBRACE:
+                       case Symbols.TokenLBRACKET:
+                       case Symbols.TokenEOF:
+                               return false;
+                       }
+               }
+       }
+
+       /**
+        * while(condition); is ambiguous when parsed backwardly, as it is a valid
+        * statement by its own, so we have to check whether there is a matching do.
+        * A <code>do</code> can either be separated from the while by a block, or
+        * by a single statement, which limits our search distance.
+        * 
+        * @return <code>true</code> if the <code>while</code> currently in
+        *         <code>fToken</code> has a matching <code>do</code>.
+        */
+       private boolean hasMatchingDo() {
+               Assert.isTrue(fToken == Symbols.TokenWHILE);
+               nextToken();
+               switch (fToken) {
+               case Symbols.TokenRBRACE:
+                       skipScope(); // and fall thru
+               case Symbols.TokenSEMICOLON:
+                       skipToStatementStart(false, false);
+                       return fToken == Symbols.TokenDO;
+               }
+               return false;
+       }
+
+       /**
+        * Skips brackets if the current token is a RBRACKET. There can be nothing
+        * but whitespace in between, this is only to be used for <code>[]</code>
+        * elements.
+        * 
+        * @return <code>true</code> if a <code>[]</code> could be scanned, the
+        *         current token is left at the LBRACKET.
+        */
+       private boolean skipBrackets() {
+               if (fToken == Symbols.TokenRBRACKET) {
+                       nextToken();
+                       if (fToken == Symbols.TokenLBRACKET) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Reads the next token in backward direction from the heuristic scanner and
+        * sets the fields <code>fToken, fPreviousPosition</code> and
+        * <code>fPosition</code> accordingly.
+        */
+       private void nextToken() {
+               nextToken(fPosition);
+       }
+
+       /**
+        * Reads the next token in backward direction of <code>start</code> from
+        * the heuristic scanner and sets the fields
+        * <code>fToken, fPreviousPosition</code> and <code>fPosition</code>
+        * accordingly.
+        */
+       private void nextToken(int start) {
+               fToken = fScanner
+                               .previousToken(start - 1, JavaHeuristicScanner.UNBOUND);
+               fPreviousPos = start;
+               fPosition = fScanner.getPosition() + 1;
+               try {
+                       fLine = fDocument.getLineOfOffset(fPosition);
+               } catch (BadLocationException e) {
+                       fLine = -1;
+               }
+       }
+
+       /**
+        * Returns <code>true</code> if the current tokens look like a method
+        * declaration header (i.e. only the return type and method name). The
+        * heuristic calls <code>nextToken</code> and expects an identifier
+        * (method name) and a type declaration (an identifier with optional
+        * brackets) which also covers the visibility modifier of constructors; it
+        * does not recognize package visible constructors.
+        * 
+        * @return <code>true</code> if the current position looks like a method
+        *         declaration header.
+        */
+       private boolean looksLikeMethodDecl() {
+               /*
+                * TODO This heuristic does not recognize package private constructors
+                * since those do have neither type nor visibility keywords. One option
+                * would be to go over the parameter list, but that might be empty as
+                * well - hard to do without an AST...
+                */
+
+               nextToken();
+               if (fToken == Symbols.TokenIDENT) { // method name
+                       do
+                               nextToken();
+                       while (skipBrackets()); // optional brackets for array valued return
+                                                                       // types
+                       return fToken == Symbols.TokenIDENT; // type name
+
+               }
+               return false;
+       }
+
+       /**
+        * Returns <code>true</code> if the current tokens look like a method call
+        * header (i.e. an identifier as opposed to a keyword taking parenthesized
+        * parameters such as <code>if</code>).
+        * <p>
+        * The heuristic calls <code>nextToken</code> and expects an identifier
+        * (method name).
+        * 
+        * @return <code>true</code> if the current position looks like a method
+        *         call header.
+        */
+       private boolean looksLikeMethodCall() {
+               nextToken();
+               return fToken == Symbols.TokenIDENT; // method name
+       }
+
+       /**
+        * Scans tokens for the matching opening peer. The internal cursor (<code>fPosition</code>)
+        * is set to the offset of the opening peer if found.
+        * 
+        * @return <code>true</code> if a matching token was found,
+        *         <code>false</code> otherwise
+        */
+       private boolean skipScope(int openToken, int closeToken) {
+
+               int depth = 1;
+
+               while (true) {
+                       nextToken();
+
+                       if (fToken == closeToken) {
+                               depth++;
+                       } else if (fToken == openToken) {
+                               depth--;
+                               if (depth == 0)
+                                       return true;
+                       } else if (fToken == Symbols.TokenEOF) {
+                               return false;
+                       }
+               }
+       }
+
+       // TODO adjust once there are per-project settings
+
+       private int prefTabLength() {
+               int tabLen;
+               // JavaCore core= JavaCore.getJavaCore();
+               WebUI plugin = WebUI.getDefault();
+               // if (core != null && plugin != null)
+               if (plugin != null)
+                       if (JavaCore.SPACE
+                                       .equals(JavaCore
+                                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR)))
+                               // if the formatter uses chars to mark indentation, then don't
+                               // substitute any chars
+                               tabLen = -1; // results in no tabs being substituted for
+                                                               // space runs
+                       else
+                               // if the formatter uses tabs to mark indentations, use the
+                               // visual setting from the editor
+                               // to get nicely aligned indentations
+                               tabLen = plugin
+                                               .getPreferenceStore()
+                                               .getInt(
+                                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+               else
+                       tabLen = 4; // sensible default for testing
+
+               return tabLen;
+       }
+
+       private boolean prefArrayDimensionsDeepIndent() {
+               return true; // sensible default
+       }
+
+       private int prefArrayIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER);
+                       try {
+                               if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE)
+                                       return 1;
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+
+               return prefContinuationIndent(); // default
+       }
+
+       private boolean prefArrayDeepIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER);
+                       try {
+                               return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+
+               return true;
+       }
+
+       private boolean prefTernaryDeepAlign() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION);
+                       try {
+                               return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+               return false;
+       }
+
+       private int prefTernaryIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION);
+                       try {
+                               if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE)
+                                       return 1;
+                               else
+                                       return prefContinuationIndent();
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+
+               return prefContinuationIndent();
+       }
+
+       private int prefCaseIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       if (DefaultCodeFormatterConstants.TRUE
+                                       .equals(JavaCore
+                                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH)))
+                               return prefBlockIndent();
+                       else
+                               return 0;
+               }
+
+               return 0; // sun standard
+       }
+
+       private int prefAssignmentIndent() {
+               return prefBlockIndent();
+       }
+
+       private int prefCaseBlockIndent() {
+               if (true)
+                       return prefBlockIndent();
+
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       if (DefaultCodeFormatterConstants.TRUE
+                                       .equals(JavaCore
+                                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES)))
+                               return prefBlockIndent();
+                       else
+                               return 0;
+               }
+               return prefBlockIndent(); // sun standard
+       }
+
+       private int prefSimpleIndent() {
+               return prefBlockIndent();
+       }
+
+       private int prefBracketIndent() {
+               return prefBlockIndent();
+       }
+
+       private boolean prefMethodDeclDeepIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+                       try {
+                               return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+
+               return true;
+       }
+
+       private int prefMethodDeclIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+                       try {
+                               if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE)
+                                       return 1;
+                               else
+                                       return prefContinuationIndent();
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+               return 1;
+       }
+
+       private boolean prefMethodCallDeepIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+                       try {
+                               return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+               return false; // sensible default
+       }
+
+       private int prefMethodCallIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+                       try {
+                               if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE)
+                                       return 1;
+                               else
+                                       return prefContinuationIndent();
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+
+               return 1; // sensible default
+       }
+
+       private boolean prefParenthesisDeepIndent() {
+
+               if (true) // don't do parenthesis deep indentation
+                       return false;
+
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION);
+                       try {
+                               return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+                       } catch (IllegalArgumentException e) {
+                               // ignore and return default
+                       }
+               }
+
+               return false; // sensible default
+       }
+
+       private int prefParenthesisIndent() {
+               return prefContinuationIndent();
+       }
+
+       private int prefBlockIndent() {
+               return 1; // sensible default
+       }
+
+       private boolean prefIndentBracesForBlocks() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK);
+                       return option
+                                       .equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED);
+               }
+
+               return false; // sensible default
+       }
+
+       private boolean prefIndentBracesForArrays() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER);
+                       return option
+                                       .equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED);
+               }
+
+               return false; // sensible default
+       }
+
+       private boolean prefIndentBracesForMethods() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION);
+                       return option
+                                       .equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED);
+               }
+
+               return false; // sensible default
+       }
+
+       private int prefContinuationIndent() {
+               Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+                       String option = JavaCore
+                                       .getOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION);
+                       try {
+                               return Integer.parseInt(option);
+                       } catch (NumberFormatException e) {
+                               // ignore and return default
+                       }
+               }
+
+               return 2; // sensible default
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaOutlineInformationControl.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaOutlineInformationControl.java
new file mode 100644 (file)
index 0000000..badd6d4
--- /dev/null
@@ -0,0 +1,640 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IParent;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.actions.OpenActionUtil;
+import net.sourceforge.phpdt.internal.ui.util.StringMatcher;
+import net.sourceforge.phpdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
+import net.sourceforge.phpdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
+import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementLabels;
+import net.sourceforge.phpdt.ui.JavaElementSorter;
+import net.sourceforge.phpdt.ui.StandardJavaElementContentProvider;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlExtension;
+import org.eclipse.jface.text.IInformationControlExtension2;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+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.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.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+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.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * @author dmegert
+ * 
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>Templates. To enable and disable the creation of type
+ * comments go to Window>Preferences>Java>Code Generation.
+ */
+public class JavaOutlineInformationControl implements IInformationControl,
+               IInformationControlExtension, IInformationControlExtension2 {
+
+       /**
+        * The NamePatternFilter selects the elements which match the given string
+        * patterns.
+        * <p>
+        * The following characters have special meaning: ? => any character * =>
+        * any string
+        * </p>
+        * 
+        * @since 2.0
+        */
+       private static class NamePatternFilter extends ViewerFilter {
+               private String fPattern;
+
+               private StringMatcher fMatcher;
+
+               private ILabelProvider fLabelProvider;
+
+               private Viewer fViewer;
+
+               private StringMatcher getMatcher() {
+                       return fMatcher;
+               }
+
+               /*
+                * (non-Javadoc) Method declared on ViewerFilter.
+                */
+               public boolean select(Viewer viewer, Object parentElement,
+                               Object element) {
+                       if (fMatcher == null)
+                               return true;
+
+                       ILabelProvider labelProvider = getLabelProvider(viewer);
+
+                       String matchName = null;
+                       if (labelProvider != null)
+                               matchName = ((ILabelProvider) labelProvider).getText(element);
+                       else if (element instanceof IJavaElement)
+                               matchName = ((IJavaElement) element).getElementName();
+
+                       if (matchName != null && fMatcher.match(matchName))
+                               return true;
+
+                       return hasUnfilteredChild(viewer, element);
+               }
+
+               private ILabelProvider getLabelProvider(Viewer viewer) {
+                       if (fViewer == viewer)
+                               return fLabelProvider;
+
+                       fLabelProvider = null;
+                       IBaseLabelProvider baseLabelProvider = null;
+                       if (viewer instanceof StructuredViewer)
+                               baseLabelProvider = ((StructuredViewer) viewer)
+                                               .getLabelProvider();
+
+                       if (baseLabelProvider instanceof ILabelProvider)
+                               fLabelProvider = (ILabelProvider) baseLabelProvider;
+
+                       return fLabelProvider;
+               }
+
+               private boolean hasUnfilteredChild(Viewer viewer, Object element) {
+                       IJavaElement[] children;
+                       if (element instanceof IParent) {
+                               try {
+                                       children = ((IParent) element).getChildren();
+                               } catch (JavaModelException ex) {
+                                       return false;
+                               }
+                               for (int i = 0; i < children.length; i++)
+                                       if (select(viewer, element, children[i]))
+                                               return true;
+                       }
+                       return false;
+               }
+
+               /**
+                * Sets the patterns to filter out for the receiver.
+                * <p>
+                * The following characters have special meaning: ? => any character * =>
+                * any string
+                * </p>
+                */
+               public void setPattern(String pattern) {
+                       fPattern = pattern;
+                       if (fPattern == null) {
+                               fMatcher = null;
+                               return;
+                       }
+                       boolean ignoreCase = pattern.toLowerCase().equals(pattern);
+                       fMatcher = new StringMatcher(pattern, ignoreCase, false);
+               }
+       }
+
+       private static class BorderFillLayout extends Layout {
+
+               /** The border widths. */
+               final int fBorderSize;
+
+               /**
+                * Creates a fill layout with a border.
+                */
+               public BorderFillLayout(int borderSize) {
+                       if (borderSize < 0)
+                               throw new IllegalArgumentException();
+                       fBorderSize = borderSize;
+               }
+
+               /**
+                * Returns 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);
+                               }
+                       }
+               }
+       }
+
+       /** Border thickness in pixels. */
+       private static final int BORDER = 1;
+
+       /** Right margin in pixels. */
+       private static final int RIGHT_MARGIN = 3;
+
+       /** 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 control width constraint */
+       private int fMaxWidth = -1;
+
+       /** The control height constraint */
+       private int fMaxHeight = -1;
+
+       private StringMatcher fStringMatcher;
+
+       /**
+        * Creates a tree information control with the given shell as parent. The
+        * given style is applied to the tree widget.
+        * 
+        * @param parent
+        *            the parent shell
+        * @param style
+        *            the additional styles for the tree widget
+        */
+       public JavaOutlineInformationControl(Shell parent, int style) {
+               this(parent, SWT.RESIZE, style);
+       }
+
+       /**
+        * Creates a tree information control with the given shell as parent. No
+        * additional styles are applied.
+        * 
+        * @param parent
+        *            the parent shell
+        */
+       public JavaOutlineInformationControl(Shell parent) {
+               this(parent, SWT.NONE);
+       }
+
+       /**
+        * 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 JavaOutlineInformationControl(Shell parent, int shellStyle,
+                       int treeStyle) {
+               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));
+
+               createFilterText(fComposite);
+               createTreeViewer(fComposite, treeStyle);
+
+               int border = ((shellStyle & SWT.NO_TRIM) == 0) ? 0 : BORDER;
+               fShell.setLayout(new BorderFillLayout(border));
+
+               setInfoSystemColor();
+               installFilter();
+       }
+
+       private void createTreeViewer(Composite parent, int style) {
+               Tree tree = new Tree(parent, SWT.SINGLE | (style & ~SWT.MULTI));
+               GridData data = new GridData(GridData.FILL_BOTH);
+               tree.setLayoutData(data);
+
+               fTreeViewer = new TreeViewer(tree);
+
+               // Hide import declartions but show the container
+               // fTreeViewer.addFilter(new ViewerFilter() {
+               // public boolean select(Viewer viewer, Object parentElement, Object
+               // element) {
+               // return !(element instanceof IImportDeclaration);
+               // }
+               // });
+
+               fTreeViewer.setContentProvider(new StandardJavaElementContentProvider(
+                               true, true));
+               fTreeViewer.setSorter(new JavaElementSorter());
+               fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
+
+               AppearanceAwareLabelProvider lprovider = new AppearanceAwareLabelProvider(
+                               AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS
+                                               | JavaElementLabels.F_APP_TYPE_SIGNATURE,
+                               AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS);
+               fTreeViewer
+                               .setLabelProvider(new DecoratingJavaLabelProvider(lprovider));
+
+               fTreeViewer.getTree().addKeyListener(new KeyListener() {
+                       public void keyPressed(KeyEvent e) {
+                               if (e.character == 0x1B) // ESC
+                                       dispose();
+                       }
+
+                       public void keyReleased(KeyEvent e) {
+                               // do nothing
+                       }
+               });
+
+               fTreeViewer.getTree().addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               gotoSelectedElement();
+                       }
+               });
+       }
+
+       private Text createFilterText(Composite parent) {
+               fFilterText = new Text(parent, SWT.FLAT);
+
+               GridData data = new GridData();
+               GC gc = new GC(parent);
+               gc.setFont(parent.getFont());
+               FontMetrics fontMetrics = gc.getFontMetrics();
+               gc.dispose();
+
+               data.heightHint = org.eclipse.jface.dialogs.Dialog
+                               .convertHeightInCharsToPixels(fontMetrics, 1);
+               data.horizontalAlignment = GridData.FILL;
+               data.verticalAlignment = GridData.BEGINNING;
+               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
+                       }
+               });
+
+               // Horizonral separator line
+               Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL
+                               | SWT.LINE_DOT);
+               separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               return fFilterText;
+       }
+
+       private void setInfoSystemColor() {
+               Display display = fShell.getDisplay();
+               setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+               setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+       }
+
+       private void installFilter() {
+               final NamePatternFilter viewerFilter = new NamePatternFilter();
+               fTreeViewer.addFilter(viewerFilter);
+               fFilterText.setText(""); //$NON-NLS-1$
+
+               fFilterText.addModifyListener(new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               String pattern = fFilterText.getText();
+                               if (pattern != null) {
+                                       int length = pattern.length();
+                                       if (length == 0)
+                                               pattern = null;
+                                       else if (pattern.charAt(length - 1) != '*')
+                                               pattern = pattern + '*';
+                               } else
+                                       pattern = null;
+                               viewerFilter.setPattern(pattern);
+                               fStringMatcher = viewerFilter.getMatcher();
+                               fTreeViewer.getControl().setRedraw(false);
+                               fTreeViewer.refresh();
+                               fTreeViewer.expandAll();
+                               selectFirstMatch();
+                               fTreeViewer.getControl().setRedraw(true);
+                       }
+               });
+       }
+
+       private void gotoSelectedElement() {
+               Object selectedElement = ((IStructuredSelection) fTreeViewer
+                               .getSelection()).getFirstElement();
+               if (selectedElement != null) {
+                       try {
+                               dispose();
+                               OpenActionUtil.open(selectedElement, true);
+                       } catch (CoreException ex) {
+                               WebUI.log(ex);
+                       }
+               }
+       }
+
+       /**
+        * Selects the first element in the tree which matches the current filter
+        * pattern.
+        */
+       private 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 IJavaElement findElement(TreeItem[] items) {
+               ILabelProvider labelProvider = (ILabelProvider) fTreeViewer
+                               .getLabelProvider();
+               for (int i = 0; i < items.length; i++) {
+                       IJavaElement element = (IJavaElement) 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;
+       }
+
+       /*
+        * @see IInformationControl#setInformation(String)
+        */
+       public void setInformation(String information) {
+               // this method is ignored, see IInformationControlExtension2
+       }
+
+       /*
+        * @see IInformationControlExtension2#setInput(Object)
+        */
+       public void setInput(Object information) {
+               fFilterText.setText(""); //$NON-NLS-1$
+               if (information == null || information instanceof String) {
+                       setInput(null);
+                       return;
+               }
+               IJavaElement je = (IJavaElement) information;
+               IJavaElement sel = null;
+               ICompilationUnit cu = (ICompilationUnit) je
+                               .getAncestor(IJavaElement.COMPILATION_UNIT);
+               if (cu != null)
+                       sel = cu;
+               else
+                       sel = je.getAncestor(IJavaElement.CLASS_FILE);
+               fTreeViewer.setInput(sel);
+               fTreeViewer.setSelection(new StructuredSelection(information));
+       }
+
+       /*
+        * @see IInformationControl#setVisible(boolean)
+        */
+       public void setVisible(boolean visible) {
+               fShell.setVisible(visible);
+       }
+
+       /*
+        * @see IInformationControl#dispose()
+        */
+       public void dispose() {
+               if (fShell != null) {
+                       if (!fShell.isDisposed())
+                               fShell.dispose();
+                       fShell = null;
+                       fTreeViewer = null;
+                       fComposite = null;
+                       fFilterText = null;
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
+        */
+       public boolean hasContents() {
+               return fTreeViewer != null && fTreeViewer.getInput() != null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int,
+        *      int)
+        */
+       public void setSizeConstraints(int maxWidth, int maxHeight) {
+               fMaxWidth = maxWidth;
+               fMaxHeight = maxHeight;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
+        */
+       public Point computeSizeHint() {
+               return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+       }
+
+       /*
+        * @see IInformationControl#setLocation(Point)
+        */
+       public void setLocation(Point location) {
+               Rectangle trim = fShell.computeTrim(0, 0, 0, 0);
+               Point textLocation = fComposite.getLocation();
+               location.x += trim.x - textLocation.x;
+               location.y += trim.y - textLocation.y;
+               fShell.setLocation(location);
+       }
+
+       /*
+        * @see IInformationControl#setSize(int, int)
+        */
+       public void setSize(int width, int height) {
+               fShell.setSize(width, height);
+       }
+
+       /*
+        * @see IInformationControl#addDisposeListener(DisposeListener)
+        */
+       public void addDisposeListener(DisposeListener listener) {
+               fShell.addDisposeListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#removeDisposeListener(DisposeListener)
+        */
+       public void removeDisposeListener(DisposeListener listener) {
+               fShell.removeDisposeListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#setForegroundColor(Color)
+        */
+       public void setForegroundColor(Color foreground) {
+               fTreeViewer.getTree().setForeground(foreground);
+               fFilterText.setForeground(foreground);
+               fComposite.setForeground(foreground);
+       }
+
+       /*
+        * @see IInformationControl#setBackgroundColor(Color)
+        */
+       public void setBackgroundColor(Color background) {
+               fTreeViewer.getTree().setBackground(background);
+               fFilterText.setBackground(background);
+               fComposite.setBackground(background);
+       }
+
+       /*
+        * @see IInformationControl#isFocusControl()
+        */
+       public boolean isFocusControl() {
+               return fTreeViewer.getControl().isFocusControl()
+                               || fFilterText.isFocusControl();
+       }
+
+       /*
+        * @see IInformationControl#setFocus()
+        */
+       public void setFocus() {
+               fShell.forceFocus();
+               fFilterText.setFocus();
+       }
+
+       /*
+        * @see IInformationControl#addFocusListener(FocusListener)
+        */
+       public void addFocusListener(FocusListener listener) {
+               fShell.addFocusListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#removeFocusListener(FocusListener)
+        */
+       public void removeFocusListener(FocusListener listener) {
+               fShell.removeFocusListener(listener);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaPresentationReconciler.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaPresentationReconciler.java
new file mode 100644 (file)
index 0000000..0b608f9
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+
+/**
+ * Presentation reconciler, adding functionality for operation without a viewer.
+ * 
+ * @since 3.0
+ */
+public class JavaPresentationReconciler extends PresentationReconciler {
+
+       /** Last used document */
+       private IDocument fLastDocument;
+
+       /**
+        * Constructs a "repair description" for the given damage and returns this
+        * description as a text presentation.
+        * <p>
+        * NOTE: Should not be used if this reconciler is installed on a viewer.
+        * </p>
+        * 
+        * @param damage
+        *            the damage to be repaired
+        * @param document
+        *            the document whose presentation must be repaired
+        * @return the presentation repair description as text presentation
+        */
+       public TextPresentation createRepairDescription(IRegion damage,
+                       IDocument document) {
+               if (document != fLastDocument) {
+                       setDocumentToDamagers(document);
+                       setDocumentToRepairers(document);
+               }
+               return createPresentation(damage, document);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaReconciler.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaReconciler.java
new file mode 100644 (file)
index 0000000..17106cc
--- /dev/null
@@ -0,0 +1,463 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.core.ElementChangedEvent;
+import net.sourceforge.phpdt.core.IElementChangedListener;
+import net.sourceforge.phpdt.core.JavaCore;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IMarkerDelta;
+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.IWorkspace;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.MonoReconciler;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.events.ShellListener;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * A reconciler that is also activated on editor activation.
+ */
+public class JavaReconciler extends MonoReconciler {
+
+       /**
+        * Internal part listener for activating the reconciler.
+        */
+       private class PartListener implements IPartListener {
+
+               /*
+                * @see org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart)
+                */
+               public void partActivated(IWorkbenchPart part) {
+                       if (part == fTextEditor && hasJavaModelChanged())
+                               JavaReconciler.this.forceReconciling();
+               }
+
+               /*
+                * @see org.eclipse.ui.IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart)
+                */
+               public void partBroughtToTop(IWorkbenchPart part) {
+               }
+
+               /*
+                * @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
+                */
+               public void partClosed(IWorkbenchPart part) {
+               }
+
+               /*
+                * @see org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart)
+                */
+               public void partDeactivated(IWorkbenchPart part) {
+                       if (part == fTextEditor)
+                               setJavaModelChanged(false);
+               }
+
+               /*
+                * @see org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
+                */
+               public void partOpened(IWorkbenchPart part) {
+               }
+       }
+
+       /**
+        * Internal Shell activation listener for activating the reconciler.
+        */
+       private class ActivationListener extends ShellAdapter {
+
+               private Control fControl;
+
+               public ActivationListener(Control control) {
+                       fControl = control;
+               }
+
+               /*
+                * @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent)
+                */
+               public void shellActivated(ShellEvent e) {
+                       if (!fControl.isDisposed() && fControl.isVisible()
+                                       && hasJavaModelChanged())
+                               JavaReconciler.this.forceReconciling();
+               }
+
+               /*
+                * @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
+                */
+               public void shellDeactivated(ShellEvent e) {
+                       setJavaModelChanged(false);
+               }
+       }
+
+       /**
+        * Internal Java element changed listener
+        * 
+        * @since 3.0
+        */
+       private class ElementChangedListener implements IElementChangedListener {
+               /*
+                * @see net.sourceforge.phpdt.core.IElementChangedListener#elementChanged(net.sourceforge.phpdt.core.ElementChangedEvent)
+                */
+               public void elementChanged(ElementChangedEvent event) {
+                       setJavaModelChanged(true);
+               }
+       }
+
+       /**
+        * Internal resource change listener.
+        * 
+        * @since 3.0
+        */
+       class ResourceChangeListener implements IResourceChangeListener {
+
+               private IResource getResource() {
+                       IEditorInput input = fTextEditor.getEditorInput();
+                       if (input instanceof IFileEditorInput) {
+                               IFileEditorInput fileInput = (IFileEditorInput) input;
+                               return fileInput.getFile();
+                       }
+                       return null;
+               }
+
+               /*
+                * @see IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+                */
+               public void resourceChanged(IResourceChangeEvent e) {
+                       IResourceDelta delta = e.getDelta();
+                       IResource resource = getResource();
+                       if (delta != null && resource != null) {
+                               IResourceDelta child = delta.findMember(resource.getFullPath());
+                               if (child != null) {
+                                       IMarkerDelta[] deltas = child.getMarkerDeltas();
+                                       if (deltas.length > 0)
+                                               forceReconciling();
+                               }
+                       }
+               }
+       }
+
+       /** The reconciler's editor */
+       private ITextEditor fTextEditor;
+
+       /** The part listener */
+       private IPartListener fPartListener;
+
+       /** The shell listener */
+       private ShellListener fActivationListener;
+
+       /**
+        * The mutex that keeps us from running multiple reconcilers on one editor.
+        * TODO remove once we have ensured that there is only one reconciler per
+        * editor.
+        */
+       private Object fMutex;
+
+       /**
+        * The Java element changed listener.
+        * 
+        * @since 3.0
+        */
+       private IElementChangedListener fJavaElementChangedListener;
+
+       /**
+        * Tells whether the Java model sent out a changed event.
+        * 
+        * @since 3.0
+        */
+       private volatile boolean fHasJavaModelChanged = true;
+
+       /**
+        * The resource change listener.
+        * 
+        * @since 3.0
+        */
+       private IResourceChangeListener fResourceChangeListener;
+
+       private boolean fIninitalProcessDone = false;
+
+       /**
+        * Creates a new reconciler.
+        */
+       public JavaReconciler(ITextEditor editor,
+                       JavaCompositeReconcilingStrategy strategy, boolean isIncremental) {
+               super(strategy, isIncremental);
+               fTextEditor = editor;
+
+               // https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898
+               // when re-using editors, a new reconciler is set up by the source
+               // viewer
+               // and the old one uninstalled. However, the old reconciler may still be
+               // running.
+               // To avoid having to reconcilers calling
+               // CompilationUnitEditor.reconciled,
+               // we synchronized on a lock object provided by the editor.
+               // The critical section is really the entire run() method of the
+               // reconciler
+               // thread, but synchronizing process() only will keep
+               // JavaReconcilingStrategy
+               // from running concurrently on the same editor.
+               // TODO remove once we have ensured that there is only one reconciler
+               // per editor.
+               if (editor instanceof PHPUnitEditor)
+                       fMutex = ((PHPUnitEditor) editor).getReconcilerLock();
+               else
+                       fMutex = new Object(); // Null Object
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconciler#install(org.eclipse.jface.text.ITextViewer)
+        */
+       public void install(ITextViewer textViewer) {
+               super.install(textViewer);
+
+               fPartListener = new PartListener();
+               IWorkbenchPartSite site = fTextEditor.getSite();
+               IWorkbenchWindow window = site.getWorkbenchWindow();
+               window.getPartService().addPartListener(fPartListener);
+
+               fActivationListener = new ActivationListener(textViewer.getTextWidget());
+               Shell shell = window.getShell();
+               shell.addShellListener(fActivationListener);
+
+               fJavaElementChangedListener = new ElementChangedListener();
+               JavaCore.addElementChangedListener(fJavaElementChangedListener);
+
+               fResourceChangeListener = new ResourceChangeListener();
+               IWorkspace workspace = WebUI.getWorkspace();
+               workspace.addResourceChangeListener(fResourceChangeListener);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconciler#uninstall()
+        */
+       public void uninstall() {
+
+               IWorkbenchPartSite site = fTextEditor.getSite();
+               IWorkbenchWindow window = site.getWorkbenchWindow();
+               window.getPartService().removePartListener(fPartListener);
+               fPartListener = null;
+
+               Shell shell = window.getShell();
+               if (shell != null && !shell.isDisposed())
+                       shell.removeShellListener(fActivationListener);
+               fActivationListener = null;
+
+               JavaCore.removeElementChangedListener(fJavaElementChangedListener);
+               fJavaElementChangedListener = null;
+
+               IWorkspace workspace = WebUI.getWorkspace();
+               workspace.removeResourceChangeListener(fResourceChangeListener);
+               fResourceChangeListener = null;
+
+               super.uninstall();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.AbstractReconciler#forceReconciling()
+        */
+       protected void forceReconciling() {
+               if (!fIninitalProcessDone)
+                       return;
+
+               super.forceReconciling();
+               JavaCompositeReconcilingStrategy strategy = (JavaCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
+               strategy.notifyListeners(false);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.AbstractReconciler#aboutToReconcile()
+        * @since 3.0
+        */
+       protected void aboutToBeReconciled() {
+               JavaCompositeReconcilingStrategy strategy = (JavaCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
+               strategy.aboutToBeReconciled();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.AbstractReconciler#reconcilerReset()
+        */
+       protected void reconcilerReset() {
+               super.reconcilerReset();
+               JavaCompositeReconcilingStrategy strategy = (JavaCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
+               strategy.notifyListeners(true);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.MonoReconciler#initialProcess()
+        */
+       protected void initialProcess() {
+               // TODO remove once we have ensured that there is only one reconciler
+               // per editor.
+               synchronized (fMutex) {
+                       super.initialProcess();
+               }
+               fIninitalProcessDone = true;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.MonoReconciler#process(org.eclipse.jface.text.reconciler.DirtyRegion)
+        */
+       protected void process(DirtyRegion dirtyRegion) {
+               // TODO remove once we have ensured that there is only one reconciler
+               // per editor.
+               synchronized (fMutex) {
+                       super.process(dirtyRegion);
+               }
+       }
+
+       /**
+        * Tells whether the Java Model has changed or not.
+        * 
+        * @return <code>true</code> iff the Java Model has changed
+        * @since 3.0
+        */
+       private synchronized boolean hasJavaModelChanged() {
+               return fHasJavaModelChanged;
+       }
+
+       /**
+        * Sets whether the Java Model has changed or not.
+        * 
+        * @param state
+        *            <code>true</code> iff the java model has changed
+        * @since 3.0
+        */
+       private synchronized void setJavaModelChanged(boolean state) {
+               fHasJavaModelChanged = state;
+       }
+}
+// /**
+// * A reconciler that is also activated on editor activation.
+// */
+// public class JavaReconciler extends MonoReconciler {
+//     
+// /**
+// * Internal part listener for activating the reconciler.
+// */
+// class PartListener implements IPartListener {
+//             
+// /*
+// * @see IPartListener#partActivated(IWorkbenchPart)
+// */
+// public void partActivated(IWorkbenchPart part) {
+// if (part == fTextEditor)
+// JavaReconciler.this.forceReconciling();
+// }
+//
+// /*
+// * @see IPartListener#partBroughtToTop(IWorkbenchPart)
+// */
+// public void partBroughtToTop(IWorkbenchPart part) {
+// }
+//
+// /*
+// * @see IPartListener#partClosed(IWorkbenchPart)
+// */
+// public void partClosed(IWorkbenchPart part) {
+// }
+//
+// /*
+// * @see IPartListener#partDeactivated(IWorkbenchPart)
+// */
+// public void partDeactivated(IWorkbenchPart part) {
+// }
+//
+// /*
+// * @see IPartListener#partOpened(IWorkbenchPart)
+// */
+// public void partOpened(IWorkbenchPart part) {
+// }
+// };
+//     
+//     
+// /** The reconciler's editor */
+// private ITextEditor fTextEditor;
+// /** The part listener */
+// private IPartListener fPartListener;
+//     
+//     
+// /**
+// * Creates a new reconciler.
+// */
+// public JavaReconciler(ITextEditor editor, IReconcilingStrategy strategy,
+// boolean isIncremental) {
+// super(strategy, isIncremental);
+// fTextEditor= editor;
+// }
+//     
+// /*
+// * @see IReconciler#install(ITextViewer)
+// */
+// public void install(ITextViewer textViewer) {
+// super.install(textViewer);
+//             
+// fPartListener= new PartListener();
+// IWorkbenchPartSite site= fTextEditor.getSite();
+// IWorkbenchWindow window= site.getWorkbenchWindow();
+// window.getPartService().addPartListener(fPartListener);
+// }
+//
+// /*
+// * @see IReconciler#uninstall()
+// */
+// public void uninstall() {
+//             
+// IWorkbenchPartSite site= fTextEditor.getSite();
+// IWorkbenchWindow window= site.getWorkbenchWindow();
+// window.getPartService().removePartListener(fPartListener);
+// fPartListener= null;
+//             
+// super.uninstall();
+// }
+//     
+// /*
+// * @see AbstractReconciler#forceReconciling()
+// */
+// protected void forceReconciling() {
+// super.forceReconciling();
+// IReconcilingStrategy strategy=
+// getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
+// if (strategy instanceof JavaReconcilingStrategy) {
+// JavaReconcilingStrategy java= (JavaReconcilingStrategy) strategy;
+// java.notifyParticipants(false);
+// }
+// }
+//    
+// /*
+// * @see AbstractReconciler#reconcilerReset()
+// */
+// protected void reconcilerReset() {
+// super.reconcilerReset();
+// IReconcilingStrategy strategy=
+// getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
+// if (strategy instanceof JavaReconcilingStrategy) {
+// JavaReconcilingStrategy java= (JavaReconcilingStrategy) strategy;
+// java.notifyParticipants(true);
+// }
+// }
+// }
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java
new file mode 100644 (file)
index 0000000..37944fb
--- /dev/null
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+public class JavaWordFinder {
+
+       public static IRegion findWord(IDocument document, int offset) {
+
+               int start = -1;
+               int end = -1;
+
+               try {
+
+                       int pos = offset;
+                       char c = ' ';
+
+                       while (pos >= 0) {
+                               c = document.getChar(pos);
+                               if (c == '$') {
+                                       --pos;
+                                       break;
+                               }
+                               if (!Scanner.isPHPIdentifierPart(c))
+                                       break;
+
+                               --pos;
+                       }
+
+                       start = pos;
+
+                       pos = offset;
+                       int length = document.getLength();
+
+                       while (pos < length) {
+                               c = document.getChar(pos);
+                               if (!Scanner.isPHPIdentifierPart(c))
+                                       break;
+                               ++pos;
+                       }
+
+                       end = pos;
+
+               } catch (BadLocationException x) {
+               }
+
+               if (start > -1 && end > -1) {
+                       if (start == offset && end == offset)
+                               return new Region(offset, 0);
+                       else if (start == offset)
+                               return new Region(start, end - start);
+                       else
+                               return new Region(start + 1, end - start - 1);
+               }
+
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaWordIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/JavaWordIterator.java
new file mode 100644 (file)
index 0000000..1c55ba9
--- /dev/null
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+
+import org.eclipse.jface.text.Assert;
+
+/**
+ * Breaks java text into word starts, also stops at line start and end. No
+ * direction dependency.
+ * 
+ * @since 3.0
+ */
+public class JavaWordIterator extends BreakIterator {
+
+       /**
+        * The underlying java break iterator. It returns all breaks, including
+        * before and after every whitespace.
+        */
+       private JavaBreakIterator fIterator;
+
+       /** The current index for the stateful operations. */
+       private int fIndex;
+
+       /**
+        * Creates a new word iterator.
+        */
+       public JavaWordIterator() {
+               fIterator = new JavaBreakIterator();
+               first();
+       }
+
+       /*
+        * @see java.text.BreakIterator#first()
+        */
+       public int first() {
+               fIndex = fIterator.first();
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#last()
+        */
+       public int last() {
+               fIndex = fIterator.last();
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#next(int)
+        */
+       public int next(int n) {
+               int next = 0;
+               while (--n > 0 && next != DONE) {
+                       next = next();
+               }
+               return next;
+       }
+
+       /*
+        * @see java.text.BreakIterator#next()
+        */
+       public int next() {
+               fIndex = following(fIndex);
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#previous()
+        */
+       public int previous() {
+               fIndex = preceding(fIndex);
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#preceding(int)
+        */
+       public int preceding(int offset) {
+               int first = fIterator.preceding(offset);
+               if (isWhitespace(first, offset)) {
+                       int second = fIterator.preceding(first);
+                       if (second != DONE && !isDelimiter(second, first))
+                               return second;
+               }
+               return first;
+       }
+
+       /*
+        * @see java.text.BreakIterator#following(int)
+        */
+       public int following(int offset) {
+               int first = fIterator.following(offset);
+               if (eatFollowingWhitespace(offset, first)) {
+                       int second = fIterator.following(first);
+                       if (isWhitespace(first, second))
+                               return second;
+               }
+               return first;
+       }
+
+       private boolean eatFollowingWhitespace(int offset, int exclusiveEnd) {
+               if (exclusiveEnd == DONE || offset == DONE)
+                       return false;
+
+               if (isWhitespace(offset, exclusiveEnd))
+                       return false;
+               if (isDelimiter(offset, exclusiveEnd))
+                       return false;
+
+               return true;
+       }
+
+       /**
+        * Returns <code>true</code> if the given sequence into the underlying
+        * text represents a delimiter, <code>false</code> otherwise.
+        * 
+        * @param offset
+        *            the offset
+        * @param exclusiveEnd
+        *            the end offset
+        * @return <code>true</code> if the given range is a delimiter
+        */
+       private boolean isDelimiter(int offset, int exclusiveEnd) {
+               if (exclusiveEnd == DONE || offset == DONE)
+                       return false;
+
+               Assert.isTrue(offset >= 0);
+               Assert.isTrue(exclusiveEnd <= getText().getEndIndex());
+               Assert.isTrue(exclusiveEnd > offset);
+
+               CharSequence seq = fIterator.fText;
+
+               while (offset < exclusiveEnd) {
+                       char ch = seq.charAt(offset);
+                       if (ch != '\n' && ch != '\r')
+                               return false;
+                       offset++;
+               }
+
+               return true;
+       }
+
+       /**
+        * Returns <code>true</code> if the given sequence into the underlying
+        * text represents whitespace, but not a delimiter, <code>false</code>
+        * otherwise.
+        * 
+        * @param offset
+        *            the offset
+        * @param exclusiveEnd
+        *            the end offset
+        * @return <code>true</code> if the given range is whitespace
+        */
+       private boolean isWhitespace(int offset, int exclusiveEnd) {
+               if (exclusiveEnd == DONE || offset == DONE)
+                       return false;
+
+               Assert.isTrue(offset >= 0);
+               Assert.isTrue(exclusiveEnd <= getText().getEndIndex());
+               Assert.isTrue(exclusiveEnd > offset);
+
+               CharSequence seq = fIterator.fText;
+
+               while (offset < exclusiveEnd) {
+                       char ch = seq.charAt(offset);
+                       if (!Character.isWhitespace(ch))
+                               return false;
+                       if (ch == '\n' || ch == '\r')
+                               return false;
+                       offset++;
+               }
+
+               return true;
+       }
+
+       /*
+        * @see java.text.BreakIterator#current()
+        */
+       public int current() {
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#getText()
+        */
+       public CharacterIterator getText() {
+               return fIterator.getText();
+       }
+
+       /**
+        * Sets the text as <code>CharSequence</code>.
+        * 
+        * @param newText
+        *            the new text
+        */
+       public void setText(CharSequence newText) {
+               fIterator.setText(newText);
+               first();
+       }
+
+       /*
+        * @see java.text.BreakIterator#setText(java.text.CharacterIterator)
+        */
+       public void setText(CharacterIterator newText) {
+               fIterator.setText(newText);
+               first();
+       }
+
+       /*
+        * @see java.text.BreakIterator#setText(java.lang.String)
+        */
+       public void setText(String newText) {
+               setText((CharSequence) newText);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/LineBreakingReader.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/LineBreakingReader.java
new file mode 100644 (file)
index 0000000..c69c0c8
--- /dev/null
@@ -0,0 +1,116 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.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;
+
+       /**
+        * 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 (pixes) 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();
+       }
+
+       public boolean isFormattedLine() {
+               return fLine != null;
+       }
+
+       /**
+        * Reads the next line. The lengths of the line will not exceed the gived
+        * maximum width.
+        */
+       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;
+                               } else {
+                                       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/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PHPCodeReader.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PHPCodeReader.java
new file mode 100644 (file)
index 0000000..fffffda
--- /dev/null
@@ -0,0 +1,256 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.IOException;
+
+import net.sourceforge.phpdt.internal.corext.phpdoc.SingleCharReader;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * Reads from a document either forwards or backwards. May be configured to skip
+ * comments and strings.
+ */
+public class PHPCodeReader extends SingleCharReader {
+
+       /** The EOF character */
+       public static final int EOF = -1;
+
+       private boolean fSkipComments = false;
+
+       private boolean fSkipStrings = false;
+
+       private boolean fForward = false;
+
+       private IDocument fDocument;
+
+       private int fOffset;
+
+       private int fEnd = -1;
+
+       private int fCachedLineNumber = -1;
+
+       private int fCachedLineOffset = -1;
+
+       public PHPCodeReader() {
+       }
+
+       /**
+        * Returns the offset of the last read character. Should only be called
+        * after read has been called.
+        */
+       public int getOffset() {
+               return fForward ? fOffset - 1 : fOffset;
+       }
+
+       public void configureForwardReader(IDocument document, int offset,
+                       int length, boolean skipComments, boolean skipStrings)
+                       throws IOException {
+               fDocument = document;
+               fOffset = offset;
+               fSkipComments = skipComments;
+               fSkipStrings = skipStrings;
+
+               fForward = true;
+               fEnd = Math.min(fDocument.getLength(), fOffset + length);
+       }
+
+       public void configureBackwardReader(IDocument document, int offset,
+                       boolean skipComments, boolean skipStrings) throws IOException {
+               fDocument = document;
+               fOffset = offset;
+               fSkipComments = skipComments;
+               fSkipStrings = skipStrings;
+
+               fForward = false;
+               try {
+                       fCachedLineNumber = fDocument.getLineOfOffset(fOffset);
+               } catch (BadLocationException x) {
+                       throw new IOException(x.getMessage());
+               }
+       }
+
+       /*
+        * @see Reader#close()
+        */
+       public void close() throws IOException {
+               fDocument = null;
+       }
+
+       /*
+        * @see SingleCharReader#read()
+        */
+       public int read() throws IOException {
+               try {
+                       return fForward ? readForwards() : readBackwards();
+               } catch (BadLocationException x) {
+                       throw new IOException(x.getMessage());
+               }
+       }
+
+       private void gotoCommentEnd() throws BadLocationException {
+               while (fOffset < fEnd) {
+                       char current = fDocument.getChar(fOffset++);
+                       if (current == '*') {
+                               if (fOffset < fEnd && fDocument.getChar(fOffset) == '/') {
+                                       ++fOffset;
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       private void gotoStringEnd(char delimiter) throws BadLocationException {
+               while (fOffset < fEnd) {
+                       char current = fDocument.getChar(fOffset++);
+                       if (current == '\\') {
+                               // ignore escaped characters
+                               ++fOffset;
+                       } else if (current == delimiter) {
+                               return;
+                       }
+               }
+       }
+
+       private void gotoLineEnd() throws BadLocationException {
+               int line = fDocument.getLineOfOffset(fOffset);
+               fOffset = fDocument.getLineOffset(line + 1);
+       }
+
+       private int readForwards() throws BadLocationException {
+               while (fOffset < fEnd) {
+                       char current = fDocument.getChar(fOffset++);
+
+                       switch (current) {
+                       case '"':
+                       case '\'':
+
+                               if (fSkipStrings) {
+                                       gotoStringEnd(current);
+                                       continue;
+                               }
+
+                               return current;
+                       case '#':
+
+                               if (fSkipComments && fOffset < fEnd) {
+                                       gotoLineEnd();
+                                       continue;
+                               }
+
+                               return current;
+
+                       case '/':
+
+                               if (fSkipComments && fOffset < fEnd) {
+                                       char next = fDocument.getChar(fOffset);
+                                       if (next == '*') {
+                                               // a comment starts, advance to the comment end
+                                               ++fOffset;
+                                               gotoCommentEnd();
+                                               continue;
+                                       } else if (next == '/') {
+                                               // '//'-comment starts, advance to the line end
+                                               gotoLineEnd();
+                                               continue;
+                                       }
+                               }
+
+                               return current;
+
+                       }
+
+                       return current;
+               }
+
+               return EOF;
+       }
+
+       private void handleSingleLineComment() throws BadLocationException {
+               int line = fDocument.getLineOfOffset(fOffset);
+               if (line < fCachedLineNumber) {
+                       fCachedLineNumber = line;
+                       fCachedLineOffset = fDocument.getLineOffset(line);
+                       int offset = fOffset;
+                       while (fCachedLineOffset < offset) {
+                               char current = fDocument.getChar(offset--);
+
+                               if (current == '/' && fCachedLineOffset <= offset
+                                               && fDocument.getChar(offset) == '/') {
+                                       fOffset = offset;
+                                       return;
+                               }
+
+                               if (current == '#' && fCachedLineOffset <= offset) {
+                                       fOffset = offset;
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       private void gotoCommentStart() throws BadLocationException {
+               while (0 < fOffset) {
+                       char current = fDocument.getChar(fOffset--);
+                       if (current == '*' && 0 <= fOffset
+                                       && fDocument.getChar(fOffset) == '/')
+                               return;
+               }
+       }
+
+       private void gotoStringStart(char delimiter) throws BadLocationException {
+               while (0 < fOffset) {
+                       char current = fDocument.getChar(fOffset);
+                       if (current == delimiter) {
+                               if (!(0 <= fOffset && fDocument.getChar(fOffset - 1) == '\\'))
+                                       return;
+                       }
+                       --fOffset;
+               }
+       }
+
+       private int readBackwards() throws BadLocationException {
+
+               while (0 < fOffset) {
+                       --fOffset;
+
+                       handleSingleLineComment();
+
+                       char current = fDocument.getChar(fOffset);
+                       switch (current) {
+                       case '/':
+
+                               if (fSkipComments && fOffset > 1) {
+                                       char next = fDocument.getChar(fOffset - 1);
+                                       if (next == '*') {
+                                               // a comment ends, advance to the comment start
+                                               fOffset -= 2;
+                                               gotoCommentStart();
+                                               continue;
+                                       }
+                               }
+
+                               return current;
+                       case '"':
+                       case '\'':
+
+                               if (fSkipStrings) {
+                                       --fOffset;
+                                       gotoStringStart(current);
+                                       continue;
+                               }
+
+                               return current;
+                       }
+
+                       return current;
+               }
+
+               return EOF;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PHPPairMatcher.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PHPPairMatcher.java
new file mode 100644 (file)
index 0000000..ab9abd5
--- /dev/null
@@ -0,0 +1,188 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.IOException;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.ICharacterPairMatcher;
+
+/**
+ * Helper class for match pairs of characters.
+ */
+public class PHPPairMatcher implements ICharacterPairMatcher {
+       protected char[] fPairs;
+
+       protected IDocument fDocument;
+
+       protected int fOffset;
+
+       protected int fStartPos;
+
+       protected int fEndPos;
+
+       protected int fAnchor;
+
+       protected PHPCodeReader fReader = new PHPCodeReader();
+
+       public PHPPairMatcher(char[] pairs) {
+               fPairs = pairs;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.ICharacterPairMatcher#clear()
+        */
+       public void clear() {
+               if (fReader != null) {
+                       try {
+                               fReader.close();
+                       } catch (IOException x) {
+                               // ignore
+                       }
+               }
+       }
+
+       public IRegion match(IDocument document, int offset) {
+
+               fOffset = offset;
+
+               if (fOffset < 0)
+                       return null;
+
+               fDocument = document;
+
+               if (matchPairsAt() && fStartPos != fEndPos)
+                       return new Region(fStartPos, fEndPos - fStartPos + 1);
+
+               return null;
+       }
+
+       public int getAnchor() {
+               return fAnchor;
+       }
+
+       public void dispose() {
+               fDocument = null;
+               if (fReader != null) {
+                       try {
+                               fReader.close();
+                       } catch (IOException x) {
+                               // ignore
+                       }
+                       fReader = null;
+               }
+       }
+
+       protected boolean matchPairsAt() {
+
+               int i;
+               int pairIndex1 = fPairs.length;
+               int pairIndex2 = fPairs.length;
+
+               fStartPos = -1;
+               fEndPos = -1;
+
+               // get the chars preceding and following the start position
+               try {
+
+                       char prevChar = fDocument.getChar(Math.max(fOffset - 1, 0));
+                       char nextChar = fDocument.getChar(fOffset);
+
+                       // search for opening peer character next to the activation point
+                       for (i = 0; i < fPairs.length; i = i + 2) {
+                               if (nextChar == fPairs[i]) {
+                                       fStartPos = fOffset;
+                                       pairIndex1 = i;
+                               } else if (prevChar == fPairs[i]) {
+                                       fStartPos = fOffset - 1;
+                                       pairIndex1 = i;
+                               }
+                       }
+
+                       // search for closing peer character next to the activation point
+                       for (i = 1; i < fPairs.length; i = i + 2) {
+                               if (prevChar == fPairs[i]) {
+                                       fEndPos = fOffset - 1;
+                                       pairIndex2 = i;
+                               } else if (nextChar == fPairs[i]) {
+                                       fEndPos = fOffset;
+                                       pairIndex2 = i;
+                               }
+                       }
+
+                       if (fEndPos > -1) {
+                               fAnchor = RIGHT;
+                               fStartPos = searchForOpeningPeer(fEndPos,
+                                               fPairs[pairIndex2 - 1], fPairs[pairIndex2], fDocument);
+                               if (fStartPos > -1)
+                                       return true;
+                               else
+                                       fEndPos = -1;
+                       } else if (fStartPos > -1) {
+                               fAnchor = LEFT;
+                               fEndPos = searchForClosingPeer(fStartPos, fPairs[pairIndex1],
+                                               fPairs[pairIndex1 + 1], fDocument);
+                               if (fEndPos > -1)
+                                       return true;
+                               else
+                                       fStartPos = -1;
+                       }
+
+               } catch (BadLocationException x) {
+               } catch (IOException x) {
+               }
+
+               return false;
+       }
+
+       protected int searchForClosingPeer(int offset, int openingPeer,
+                       int closingPeer, IDocument document) throws IOException {
+
+               fReader.configureForwardReader(document, offset + 1, document
+                               .getLength(), true, true);
+
+               int stack = 1;
+               int c = fReader.read();
+               while (c != PHPCodeReader.EOF) {
+                       if (c == openingPeer && c != closingPeer)
+                               stack++;
+                       else if (c == closingPeer)
+                               stack--;
+
+                       if (stack == 0)
+                               return fReader.getOffset();
+
+                       c = fReader.read();
+               }
+
+               return -1;
+       }
+
+       protected int searchForOpeningPeer(int offset, int openingPeer,
+                       int closingPeer, IDocument document) throws IOException {
+
+               fReader.configureBackwardReader(document, offset, true, true);
+
+               int stack = 1;
+               int c = fReader.read();
+               while (c != PHPCodeReader.EOF) {
+                       if (c == closingPeer && c != openingPeer)
+                               stack++;
+                       else if (c == openingPeer)
+                               stack--;
+
+                       if (stack == 0)
+                               return fReader.getOffset();
+
+                       c = fReader.read();
+               }
+
+               return -1;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PreferencesAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/PreferencesAdapter.java
new file mode 100644 (file)
index 0000000..acc8643
--- /dev/null
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * Adapts {@link org.eclipse.core.runtime.Preferences} to
+ * {@link org.eclipse.jface.preference.IPreferenceStore}
+ * 
+ * @since 3.0
+ */
+public class PreferencesAdapter implements IPreferenceStore {
+
+       /**
+        * Property change listener. Listens for events of type
+        * {@link org.eclipse.core.runtime.Preferences.PropertyChangeEvent} and
+        * fires a {@link org.eclipse.jface.util.PropertyChangeEvent} on the adapter
+        * with arguments from the received event.
+        */
+       private class PropertyChangeListener implements
+                       Preferences.IPropertyChangeListener {
+
+               /*
+                * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
+                */
+               public void propertyChange(Preferences.PropertyChangeEvent event) {
+                       firePropertyChangeEvent(event.getProperty(), event.getOldValue(),
+                                       event.getNewValue());
+               }
+       }
+
+       /** Listeners on the adapter */
+       private ListenerList fListeners = new ListenerList();
+
+       /** Listener on the adapted Preferences */
+       private PropertyChangeListener fListener = new PropertyChangeListener();
+
+       /** Adapted Preferences */
+       private Preferences fPreferences;
+
+       /** True iff no events should be forwarded */
+       private boolean fSilent;
+
+       /**
+        * Initialize with empty Preferences.
+        */
+       public PreferencesAdapter() {
+               this(new Preferences());
+       }
+
+       /**
+        * Initialize with the given Preferences.
+        * 
+        * @param preferences
+        *            The preferences to wrap.
+        */
+       public PreferencesAdapter(Preferences preferences) {
+               fPreferences = preferences;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void addPropertyChangeListener(IPropertyChangeListener listener) {
+               if (fListeners.size() == 0)
+                       fPreferences.addPropertyChangeListener(fListener);
+               fListeners.add(listener);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void removePropertyChangeListener(IPropertyChangeListener listener) {
+               fListeners.remove(listener);
+               if (fListeners.size() == 0)
+                       fPreferences.removePropertyChangeListener(fListener);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean contains(String name) {
+               return fPreferences.contains(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void firePropertyChangeEvent(String name, Object oldValue,
+                       Object newValue) {
+               if (!fSilent) {
+                       PropertyChangeEvent event = new PropertyChangeEvent(this, name,
+                                       oldValue, newValue);
+                       Object[] listeners = fListeners.getListeners();
+                       for (int i = 0; i < listeners.length; i++)
+                               ((IPropertyChangeListener) listeners[i]).propertyChange(event);
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean getBoolean(String name) {
+               return fPreferences.getBoolean(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean getDefaultBoolean(String name) {
+               return fPreferences.getDefaultBoolean(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public double getDefaultDouble(String name) {
+               return fPreferences.getDefaultDouble(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public float getDefaultFloat(String name) {
+               return fPreferences.getDefaultFloat(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public int getDefaultInt(String name) {
+               return fPreferences.getDefaultInt(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public long getDefaultLong(String name) {
+               return fPreferences.getDefaultLong(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public String getDefaultString(String name) {
+               return fPreferences.getDefaultString(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public double getDouble(String name) {
+               return fPreferences.getDouble(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public float getFloat(String name) {
+               return fPreferences.getFloat(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public int getInt(String name) {
+               return fPreferences.getInt(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public long getLong(String name) {
+               return fPreferences.getLong(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public String getString(String name) {
+               return fPreferences.getString(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean isDefault(String name) {
+               return fPreferences.isDefault(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean needsSaving() {
+               return fPreferences.needsSaving();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void putValue(String name, String value) {
+               try {
+                       fSilent = true;
+                       fPreferences.setValue(name, value);
+               } finally {
+                       fSilent = false;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, double value) {
+               fPreferences.setDefault(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, float value) {
+               fPreferences.setDefault(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, int value) {
+               fPreferences.setDefault(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, long value) {
+               fPreferences.setDefault(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, String defaultObject) {
+               fPreferences.setDefault(name, defaultObject);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setDefault(String name, boolean value) {
+               fPreferences.setDefault(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setToDefault(String name) {
+               fPreferences.setToDefault(name);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, double value) {
+               fPreferences.setValue(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, float value) {
+               fPreferences.setValue(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, int value) {
+               fPreferences.setValue(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, long value) {
+               fPreferences.setValue(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, String value) {
+               fPreferences.setValue(name, value);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setValue(String name, boolean value) {
+               fPreferences.setValue(name, value);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SequenceCharacterIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SequenceCharacterIterator.java
new file mode 100644 (file)
index 0000000..33a9906
--- /dev/null
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.text.CharacterIterator;
+
+import org.eclipse.jface.text.Assert;
+
+/**
+ * A <code>CharSequence</code> based implementation of
+ * <code>CharacterIterator</code>.
+ * 
+ * @since 3.0
+ */
+public class SequenceCharacterIterator implements CharacterIterator {
+
+       private int fIndex = -1;
+
+       private final CharSequence fSequence;
+
+       private final int fFirst;
+
+       private final int fLast;
+
+       private void invariant() {
+               Assert.isTrue(fIndex >= fFirst);
+               Assert.isTrue(fIndex <= fLast);
+       }
+
+       /**
+        * Creates an iterator for the entire sequence.
+        * 
+        * @param sequence
+        *            the sequence backing this iterator
+        */
+       public SequenceCharacterIterator(CharSequence sequence) {
+               this(sequence, 0);
+       }
+
+       /**
+        * Creates an iterator.
+        * 
+        * @param sequence
+        *            the sequence backing this iterator
+        * @param first
+        *            the first character to consider
+        * @throws IllegalArgumentException
+        *             if the indices are out of bounds
+        */
+       public SequenceCharacterIterator(CharSequence sequence, int first)
+                       throws IllegalArgumentException {
+               this(sequence, first, sequence.length());
+       }
+
+       /**
+        * Creates an iterator.
+        * 
+        * @param sequence
+        *            the sequence backing this iterator
+        * @param first
+        *            the first character to consider
+        * @param last
+        *            the last character index to consider
+        * @throws IllegalArgumentException
+        *             if the indices are out of bounds
+        */
+       public SequenceCharacterIterator(CharSequence sequence, int first, int last)
+                       throws IllegalArgumentException {
+               if (sequence == null)
+                       throw new NullPointerException();
+               if (first < 0 || first > last)
+                       throw new IllegalArgumentException();
+               if (last > sequence.length())
+                       throw new IllegalArgumentException();
+               fSequence = sequence;
+               fFirst = first;
+               fLast = last;
+               fIndex = first;
+               invariant();
+       }
+
+       /*
+        * @see java.text.CharacterIterator#first()
+        */
+       public char first() {
+               return setIndex(getBeginIndex());
+       }
+
+       /*
+        * @see java.text.CharacterIterator#last()
+        */
+       public char last() {
+               if (fFirst == fLast)
+                       return setIndex(getEndIndex());
+               else
+                       return setIndex(getEndIndex() - 1);
+       }
+
+       /*
+        * @see java.text.CharacterIterator#current()
+        */
+       public char current() {
+               if (fIndex >= fFirst && fIndex < fLast)
+                       return fSequence.charAt(fIndex);
+               else
+                       return DONE;
+       }
+
+       /*
+        * @see java.text.CharacterIterator#next()
+        */
+       public char next() {
+               return setIndex(Math.min(fIndex + 1, getEndIndex()));
+       }
+
+       /*
+        * @see java.text.CharacterIterator#previous()
+        */
+       public char previous() {
+               if (fIndex > getBeginIndex()) {
+                       return setIndex(fIndex - 1);
+               } else {
+                       return DONE;
+               }
+       }
+
+       /*
+        * @see java.text.CharacterIterator#setIndex(int)
+        */
+       public char setIndex(int position) {
+               if (position >= getBeginIndex() && position <= getEndIndex())
+                       fIndex = position;
+               else
+                       throw new IllegalArgumentException();
+
+               invariant();
+               return current();
+       }
+
+       /*
+        * @see java.text.CharacterIterator#getBeginIndex()
+        */
+       public int getBeginIndex() {
+               return fFirst;
+       }
+
+       /*
+        * @see java.text.CharacterIterator#getEndIndex()
+        */
+       public int getEndIndex() {
+               return fLast;
+       }
+
+       /*
+        * @see java.text.CharacterIterator#getIndex()
+        */
+       public int getIndex() {
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.CharacterIterator#clone()
+        */
+       public Object clone() {
+               try {
+                       return super.clone();
+               } catch (CloneNotSupportedException e) {
+                       throw new InternalError();
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SmartBackspaceManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SmartBackspaceManager.java
new file mode 100644 (file)
index 0000000..9f74ae9
--- /dev/null
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.text.TypingRun.ChangeType;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Installs as a verify key listener on a viewer and overwrites the behaviour of
+ * the backspace key. Clients may register undo specifications for certain
+ * offsets in a document. The <code>SmartBackspaceManager</code> will manage
+ * the specfications and execute the contained <code>TextEdit</code>s when
+ * backspace is pressed at the given offset and the specification is still
+ * valid.
+ * <p>
+ * Undo specifications are removed after a number of typing runs.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class SmartBackspaceManager {
+       /* independent of JDT - may be moved to jface.text */
+
+       /**
+        * An undo specification describes the change that should be executed if
+        * backspace is pressed at its trigger offset.
+        * 
+        * @since 3.0
+        */
+       public static final class UndoSpec {
+               private final int triggerOffset;
+
+               private final IRegion selection;
+
+               private final TextEdit[] undoEdits;
+
+               private final UndoSpec child;
+
+               int lives;
+
+               /**
+                * Creates a new spec. A specification consists of a number of
+                * <code>TextEdit</code> s that will be executed when backspace is
+                * pressed at <code>triggerOffset</code>. The spec will be removed
+                * when it is executed, or if more than <code>lives</code>
+                * <code>TypingRun</code>s
+                * have ended after registering the spec.
+                * <p>
+                * Optionally, a child specification can be registered. After executing
+                * the spec, the child spec will be registered with the manager. This
+                * allows to create chains of <code>UndoSpec</code>s that will be
+                * executed upon repeated pressing of backspace.
+                * </p>
+                * 
+                * @param triggerOffset
+                *            the offset where this spec is active
+                * @param selection
+                *            the selection after executing the undo spec
+                * @param edits
+                *            the <code>TextEdit</code> s to perform when executing
+                *            the spec
+                * @param lives
+                *            the number of <code>TypingRun</code> s before removing
+                *            the spec
+                * @param child
+                *            a child specification that will be registered after
+                *            executing this spec, or <code>null</code>
+                */
+               public UndoSpec(int triggerOffset, IRegion selection, TextEdit[] edits,
+                               int lives, UndoSpec child) {
+                       Assert.isLegal(triggerOffset >= 0);
+                       Assert.isLegal(selection != null);
+                       Assert.isLegal(lives >= 0);
+                       Assert.isLegal(edits != null);
+                       Assert.isLegal(edits.length > 0);
+                       for (int i = 0; i < edits.length; i++) {
+                               Assert.isLegal(edits[i] != null);
+                       }
+
+                       this.triggerOffset = triggerOffset;
+                       this.selection = selection;
+                       this.undoEdits = edits;
+                       this.lives = lives;
+                       this.child = child;
+               }
+       }
+
+       private class BackspaceListener implements VerifyKeyListener {
+
+               /*
+                * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
+                */
+               public void verifyKey(VerifyEvent event) {
+                       if (fViewer != null && isBackspace(event)) {
+                               int offset = getCaretOffset();
+                               UndoSpec spec = removeEdit(offset);
+                               if (spec != null) {
+                                       try {
+                                               beginChange();
+                                               for (int i = 0; i < spec.undoEdits.length; i++) {
+                                                       spec.undoEdits[i].apply(getDocument(),
+                                                                       TextEdit.UPDATE_REGIONS);
+                                               }
+                                               fViewer.setSelectedRange(spec.selection.getOffset(),
+                                                               spec.selection.getLength());
+                                               if (spec.child != null)
+                                                       register(spec.child);
+                                       } catch (MalformedTreeException e) {
+                                               // fall back to standard bs
+                                               return;
+                                       } catch (BadLocationException e) {
+                                               // fall back to standard bs
+                                               return;
+                                       } finally {
+                                               endChange();
+                                       }
+                                       event.doit = false;
+                               }
+
+                       }
+               }
+
+               private void beginChange() {
+                       ITextViewer viewer = fViewer;
+                       if (viewer instanceof TextViewer) {
+                               TextViewer v = (TextViewer) viewer;
+                               v.getRewriteTarget().beginCompoundChange();
+                               v.setRedraw(false);
+                       }
+               }
+
+               private void endChange() {
+                       ITextViewer viewer = fViewer;
+                       if (viewer instanceof TextViewer) {
+                               TextViewer v = (TextViewer) viewer;
+                               v.getRewriteTarget().endCompoundChange();
+                               v.setRedraw(true);
+                       }
+               }
+
+               private boolean isBackspace(VerifyEvent event) {
+                       return event.doit == true && event.character == SWT.BS
+                                       && event.stateMask == 0;
+               }
+
+               private int getCaretOffset() {
+                       ITextViewer viewer = fViewer;
+                       Point point = viewer.getSelectedRange();
+                       return point.x;
+               }
+
+       }
+
+       private ITextViewer fViewer;
+
+       private BackspaceListener fBackspaceListener;
+
+       private Map fSpecs;
+
+       private TypingRunDetector fRunDetector;
+
+       private ITypingRunListener fRunListener;
+
+       /**
+        * Registers an undo specification with this manager.
+        * 
+        * @param spec
+        *            the specification to register
+        * @throws IllegalStateException
+        *             if the manager is not installed
+        */
+       public void register(UndoSpec spec) {
+               if (fViewer == null)
+                       throw new IllegalStateException();
+
+               ensureListenerInstalled();
+               addEdit(spec);
+       }
+
+       private void addEdit(UndoSpec spec) {
+               Integer i = new Integer(spec.triggerOffset);
+               fSpecs.put(i, spec);
+       }
+
+       private UndoSpec removeEdit(int offset) {
+               Integer i = new Integer(offset);
+               UndoSpec spec = (UndoSpec) fSpecs.remove(i);
+               return spec;
+       }
+
+       private void ensureListenerInstalled() {
+               if (fBackspaceListener == null) {
+                       fBackspaceListener = new BackspaceListener();
+                       ITextViewer viewer = fViewer;
+                       if (viewer instanceof ITextViewerExtension)
+                               ((ITextViewerExtension) viewer)
+                                               .prependVerifyKeyListener(fBackspaceListener);
+                       else
+                               viewer.getTextWidget().addVerifyKeyListener(fBackspaceListener);
+               }
+       }
+
+       private void ensureListenerRemoved() {
+               if (fBackspaceListener != null) {
+                       ITextViewer viewer = fViewer;
+                       if (viewer instanceof ITextViewerExtension)
+                               ((ITextViewerExtension) viewer)
+                                               .removeVerifyKeyListener(fBackspaceListener);
+                       else
+                               viewer.getTextWidget().removeVerifyKeyListener(
+                                               fBackspaceListener);
+                       fBackspaceListener = null;
+               }
+       }
+
+       private IDocument getDocument() {
+               return fViewer.getDocument();
+       }
+
+       /**
+        * Installs the receiver on a text viewer.
+        * 
+        * @param viewer
+        */
+       public void install(ITextViewer viewer) {
+               Assert.isLegal(viewer != null);
+
+               fViewer = viewer;
+               fSpecs = new HashMap();
+               fRunDetector = new TypingRunDetector();
+               fRunDetector.install(viewer);
+               fRunListener = new ITypingRunListener() {
+
+                       /*
+                        * @see org.eclipse.jface.text.TypingRunDetector.ITypingRunListener#typingRunStarted(org.eclipse.jface.text.TypingRunDetector.TypingRun)
+                        */
+                       public void typingRunStarted(TypingRun run) {
+                       }
+
+                       /*
+                        * @see org.eclipse.jface.text.TypingRunDetector.ITypingRunListener#typingRunEnded(org.eclipse.jface.text.TypingRunDetector.TypingRun)
+                        */
+                       public void typingRunEnded(TypingRun run, ChangeType reason) {
+                               if (reason == TypingRun.SELECTION)
+                                       fSpecs.clear();
+                               else
+                                       prune();
+                       }
+               };
+               fRunDetector.addTypingRunListener(fRunListener);
+       }
+
+       private void prune() {
+               for (Iterator it = fSpecs.values().iterator(); it.hasNext();) {
+                       UndoSpec spec = (UndoSpec) it.next();
+                       if (--spec.lives < 0)
+                               it.remove();
+               }
+       }
+
+       /**
+        * Uninstalls the receiver. No undo specifications may be registered on an
+        * uninstalled manager.
+        */
+       public void uninstall() {
+               if (fViewer != null) {
+                       fRunDetector.removeTypingRunListener(fRunListener);
+                       fRunDetector.uninstall();
+                       fRunDetector = null;
+                       ensureListenerRemoved();
+                       fViewer = null;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java
new file mode 100644 (file)
index 0000000..00e57c1
--- /dev/null
@@ -0,0 +1,1299 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.Arrays;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.core.Assert;
+import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager.UndoSpec;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.texteditor.ITextEditorExtension2;
+import org.eclipse.ui.texteditor.ITextEditorExtension3;
+
+/**
+ * Modifies <code>DocumentCommand</code>s inserting semicolons and opening
+ * braces to place them smartly, i.e. moving them to the end of a line if that
+ * is what the user expects.
+ * 
+ * <p>
+ * In practice, semicolons and braces (and the caret) are moved to the end of
+ * the line if they are typed anywhere except for semicolons in a
+ * <code>for</code> statements definition. If the line contains a semicolon or
+ * brace after the current caret position, the cursor is moved after it.
+ * </p>
+ * 
+ * @see org.eclipse.jface.text.DocumentCommand
+ * @since 3.0
+ */
+public class SmartSemicolonAutoEditStrategy implements IAutoEditStrategy {
+
+       /** String representation of a semicolon. */
+       private static final String SEMICOLON = ";"; //$NON-NLS-1$
+
+       /** Char representation of a semicolon. */
+       private static final char SEMICHAR = ';';
+
+       /** String represenattion of a opening brace. */
+       private static final String BRACE = "{"; //$NON-NLS-1$
+
+       /** Char representation of a opening brace */
+       private static final char BRACECHAR = '{';
+
+       private char fCharacter;
+
+       private String fPartitioning;
+
+       /**
+        * Creates a new SmartSemicolonAutoEditStrategy.
+        * 
+        * @param partitioning
+        *            the document partitioning
+        */
+       public SmartSemicolonAutoEditStrategy(String partitioning) {
+               fPartitioning = partitioning;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument,
+        *      org.eclipse.jface.text.DocumentCommand)
+        */
+       public void customizeDocumentCommand(IDocument document,
+                       DocumentCommand command) {
+               // 0: early pruning
+               // also customize if <code>doit</code> is false (so it works in code
+               // completion situations)
+               // if (!command.doit)
+               // return;
+
+               if (command.text == null)
+                       return;
+
+               if (command.text.equals(SEMICOLON))
+                       fCharacter = SEMICHAR;
+               else if (command.text.equals(BRACE))
+                       fCharacter = BRACECHAR;
+               else
+                       return;
+
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               if (fCharacter == SEMICHAR
+                               && !store
+                                               .getBoolean(PreferenceConstants.EDITOR_SMART_SEMICOLON))
+                       return;
+               if (fCharacter == BRACECHAR
+                               && !store
+                                               .getBoolean(PreferenceConstants.EDITOR_SMART_OPENING_BRACE))
+                       return;
+
+               IWorkbenchPage page = WebUI.getActivePage();
+               if (page == null)
+                       return;
+               IEditorPart part = page.getActiveEditor();
+               if (!(part instanceof PHPUnitEditor))
+                       return;
+               PHPUnitEditor editor = (PHPUnitEditor) part;
+               if (editor.getInsertMode() != ITextEditorExtension3.SMART_INSERT
+                               || !editor.isEditable())
+                       return;
+               ITextEditorExtension2 extension = (ITextEditorExtension2) editor
+                               .getAdapter(ITextEditorExtension2.class);
+               if (extension != null && !extension.validateEditorInputState())
+                       return;
+               if (isMultilineSelection(document, command))
+                       return;
+
+               // 1: find concerned line / position in java code, location in statement
+               int pos = command.offset;
+               ITextSelection line;
+               try {
+                       IRegion l = document.getLineInformationOfOffset(pos);
+                       line = new TextSelection(document, l.getOffset(), l.getLength());
+               } catch (BadLocationException e) {
+                       return;
+               }
+
+               // 2: choose action based on findings (is for-Statement?)
+               // for now: compute the best position to insert the new character
+               int positionInLine = computeCharacterPosition(document, line, pos
+                               - line.getOffset(), fCharacter, fPartitioning);
+               int position = positionInLine + line.getOffset();
+
+               // never position before the current position!
+               if (position < pos)
+                       return;
+
+               // never double already existing content
+               if (alreadyPresent(document, fCharacter, position))
+                       return;
+
+               // don't do special processing if what we do is actually the normal
+               // behaviour
+               String insertion = adjustSpacing(document, position, fCharacter);
+               if (command.offset == position && insertion.equals(command.text))
+                       return;
+
+               try {
+
+                       final SmartBackspaceManager manager = (SmartBackspaceManager) editor
+                                       .getAdapter(SmartBackspaceManager.class);
+                       if (manager != null
+                                       && WebUI.getDefault().getPreferenceStore()
+                                                       .getBoolean(
+                                                                       PreferenceConstants.EDITOR_SMART_BACKSPACE)) {
+                               TextEdit e1 = new ReplaceEdit(command.offset, command.text
+                                               .length(), document.get(command.offset, command.length));
+                               UndoSpec s1 = new UndoSpec(command.offset
+                                               + command.text.length(), new Region(command.offset, 0),
+                                               new TextEdit[] { e1 }, 0, null);
+
+                               DeleteEdit smart = new DeleteEdit(position, insertion.length());
+                               ReplaceEdit raw = new ReplaceEdit(command.offset,
+                                               command.length, command.text);
+                               UndoSpec s2 = new UndoSpec(position + insertion.length(),
+                                               new Region(command.offset + command.text.length(), 0),
+                                               new TextEdit[] { smart, raw }, 2, s1);
+                               manager.register(s2);
+                       }
+
+                       // 3: modify command
+                       command.offset = position;
+                       command.length = 0;
+                       command.caretOffset = position;
+                       command.text = insertion;
+                       command.doit = true;
+                       command.owner = null;
+               } catch (MalformedTreeException e) {
+                       WebUI.log(e);
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+               }
+
+       }
+
+       /**
+        * Returns <code>true</code> if the document command is applied on a multi
+        * line selection, <code>false</code> otherwise.
+        * 
+        * @param document
+        *            the document
+        * @param command
+        *            the command
+        * @return <code>true</code> if <code>command</code> is a multiline
+        *         command
+        */
+       private boolean isMultilineSelection(IDocument document,
+                       DocumentCommand command) {
+               try {
+                       return document.getNumberOfLines(command.offset, command.length) > 1;
+               } catch (BadLocationException e) {
+                       // ignore
+                       return false;
+               }
+       }
+
+       /**
+        * Adds a space before a brace if it is inserted after a parenthesis, equal
+        * sign, or one of the keywords <code>try, else, do</code>.
+        * 
+        * @param document
+        *            the document we are working on
+        * @param position
+        *            the insert position of <code>character</code>
+        * @param character
+        *            the character to be inserted
+        * @return a <code>String</code> consisting of <code>character</code>
+        *         plus any additional spacing
+        */
+       private String adjustSpacing(IDocument doc, int position, char character) {
+               if (character == BRACECHAR) {
+                       if (position > 0 && position <= doc.getLength()) {
+                               int pos = position - 1;
+                               if (looksLike(doc, pos, ")") //$NON-NLS-1$
+                                               || looksLike(doc, pos, "=") //$NON-NLS-1$
+                                               || looksLike(doc, pos, "]") //$NON-NLS-1$
+                                               || looksLike(doc, pos, "try") //$NON-NLS-1$
+                                               || looksLike(doc, pos, "else") //$NON-NLS-1$
+                                               || looksLike(doc, pos, "synchronized") //$NON-NLS-1$
+                                               || looksLike(doc, pos, "static") //$NON-NLS-1$
+                                               || looksLike(doc, pos, "finally") //$NON-NLS-1$
+                                               || looksLike(doc, pos, "do")) //$NON-NLS-1$
+                                       return new String(new char[] { ' ', character });
+                       }
+               }
+
+               return new String(new char[] { character });
+       }
+
+       /**
+        * Checks whether a character to be inserted is already present at the
+        * insert location (perhaps separated by some whitespace from
+        * <code>position</code>.
+        * 
+        * @param document
+        *            the document we are working on
+        * @param position
+        *            the insert position of <code>ch</code>
+        * @param character
+        *            the character to be inserted
+        * @return <code>true</code> if <code>ch</code> is already present at
+        *         <code>location</code>, <code>false</code> otherwise
+        */
+       private boolean alreadyPresent(IDocument document, char ch, int position) {
+               int pos = firstNonWhitespaceForward(document, position, fPartitioning,
+                               document.getLength());
+               try {
+                       if (pos != -1 && document.getChar(pos) == ch)
+                               return true;
+               } catch (BadLocationException e) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Computes the next insert position of the given character in the current
+        * line.
+        * 
+        * @param document
+        *            the document we are working on
+        * @param line
+        *            the line where the change is being made
+        * @param offset
+        *            the position of the caret in the line when
+        *            <code>character</code> was typed
+        * @param character
+        *            the character to look for
+        * @param partitioning
+        *            the document partitioning
+        * @return the position where <code>character</code> should be inserted /
+        *         replaced
+        */
+       protected static int computeCharacterPosition(IDocument document,
+                       ITextSelection line, int offset, char character, String partitioning) {
+               String text = line.getText();
+               if (text == null)
+                       return 0;
+
+               int insertPos;
+               if (character == BRACECHAR) {
+
+                       insertPos = computeArrayInitializationPos(document, line, offset,
+                                       partitioning);
+
+                       if (insertPos == -1) {
+                               insertPos = computeAfterTryDoElse(document, line, offset);
+                       }
+
+                       if (insertPos == -1) {
+                               insertPos = computeAfterParenthesis(document, line, offset,
+                                               partitioning);
+                       }
+
+               } else if (character == SEMICHAR) {
+
+                       if (isForStatement(text, offset)) {
+                               insertPos = -1; // don't do anything in for statements, as semis
+                                                               // are vital part of these
+                       } else {
+                               int nextPartitionPos = nextPartitionOrLineEnd(document, line,
+                                               offset, partitioning);
+                               insertPos = startOfWhitespaceBeforeOffset(text,
+                                               nextPartitionPos);
+                               // if there is a semi present, return its location as
+                               // alreadyPresent() will take it out this way.
+                               if (insertPos > 0 && text.charAt(insertPos - 1) == character)
+                                       insertPos = insertPos - 1;
+                       }
+
+               } else {
+                       Assert.isTrue(false);
+                       return -1;
+               }
+
+               return insertPos;
+       }
+
+       /**
+        * Computes an insert position for an opening brace if <code>offset</code>
+        * maps to a position in <code>document</code> that looks like being the
+        * RHS of an assignment or like an array definition.
+        * 
+        * @param document
+        *            the document being modified
+        * @param line
+        *            the current line under investigation
+        * @param offset
+        *            the offset of the caret position, relative to the line start.
+        * @param partitioning
+        *            the document partitioning
+        * @return an insert position relative to the line start if
+        *         <code>line</code> looks like being an array initialization at
+        *         <code>offset</code>, -1 otherwise
+        */
+       private static int computeArrayInitializationPos(IDocument document,
+                       ITextSelection line, int offset, String partitioning) {
+               // search backward while WS, find = (not != <= >= ==) in default
+               // partition
+               int pos = offset + line.getOffset();
+
+               if (pos == 0)
+                       return -1;
+
+               int p = firstNonWhitespaceBackward(document, pos - 1, partitioning, -1);
+
+               if (p == -1)
+                       return -1;
+
+               try {
+
+                       char ch = document.getChar(p);
+                       if (ch != '=' && ch != ']')
+                               return -1;
+
+                       if (p == 0)
+                               return offset;
+
+                       p = firstNonWhitespaceBackward(document, p - 1, partitioning, -1);
+                       if (p == -1)
+                               return -1;
+
+                       ch = document.getChar(p);
+                       if (Scanner.isPHPIdentifierPart(ch) || ch == ']' || ch == '[')
+                               return offset;
+
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Computes an insert position for an opening brace if <code>offset</code>
+        * maps to a position in <code>document</code> involving a keyword taking
+        * a block after it. These are: <code>try</code>, <code>do</code>,
+        * <code>synchronized</code>, <code>static</code>,
+        * <code>finally</code>, or <code>else</code>.
+        * 
+        * @param document
+        *            the document being modified
+        * @param line
+        *            the current line under investigation
+        * @param offset
+        *            the offset of the caret position, relative to the line start.
+        * @return an insert position relative to the line start if
+        *         <code>line</code> contains one of the above keywords at or
+        *         before <code>offset</code>, -1 otherwise
+        */
+       private static int computeAfterTryDoElse(IDocument doc,
+                       ITextSelection line, int offset) {
+               // search backward while WS, find 'try', 'do', 'else' in default
+               // partition
+               int p = offset + line.getOffset();
+               p = firstWhitespaceToRight(doc, p);
+               if (p == -1)
+                       return -1;
+               p--;
+
+               if (looksLike(doc, p, "try") //$NON-NLS-1$
+                               || looksLike(doc, p, "do") //$NON-NLS-1$
+                               || looksLike(doc, p, "synchronized") //$NON-NLS-1$
+                               || looksLike(doc, p, "static") //$NON-NLS-1$
+                               || looksLike(doc, p, "finally") //$NON-NLS-1$
+                               || looksLike(doc, p, "else")) //$NON-NLS-1$
+                       return p + 1 - line.getOffset();
+
+               return -1;
+       }
+
+       /**
+        * Computes an insert position for an opening brace if <code>offset</code>
+        * maps to a position in <code>document</code> with a expression in
+        * parenthesis that will take a block after the closing parenthesis.
+        * 
+        * @param document
+        *            the document being modified
+        * @param line
+        *            the current line under investigation
+        * @param offset
+        *            the offset of the caret position, relative to the line start.
+        * @param partitioning
+        *            the document partitioning
+        * @return an insert position relative to the line start if
+        *         <code>line</code> contains a parenthesized expression that can
+        *         be followed by a block, -1 otherwise
+        */
+       private static int computeAfterParenthesis(IDocument document,
+                       ITextSelection line, int offset, String partitioning) {
+               // find the opening parenthesis for every closing parenthesis on the
+               // current line after offset
+               // return the position behind the closing parenthesis if it looks like a
+               // method declaration
+               // or an expression for an if, while, for, catch statement
+               int pos = offset + line.getOffset();
+               int length = line.getOffset() + line.getLength();
+               int scanTo = scanForward(document, pos, partitioning, length, '}');
+               if (scanTo == -1)
+                       scanTo = length;
+
+               int closingParen = findClosingParenToLeft(document, pos, partitioning) - 1;
+
+               while (true) {
+                       int startScan = closingParen + 1;
+                       closingParen = scanForward(document, startScan, partitioning,
+                                       scanTo, ')');
+                       if (closingParen == -1)
+                               break;
+
+                       int openingParen = findOpeningParenMatch(document, closingParen,
+                                       partitioning);
+
+                       // no way an expression at the beginning of the document can mean
+                       // anything
+                       if (openingParen < 1)
+                               break;
+
+                       // only select insert positions for parenthesis currently embracing
+                       // the caret
+                       if (openingParen > pos)
+                               continue;
+
+                       if (looksLikeAnonymousClassDef(document, openingParen - 1,
+                                       partitioning))
+                               return closingParen + 1 - line.getOffset();
+
+                       if (looksLikeIfWhileForCatch(document, openingParen - 1,
+                                       partitioning))
+                               return closingParen + 1 - line.getOffset();
+
+                       if (looksLikeMethodDecl(document, openingParen - 1, partitioning))
+                               return closingParen + 1 - line.getOffset();
+
+               }
+
+               return -1;
+       }
+
+       /**
+        * Finds a closing parenthesis to the left of <code>position</code> in
+        * document, where that parenthesis is only separated by whitespace from
+        * <code>position</code>. If no such parenthesis can be found,
+        * <code>position</code> is returned.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @return the position of a closing parenthesis left to
+        *         <code>position</code> separated only by whitespace, or
+        *         <code>position</code> if no parenthesis can be found
+        */
+       private static int findClosingParenToLeft(IDocument document, int position,
+                       String partitioning) {
+               final char CLOSING_PAREN = ')';
+               try {
+                       if (position < 1)
+                               return position;
+
+                       int nonWS = firstNonWhitespaceBackward(document, position - 1,
+                                       partitioning, -1);
+                       if (nonWS != -1 && document.getChar(nonWS) == CLOSING_PAREN)
+                               return nonWS;
+               } catch (BadLocationException e1) {
+               }
+               return position;
+       }
+
+       /**
+        * Finds the first whitespace character position to the right of (and
+        * including) <code>position</code>.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @return the position of a whitespace character greater or equal than
+        *         <code>position</code> separated only by whitespace, or -1 if
+        *         none found
+        */
+       private static int firstWhitespaceToRight(IDocument document, int position) {
+               int length = document.getLength();
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(position <= length);
+
+               try {
+                       while (position < length) {
+                               char ch = document.getChar(position);
+                               if (Character.isWhitespace(ch))
+                                       return position;
+                               position++;
+                       }
+                       return position;
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Finds the highest position in <code>document</code> such that the
+        * position is &lt;= <code>position</code> and &gt; <code>bound</code>
+        * and <code>Character.isWhitespace(document.getChar(pos))</code>
+        * evaluates to <code>false</code> and the position is in the default
+        * partition.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @param bound
+        *            the first position in <code>document</code> to not consider
+        *            any more, with <code>bound</code> &gt; <code>position</code>
+        * @return the highest position of one element in <code>chars</code> in [<code>position</code>,
+        *         <code>scanTo</code>) that resides in a Java partition, or
+        *         <code>-1</code> if none can be found
+        */
+       private static int firstNonWhitespaceBackward(IDocument document,
+                       int position, String partitioning, int bound) {
+               Assert.isTrue(position < document.getLength());
+               Assert.isTrue(bound >= -1);
+
+               try {
+                       while (position > bound) {
+                               char ch = document.getChar(position);
+                               if (!Character.isWhitespace(ch)
+                                               && isDefaultPartition(document, position, partitioning))
+                                       return position;
+                               position--;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Finds the smallest position in <code>document</code> such that the
+        * position is &gt;= <code>position</code> and &lt; <code>bound</code>
+        * and <code>Character.isWhitespace(document.getChar(pos))</code>
+        * evaluates to <code>false</code> and the position is in the default
+        * partition.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @param bound
+        *            the first position in <code>document</code> to not consider
+        *            any more, with <code>bound</code> &gt; <code>position</code>
+        * @return the smallest position of one element in <code>chars</code> in [<code>position</code>,
+        *         <code>scanTo</code>) that resides in a Java partition, or
+        *         <code>-1</code> if none can be found
+        */
+       private static int firstNonWhitespaceForward(IDocument document,
+                       int position, String partitioning, int bound) {
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(bound <= document.getLength());
+
+               try {
+                       while (position < bound) {
+                               char ch = document.getChar(position);
+                               if (!Character.isWhitespace(ch)
+                                               && isDefaultPartition(document, position, partitioning))
+                                       return position;
+                               position++;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Finds the highest position in <code>document</code> such that the
+        * position is &lt;= <code>position</code> and &gt; <code>bound</code>
+        * and <code>document.getChar(position) == ch</code> evaluates to
+        * <code>true</code> for at least one ch in <code>chars</code> and the
+        * position is in the default partition.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @param bound
+        *            the first position in <code>document</code> to not consider
+        *            any more, with <code>scanTo</code> &gt;
+        *            <code>position</code>
+        * @param chars
+        *            an array of <code>char</code> to search for
+        * @return the highest position of one element in <code>chars</code> in (<code>bound</code>,
+        *         <code>position</code>] that resides in a Java partition, or
+        *         <code>-1</code> if none can be found
+        */
+       private static int scanBackward(IDocument document, int position,
+                       String partitioning, int bound, char[] chars) {
+               Assert.isTrue(bound >= -1);
+               Assert.isTrue(position < document.getLength());
+
+               Arrays.sort(chars);
+
+               try {
+                       while (position > bound) {
+
+                               if (Arrays.binarySearch(chars, document.getChar(position)) >= 0
+                                               && isDefaultPartition(document, position, partitioning))
+                                       return position;
+
+                               position--;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       // /**
+       // * Finds the highest position in <code>document</code> such that the
+       // position is &lt;= <code>position</code>
+       // * and &gt; <code>bound</code> and <code>document.getChar(position) ==
+       // ch</code> evaluates to <code>true</code>
+       // * and the position is in the default partition.
+       // *
+       // * @param document the document being modified
+       // * @param position the first character position in <code>document</code>
+       // to be considered
+       // * @param bound the first position in <code>document</code> to not
+       // consider any more, with <code>scanTo</code> &gt; <code>position</code>
+       // * @param chars an array of <code>char</code> to search for
+       // * @return the highest position of one element in <code>chars</code> in
+       // [<code>position</code>, <code>scanTo</code>) that resides in a Java
+       // partition, or <code>-1</code> if none can be found
+       // */
+       // private static int scanBackward(IDocument document, int position, int
+       // bound, char ch) {
+       // return scanBackward(document, position, bound, new char[] {ch});
+       // }
+       //
+       /**
+        * Finds the lowest position in <code>document</code> such that the
+        * position is &gt;= <code>position</code> and &lt; <code>bound</code>
+        * and <code>document.getChar(position) == ch</code> evaluates to
+        * <code>true</code> for at least one ch in <code>chars</code> and the
+        * position is in the default partition.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @param bound
+        *            the first position in <code>document</code> to not consider
+        *            any more, with <code>scanTo</code> &gt;
+        *            <code>position</code>
+        * @param chars
+        *            an array of <code>char</code> to search for
+        * @return the lowest position of one element in <code>chars</code> in [<code>position</code>,
+        *         <code>bound</code>) that resides in a Java partition, or
+        *         <code>-1</code> if none can be found
+        */
+       private static int scanForward(IDocument document, int position,
+                       String partitioning, int bound, char[] chars) {
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(bound <= document.getLength());
+
+               Arrays.sort(chars);
+
+               try {
+                       while (position < bound) {
+
+                               if (Arrays.binarySearch(chars, document.getChar(position)) >= 0
+                                               && isDefaultPartition(document, position, partitioning))
+                                       return position;
+
+                               position++;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Finds the lowest position in <code>document</code> such that the
+        * position is &gt;= <code>position</code> and &lt; <code>bound</code>
+        * and <code>document.getChar(position) == ch</code> evaluates to
+        * <code>true</code> and the position is in the default partition.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @param bound
+        *            the first position in <code>document</code> to not consider
+        *            any more, with <code>scanTo</code> &gt;
+        *            <code>position</code>
+        * @param chars
+        *            an array of <code>char</code> to search for
+        * @return the lowest position of one element in <code>chars</code> in [<code>position</code>,
+        *         <code>bound</code>) that resides in a Java partition, or
+        *         <code>-1</code> if none can be found
+        */
+       private static int scanForward(IDocument document, int position,
+                       String partitioning, int bound, char ch) {
+               return scanForward(document, position, partitioning, bound,
+                               new char[] { ch });
+       }
+
+       /**
+        * Checks whether the content of <code>document</code> in the range (<code>offset</code>,
+        * <code>length</code>) contains the <code>new</code> keyword.
+        * 
+        * @param document
+        *            the document being modified
+        * @param offset
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param length
+        *            the length of the character range to be considered
+        * @param partitioning
+        *            the document partitioning
+        * @return <code>true</code> if the specified character range contains a
+        *         <code>new</code> keyword, <code>false</code> otherwise.
+        */
+       private static boolean isNewMatch(IDocument document, int offset,
+                       int length, String partitioning) {
+               Assert.isTrue(length >= 0);
+               Assert.isTrue(offset >= 0);
+               Assert.isTrue(offset + length < document.getLength() + 1);
+
+               try {
+                       String text = document.get(offset, length);
+                       int pos = text.indexOf("new"); //$NON-NLS-1$
+
+                       while (pos != -1
+                                       && !isDefaultPartition(document, pos + offset, partitioning))
+                               pos = text.indexOf("new", pos + 2); //$NON-NLS-1$
+
+                       if (pos < 0)
+                               return false;
+
+                       if (pos != 0 && Scanner.isPHPIdentifierPart(text.charAt(pos - 1)))
+                               return false;
+
+                       if (pos + 3 < length
+                                       && Scanner.isPHPIdentifierPart(text.charAt(pos + 3)))
+                               return false;
+
+                       return true;
+
+               } catch (BadLocationException e) {
+               }
+               return false;
+       }
+
+       /**
+        * Checks whether the content of <code>document</code> at
+        * <code>position</code> looks like an anonymous class definition.
+        * <code>position</code> must be to the left of the opening parenthesis of
+        * the definition's parameter list.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @return <code>true</code> if the content of <code>document</code>
+        *         looks like an anonymous class definition, <code>false</code>
+        *         otherwise
+        */
+       private static boolean looksLikeAnonymousClassDef(IDocument document,
+                       int position, String partitioning) {
+               int previousCommaOrParen = scanBackward(document, position - 1,
+                               partitioning, -1, new char[] { ',', '(' });
+               if (previousCommaOrParen == -1 || position < previousCommaOrParen + 5) // 2
+                                                                                                                                                               // for
+                                                                                                                                                               // borders,
+                                                                                                                                                               // 3
+                                                                                                                                                               // for
+                                                                                                                                                               // "new"
+                       return false;
+
+               if (isNewMatch(document, previousCommaOrParen + 1, position
+                               - previousCommaOrParen - 2, partitioning))
+                       return true;
+
+               return false;
+       }
+
+       /**
+        * Checks whether <code>position</code> resides in a default (Java)
+        * partition of <code>document</code>.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the position to be checked
+        * @param partitioning
+        *            the document partitioning
+        * @return <code>true</code> if <code>position</code> is in the default
+        *         partition of <code>document</code>, <code>false</code>
+        *         otherwise
+        */
+       private static boolean isDefaultPartition(IDocument document, int position,
+                       String partitioning) {
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(position <= document.getLength());
+
+               try {
+                       // don't use getPartition2 since we're interested in the scanned
+                       // character's partition
+                       ITypedRegion region = TextUtilities.getPartition(document,
+                                       partitioning, position, false);
+                       return region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE);
+
+               } catch (BadLocationException e) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Finds the position of the parenthesis matching the closing parenthesis at
+        * <code>position</code>.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the position in <code>document</code> of a closing
+        *            parenthesis
+        * @param partitioning
+        *            the document partitioning
+        * @return the position in <code>document</code> of the matching
+        *         parenthesis, or -1 if none can be found
+        */
+       private static int findOpeningParenMatch(IDocument document, int position,
+                       String partitioning) {
+               final char CLOSING_PAREN = ')';
+               final char OPENING_PAREN = '(';
+
+               Assert.isTrue(position < document.getLength());
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(isDefaultPartition(document, position, partitioning));
+
+               try {
+
+                       Assert.isTrue(document.getChar(position) == CLOSING_PAREN);
+
+                       int depth = 1;
+                       while (true) {
+                               position = scanBackward(document, position - 1, partitioning,
+                                               -1, new char[] { CLOSING_PAREN, OPENING_PAREN });
+                               if (position == -1)
+                                       return -1;
+
+                               if (document.getChar(position) == CLOSING_PAREN)
+                                       depth++;
+                               else
+                                       depth--;
+
+                               if (depth == 0)
+                                       return position;
+                       }
+
+               } catch (BadLocationException e) {
+                       return -1;
+               }
+       }
+
+       /**
+        * Checks whether, to the left of <code>position</code> and separated only
+        * by whitespace, <code>document</code> contains a keyword taking a
+        * parameter list and a block after it. These are: <code>if</code>,
+        * <code>while</code>, <code>catch</code>, <code>for</code>,
+        * <code>synchronized</code>, <code>switch</code>.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @return <code>true</code> if <code>document</code> contains any of
+        *         the above keywords to the left of <code>position</code>,
+        *         <code>false</code> otherwise
+        */
+       private static boolean looksLikeIfWhileForCatch(IDocument document,
+                       int position, String partitioning) {
+               position = firstNonWhitespaceBackward(document, position, partitioning,
+                               -1);
+               if (position == -1)
+                       return false;
+
+               return looksLike(document, position, "if") //$NON-NLS-1$
+                               || looksLike(document, position, "while") //$NON-NLS-1$
+                               || looksLike(document, position, "catch") //$NON-NLS-1$
+                               || looksLike(document, position, "synchronized") //$NON-NLS-1$
+                               || looksLike(document, position, "switch") //$NON-NLS-1$
+                               || looksLike(document, position, "for"); //$NON-NLS-1$
+       }
+
+       /**
+        * Checks whether code>document</code> contains the <code>String</code> <code>like</code>
+        * such that its last character is at <code>position</code>. If <code>like</code>
+        * starts with a identifier part (as determined by
+        * {@link Scanner#isPHPIdentifierPart(char)}), it is also made sure that
+        * <code>like</code> is preceded by some non-identifier character or
+        * stands at the document start.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param like
+        *            the <code>String</code> to look for.
+        * @return <code>true</code> if <code>document</code> contains <code>like</code>
+        *         such that it ends at <code>position</code>, <code>false</code>
+        *         otherwise
+        */
+       private static boolean looksLike(IDocument document, int position,
+                       String like) {
+               int length = like.length();
+               if (position < length - 1)
+                       return false;
+
+               try {
+                       if (!like.equals(document.get(position - length + 1, length)))
+                               return false;
+
+                       if (position >= length
+                                       && Scanner.isPHPIdentifierPart(like.charAt(0))
+                                       && Scanner.isPHPIdentifierPart(document.getChar(position
+                                                       - length)))
+                               return false;
+
+               } catch (BadLocationException e) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * Checks whether the content of <code>document</code> at
+        * <code>position</code> looks like a method declaration header (i.e. only
+        * the return type and method name). <code>position</code> must be just
+        * left of the opening parenthesis of the parameter list.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @return <code>true</code> if the content of <code>document</code>
+        *         looks like a method definition, <code>false</code> otherwise
+        */
+       private static boolean looksLikeMethodDecl(IDocument document,
+                       int position, String partitioning) {
+
+               // method name
+               position = eatIdentToLeft(document, position, partitioning);
+               if (position < 1)
+                       return false;
+
+               position = eatBrackets(document, position - 1, partitioning);
+               if (position < 1)
+                       return false;
+
+               position = eatIdentToLeft(document, position - 1, partitioning);
+
+               return position != -1;
+       }
+
+       /**
+        * From <code>position</code> to the left, eats any whitespace and then a
+        * pair of brackets as used to declare an array return type like
+        * 
+        * <pre>
+        * String [ ]
+        * </pre>. The return value is either the position of the opening bracket
+        * or <code>position</code> if no pair of brackets can be parsed.
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @return the smallest character position of bracket pair or
+        *         <code>position</code>
+        */
+       private static int eatBrackets(IDocument document, int position,
+                       String partitioning) {
+               // accept array return type
+               int pos = firstNonWhitespaceBackward(document, position, partitioning,
+                               -1);
+               try {
+                       if (pos > 1 && document.getChar(pos) == ']') {
+                               pos = firstNonWhitespaceBackward(document, pos - 1,
+                                               partitioning, -1);
+                               if (pos > 0 && document.getChar(pos) == '[')
+                                       return pos;
+                       }
+               } catch (BadLocationException e) {
+                       // won't happen
+               }
+               return position;
+       }
+
+       /**
+        * From <code>position</code> to the left, eats any whitespace and the
+        * first identifier, returning the position of the first identifier
+        * character (in normal read order).
+        * <p>
+        * When called on a document with content <code>" some string  "</code> and
+        * positionition 13, the return value will be 6 (the first letter in
+        * <code>string</code>).
+        * </p>
+        * 
+        * @param document
+        *            the document being modified
+        * @param position
+        *            the first character position in <code>document</code> to be
+        *            considered
+        * @param partitioning
+        *            the document partitioning
+        * @return the smallest character position of an identifier or -1 if none
+        *         can be found; always &lt;= <code>position</code>
+        */
+       private static int eatIdentToLeft(IDocument document, int position,
+                       String partitioning) {
+               if (position < 0)
+                       return -1;
+               Assert.isTrue(position < document.getLength());
+
+               int p = firstNonWhitespaceBackward(document, position, partitioning, -1);
+               if (p == -1)
+                       return -1;
+
+               try {
+                       while (p >= 0) {
+
+                               char ch = document.getChar(p);
+                               if (Scanner.isPHPIdentifierPart(ch)) {
+                                       p--;
+                                       continue;
+                               }
+
+                               // length must be > 0
+                               if (Character.isWhitespace(ch) && p != position)
+                                       return p + 1;
+                               else
+                                       return -1;
+
+                       }
+
+                       // start of document reached
+                       return 0;
+
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Returns a position in the first java partition after the last non-empty
+        * and non-comment partition. There is no non-whitespace from the returned
+        * position to the end of the partition it is contained in.
+        * 
+        * @param document
+        *            the document being modified
+        * @param line
+        *            the line under investigation
+        * @param offset
+        *            the caret offset into <code>line</code>
+        * @param partitioning
+        *            the document partitioning
+        * @return the position of the next Java partition, or the end of
+        *         <code>line</code>
+        */
+       private static int nextPartitionOrLineEnd(IDocument document,
+                       ITextSelection line, int offset, String partitioning) {
+               // run relative to document
+               final int docOffset = offset + line.getOffset();
+               final int eol = line.getOffset() + line.getLength();
+               int nextPartitionPos = eol; // init with line end
+               int validPosition = docOffset;
+
+               try {
+                       ITypedRegion partition = TextUtilities.getPartition(document,
+                                       partitioning, nextPartitionPos, true);
+                       validPosition = getValidPositionForPartition(document, partition,
+                                       eol);
+                       while (validPosition == -1) {
+                               nextPartitionPos = partition.getOffset() - 1;
+                               if (nextPartitionPos < docOffset) {
+                                       validPosition = docOffset;
+                                       break;
+                               }
+                               partition = TextUtilities.getPartition(document, partitioning,
+                                               nextPartitionPos, false);
+                               validPosition = getValidPositionForPartition(document,
+                                               partition, eol);
+                       }
+               } catch (BadLocationException e) {
+               }
+
+               validPosition = Math.max(validPosition, docOffset);
+               // make relative to line
+               validPosition -= line.getOffset();
+               return validPosition;
+       }
+
+       /**
+        * Returns a valid insert location (except for whitespace) in
+        * <code>partition</code> or -1 if there is no valid insert location. An
+        * valid insert location is right after any java string or character
+        * partition, or at the end of a java default partition, but never behind
+        * <code>maxOffset</code>. Comment partitions or empty java partitions do
+        * never yield valid insert positions.
+        * 
+        * @param doc
+        *            the document being modified
+        * @param partition
+        *            the current partition
+        * @param maxOffset
+        *            the maximum offset to consider
+        * @return a valid insert location in <code>partition</code>, or -1 if
+        *         there is no valid insert location
+        */
+       private static int getValidPositionForPartition(IDocument doc,
+                       ITypedRegion partition, int maxOffset) {
+               final int INVALID = -1;
+
+               if (IPHPPartitions.PHP_PHPDOC_COMMENT.equals(partition.getType()))
+                       return INVALID;
+               if (IPHPPartitions.PHP_MULTILINE_COMMENT.equals(partition.getType()))
+                       return INVALID;
+               if (IPHPPartitions.PHP_SINGLELINE_COMMENT.equals(partition.getType()))
+                       return INVALID;
+
+               int endOffset = Math.min(maxOffset, partition.getOffset()
+                               + partition.getLength());
+
+               // if (IPHPPartitions.JAVA_CHARACTER.equals(partition.getType()))
+               // return endOffset;
+               if (IPHPPartitions.PHP_STRING_DQ.equals(partition.getType()))
+                       return endOffset;
+               if (IPHPPartitions.PHP_STRING_SQ.equals(partition.getType()))
+                       return endOffset;
+               if (IPHPPartitions.PHP_STRING_HEREDOC.equals(partition.getType()))
+                       return endOffset;
+               if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) {
+                       try {
+                               if (doc.get(partition.getOffset(),
+                                               endOffset - partition.getOffset()).trim().length() == 0)
+                                       return INVALID;
+                               else
+                                       return endOffset;
+                       } catch (BadLocationException e) {
+                               return INVALID;
+                       }
+               }
+               // default: we don't know anything about the partition - assume valid
+               return endOffset;
+       }
+
+       /**
+        * Determines whether the current line contains a for statement. Algorithm:
+        * any "for" word in the line is a positive, "for" contained in a string
+        * literal will produce a false positive.
+        * 
+        * @param line
+        *            the line where the change is being made
+        * @param offset
+        *            the position of the caret
+        * @return <code>true</code> if <code>line</code> contains
+        *         <code>for</code>, <code>false</code> otherwise
+        */
+       private static boolean isForStatement(String line, int offset) {
+               /* searching for (^|\s)for(\s|$) */
+               int forPos = line.indexOf("for"); //$NON-NLS-1$
+               if (forPos != -1) {
+                       if ((forPos == 0 || !Scanner.isPHPIdentifierPart(line
+                                       .charAt(forPos - 1)))
+                                       && (line.length() == forPos + 3 || !Scanner
+                                                       .isPHPIdentifierPart(line.charAt(forPos + 3))))
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Returns the position in <code>text</code> after which there comes only
+        * whitespace, up to <code>offset</code>.
+        * 
+        * @param text
+        *            the text being searched
+        * @param offset
+        *            the maximum offset to search for
+        * @return the smallest value <code>v</code> such that
+        *         <code>text.substring(v, offset).trim() == 0</code>
+        */
+       private static int startOfWhitespaceBeforeOffset(String text, int offset) {
+               int i = Math.min(offset, text.length());
+               for (; i >= 1; i--) {
+                       if (!Character.isWhitespace(text.charAt(i - 1)))
+                               break;
+               }
+               return i;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SubstitutionTextReader.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/SubstitutionTextReader.java
new file mode 100644 (file)
index 0000000..cc89ebe
--- /dev/null
@@ -0,0 +1,155 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import net.sourceforge.phpdt.internal.corext.phpdoc.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;
+
+       private 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;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/Symbols.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/Symbols.java
new file mode 100644 (file)
index 0000000..eeba337
--- /dev/null
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+/**
+ * Symbols for the heuristic java scanner.
+ * 
+ * @since 3.0
+ */
+public interface Symbols {
+       int TokenEOF = -1;
+
+       int TokenLBRACE = 1;
+
+       int TokenRBRACE = 2;
+
+       int TokenLBRACKET = 3;
+
+       int TokenRBRACKET = 4;
+
+       int TokenLPAREN = 5;
+
+       int TokenRPAREN = 6;
+
+       int TokenSEMICOLON = 7;
+
+       int TokenOTHER = 8;
+
+       int TokenCOLON = 9;
+
+       int TokenQUESTIONMARK = 10;
+
+       int TokenCOMMA = 11;
+
+       int TokenEQUAL = 12;
+
+       int TokenIF = 109;
+
+       int TokenDO = 1010;
+
+       int TokenFOR = 1011;
+
+       int TokenTRY = 1012;
+
+       int TokenCASE = 1013;
+
+       int TokenELSE = 1014;
+
+       int TokenBREAK = 1015;
+
+       int TokenCATCH = 1016;
+
+       int TokenWHILE = 1017;
+
+       int TokenRETURN = 1018;
+
+       int TokenSTATIC = 1019;
+
+       int TokenSWITCH = 1020;
+
+       int TokenFINALLY = 1021;
+
+       int TokenSYNCHRONIZED = 1022;
+
+       int TokenGOTO = 1023;
+
+       int TokenDEFAULT = 1024;
+
+       int TokenNEW = 1025;
+
+       int TokenIDENT = 2000;
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRun.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRun.java
new file mode 100644 (file)
index 0000000..6a2cd02
--- /dev/null
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+/**
+ * Describes a run of similar typing changes.
+ * <p>
+ * XXX to be extended with further information, e.g. offset, length, and content
+ * of the run.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public final class TypingRun {
+       /**
+        * A change of type <code>DELETE</code> deletes one single character
+        * (through delete or backspace or empty paste).
+        */
+       public static final ChangeType DELETE = new ChangeType(true, "DELETE"); //$NON-NLS-1$
+
+       /**
+        * A change of type <code>INSERT</code> inserts one single character
+        * (normal typing).
+        */
+       public static final ChangeType INSERT = new ChangeType(true, "INSERT"); //$NON-NLS-1$
+
+       /**
+        * A change of type <code>NO_CHANGE</code> does not change anything.
+        */
+       public static final ChangeType NO_CHANGE = new ChangeType(false,
+                       "NO_CHANGE"); //$NON-NLS-1$
+
+       /**
+        * A change of type <code>OVERTYPE</code> replaces one single character
+        * (overwrite mode, pasting a single character).
+        */
+       public static final ChangeType OVERTYPE = new ChangeType(true, "OVERTYPE"); //$NON-NLS-1$
+
+       /**
+        * A change of type <code>SELECTION</code> does not change text, but
+        * changes the focus, or selection. Such a change ends all typing runs.
+        */
+       public static final ChangeType SELECTION = new ChangeType(false,
+                       "SELECTION"); //$NON-NLS-1$
+
+       /**
+        * A change of type <code>UNKNOWN</code> modifies text in an unspecified
+        * way. An example is pasting more than one character, or deleting an entire
+        * selection, or reverting a file. Such a change ends all typing runs and
+        * cannot form a typing run with any other change, including a change of
+        * type <code>UNKNOWN</code>.
+        */
+       public static final ChangeType UNKNOWN = new ChangeType(true, "UNKNOWN"); //$NON-NLS-1$
+
+       /**
+        * Enumeration of change types.
+        * 
+        * @since 3.0
+        */
+       public static final class ChangeType {
+               private final boolean fIsModification;
+
+               private final String fName;
+
+               /** Private ctor for type safe enumeration. */
+               private ChangeType(boolean isRunPart, String name) {
+                       fIsModification = isRunPart;
+                       fName = name;
+               }
+
+               /**
+                * Returns <code>true</code> if changes of this type modify text.
+                * 
+                * @return <code>true</code> if changes of this type modify text,
+                *         <code>false</code> otherwise
+                */
+               boolean isModification() {
+                       return fIsModification;
+               }
+
+               /*
+                * @see java.lang.Object#toString()
+                */
+               public String toString() {
+                       return fName;
+               }
+       }
+
+       /**
+        * Creates a new run.
+        * 
+        * @param type
+        *            the type of the run
+        */
+       TypingRun(ChangeType type) {
+               this.type = type;
+       }
+
+       /** The change type of this run. */
+       public final ChangeType type;
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRunDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRunDetector.java
new file mode 100644 (file)
index 0000000..d74a9c3
--- /dev/null
@@ -0,0 +1,491 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import net.sourceforge.phpdt.internal.ui.text.TypingRun.ChangeType;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+
+/**
+ * When connected to a text viewer, a <code>TypingRunDetector</code> observes
+ * <code>TypingRun</code> events. A typing run is a sequence of similar text
+ * modifications, such as inserting or deleting single characters.
+ * <p>
+ * Listeners are informed about the start and end of a <code>TypingRun</code>.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class TypingRunDetector {
+       /*
+        * Implementation note: This class is independent of JDT and may be pulled
+        * up to jface.text if needed.
+        */
+
+       /** Debug flag. */
+       private static final boolean DEBUG = false;
+
+       /**
+        * Instances of this class abstract a text modification into a simple
+        * description. Typing runs consists of a sequence of one or more modifying
+        * changes of the same type. Every change records the type of change
+        * described by a text modification, and an offset it can be followed by
+        * another change of the same run.
+        */
+       private static final class Change {
+               private ChangeType fType;
+
+               private int fNextOffset;
+
+               /**
+                * Creates a new change of type <code>type</code>.
+                * 
+                * @param type
+                *            the <code>ChangeType</code> of the new change
+                * @param nextOffset
+                *            the offset of the next change in a typing run
+                */
+               public Change(ChangeType type, int nextOffset) {
+                       fType = type;
+                       fNextOffset = nextOffset;
+               }
+
+               /**
+                * Returns <code>true</code> if the receiver can extend the typing
+                * range the last change of which is described by <code>change</code>.
+                * 
+                * @param change
+                *            the last change in a typing run
+                * @return <code>true</code> if the receiver is a valid extension to
+                *         <code>change</code>,<code>false</code> otherwise
+                */
+               public boolean canFollow(Change change) {
+                       if (fType == TypingRun.NO_CHANGE)
+                               return true;
+                       else if (fType.equals(TypingRun.UNKNOWN))
+                               return false;
+                       if (fType.equals(change.fType)) {
+                               if (fType == TypingRun.DELETE)
+                                       return fNextOffset == change.fNextOffset - 1;
+                               else if (fType == TypingRun.INSERT)
+                                       return fNextOffset == change.fNextOffset + 1;
+                               else if (fType == TypingRun.OVERTYPE)
+                                       return fNextOffset == change.fNextOffset + 1;
+                               else if (fType == TypingRun.SELECTION)
+                                       return true;
+                       }
+                       return false;
+               }
+
+               /**
+                * Returns <code>true</code> if the receiver describes a text
+                * modification, <code>false</code> if it describes a focus /
+                * selection change.
+                * 
+                * @return <code>true</code> if the receiver is a text modification
+                */
+               public boolean isModification() {
+                       return fType.isModification();
+               }
+
+               /*
+                * @see java.lang.Object#toString()
+                */
+               public String toString() {
+                       return fType.toString() + "@" + fNextOffset; //$NON-NLS-1$
+               }
+
+               /**
+                * Returns the change type of this change.
+                * 
+                * @return the change type of this change
+                */
+               public ChangeType getType() {
+                       return fType;
+               }
+       }
+
+       /**
+        * Observes any events that modify the content of the document displayed in
+        * the editor. Since text events may start a new run, this listener is
+        * always registered if the detector is connected.
+        */
+       private class TextListener implements ITextListener {
+
+               /*
+                * @see org.eclipse.jface.text.ITextListener#textChanged(org.eclipse.jface.text.TextEvent)
+                */
+               public void textChanged(TextEvent event) {
+                       handleTextChanged(event);
+               }
+       }
+
+       /**
+        * Observes non-modifying events that will end a run, such as clicking into
+        * the editor, moving the caret, and the editor losing focus. These events
+        * can never start a run, therefore this listener is only registered if
+        * there is an ongoing run.
+        */
+       private class SelectionListener implements MouseListener, KeyListener,
+                       FocusListener {
+
+               /*
+                * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+                */
+               public void focusGained(FocusEvent e) {
+                       handleSelectionChanged();
+               }
+
+               /*
+                * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+                */
+               public void focusLost(FocusEvent e) {
+               }
+
+               /*
+                * @see MouseListener#mouseDoubleClick
+                */
+               public void mouseDoubleClick(MouseEvent e) {
+               }
+
+               /*
+                * If the right mouse button is pressed, the current editing command is
+                * closed
+                * 
+                * @see MouseListener#mouseDown
+                */
+               public void mouseDown(MouseEvent e) {
+                       if (e.button == 1)
+                               handleSelectionChanged();
+               }
+
+               /*
+                * @see MouseListener#mouseUp
+                */
+               public void mouseUp(MouseEvent e) {
+               }
+
+               /*
+                * @see KeyListener#keyPressed
+                */
+               public void keyReleased(KeyEvent e) {
+               }
+
+               /*
+                * On cursor keys, the current editing command is closed
+                * 
+                * @see KeyListener#keyPressed
+                */
+               public void keyPressed(KeyEvent e) {
+                       switch (e.keyCode) {
+                       case SWT.ARROW_UP:
+                       case SWT.ARROW_DOWN:
+                       case SWT.ARROW_LEFT:
+                       case SWT.ARROW_RIGHT:
+                       case SWT.END:
+                       case SWT.HOME:
+                       case SWT.PAGE_DOWN:
+                       case SWT.PAGE_UP:
+                               handleSelectionChanged();
+                               break;
+                       }
+               }
+       }
+
+       /** The listeners. */
+       private final Set fListeners = new HashSet();
+
+       /**
+        * The viewer we work upon. Set to <code>null</code> in
+        * <code>uninstall</code>.
+        */
+       private ITextViewer fViewer;
+
+       /** The text event listener. */
+       private final TextListener fTextListener = new TextListener();
+
+       /**
+        * The selection listener. Set to <code>null</code> when no run is active.
+        */
+       private SelectionListener fSelectionListener;
+
+       /* state variables */
+
+       /** The most recently observed change. Never <code>null</code>. */
+       private Change fLastChange;
+
+       /** The current run, or <code>null</code> if there is none. */
+       private TypingRun fRun;
+
+       /**
+        * Installs the receiver with a text viewer.
+        * 
+        * @param viewer
+        *            the viewer to install on
+        */
+       public void install(ITextViewer viewer) {
+               Assert.isLegal(viewer != null);
+               fViewer = viewer;
+               connect();
+       }
+
+       /**
+        * Initializes the state variables and registers any permanent listeners.
+        */
+       private void connect() {
+               if (fViewer != null) {
+                       fLastChange = new Change(TypingRun.UNKNOWN, -1);
+                       fRun = null;
+                       fSelectionListener = null;
+                       fViewer.addTextListener(fTextListener);
+               }
+       }
+
+       /**
+        * Uninstalls the receiver and removes all listeners. <code>install()</code>
+        * must be called for events to be generated.
+        */
+       public void uninstall() {
+               if (fViewer != null) {
+                       fListeners.clear();
+                       disconnect();
+                       fViewer = null;
+               }
+       }
+
+       /**
+        * Disconnects any registered listeners.
+        */
+       private void disconnect() {
+               fViewer.removeTextListener(fTextListener);
+               ensureSelectionListenerRemoved();
+       }
+
+       /**
+        * Adds a listener for <code>TypingRun</code> events. Repeatedly adding
+        * the same listener instance has no effect. Listeners may be added even if
+        * the receiver is neither connected nor installed.
+        * 
+        * @param listener
+        *            the listener add
+        */
+       public void addTypingRunListener(ITypingRunListener listener) {
+               Assert.isLegal(listener != null);
+               fListeners.add(listener);
+               if (fListeners.size() == 1)
+                       connect();
+       }
+
+       /**
+        * Removes the listener from this manager. If <code>listener</code> is not
+        * registered with the receiver, nothing happens.
+        * 
+        * @param listener
+        *            the listener to remove, or <code>null</code>
+        */
+       public void removeTypingRunListener(ITypingRunListener listener) {
+               fListeners.remove(listener);
+               if (fListeners.size() == 0)
+                       disconnect();
+       }
+
+       /**
+        * Handles an incoming text event.
+        * 
+        * @param event
+        *            the text event that describes the text modification
+        */
+       void handleTextChanged(TextEvent event) {
+               Change type = computeChange(event);
+               handleChange(type);
+       }
+
+       /**
+        * Computes the change abstraction given a text event.
+        * 
+        * @param event
+        *            the text event to analyze
+        * @return a change object describing the event
+        */
+       private Change computeChange(TextEvent event) {
+               DocumentEvent e = event.getDocumentEvent();
+               if (e == null)
+                       return new Change(TypingRun.NO_CHANGE, -1);
+
+               int start = e.getOffset();
+               int end = e.getOffset() + e.getLength();
+               String newText = e.getText();
+               if (newText == null)
+                       newText = new String();
+
+               if (start == end) {
+                       // no replace / delete / overwrite
+                       if (newText.length() == 1)
+                               return new Change(TypingRun.INSERT, end + 1);
+               } else if (start == end - 1) {
+                       if (newText.length() == 1)
+                               return new Change(TypingRun.OVERTYPE, end);
+                       if (newText.length() == 0)
+                               return new Change(TypingRun.DELETE, start);
+               }
+
+               return new Change(TypingRun.UNKNOWN, -1);
+       }
+
+       /**
+        * Handles an incoming selection event.
+        */
+       void handleSelectionChanged() {
+               handleChange(new Change(TypingRun.SELECTION, -1));
+       }
+
+       /**
+        * State machine. Changes state given the current state and the incoming
+        * change.
+        * 
+        * @param change
+        *            the incoming change
+        */
+       private void handleChange(Change change) {
+               if (change.getType() == TypingRun.NO_CHANGE)
+                       return;
+
+               if (DEBUG)
+                       System.err.println("Last change: " + fLastChange); //$NON-NLS-1$
+
+               if (!change.canFollow(fLastChange))
+                       endIfStarted(change);
+               fLastChange = change;
+               if (change.isModification())
+                       startOrContinue();
+
+               if (DEBUG)
+                       System.err.println("New change: " + change); //$NON-NLS-1$
+       }
+
+       /**
+        * Starts a new run if there is none and informs all listeners. If there
+        * already is a run, nothing happens.
+        */
+       private void startOrContinue() {
+               if (!hasRun()) {
+                       if (DEBUG)
+                               System.err.println("+Start run"); //$NON-NLS-1$
+                       fRun = new TypingRun(fLastChange.getType());
+                       ensureSelectionListenerAdded();
+                       fireRunBegun(fRun);
+               }
+       }
+
+       /**
+        * Returns <code>true</code> if there is an active run, <code>false</code>
+        * otherwise.
+        * 
+        * @return <code>true</code> if there is an active run, <code>false</code>
+        *         otherwise
+        */
+       private boolean hasRun() {
+               return fRun != null;
+       }
+
+       /**
+        * Ends any active run and informs all listeners. If there is none, nothing
+        * happens.
+        * 
+        * @param change
+        *            the change that triggered ending the active run
+        */
+       private void endIfStarted(Change change) {
+               if (hasRun()) {
+                       ensureSelectionListenerRemoved();
+                       if (DEBUG)
+                               System.err.println("-End run"); //$NON-NLS-1$
+                       fireRunEnded(fRun, change.getType());
+                       fRun = null;
+               }
+       }
+
+       /**
+        * Adds the selection listener to the text widget underlying the viewer, if
+        * not already done.
+        */
+       private void ensureSelectionListenerAdded() {
+               if (fSelectionListener == null) {
+                       fSelectionListener = new SelectionListener();
+                       StyledText textWidget = fViewer.getTextWidget();
+                       textWidget.addFocusListener(fSelectionListener);
+                       textWidget.addKeyListener(fSelectionListener);
+                       textWidget.addMouseListener(fSelectionListener);
+               }
+       }
+
+       /**
+        * If there is a selection listener, it is removed from the text widget
+        * underlying the viewer.
+        */
+       private void ensureSelectionListenerRemoved() {
+               if (fSelectionListener != null) {
+                       StyledText textWidget = fViewer.getTextWidget();
+                       textWidget.removeFocusListener(fSelectionListener);
+                       textWidget.removeKeyListener(fSelectionListener);
+                       textWidget.removeMouseListener(fSelectionListener);
+                       fSelectionListener = null;
+               }
+       }
+
+       /**
+        * Informs all listeners about a newly started <code>TypingRun</code>.
+        * 
+        * @param run
+        *            the new run
+        */
+       private void fireRunBegun(TypingRun run) {
+               List listeners = new ArrayList(fListeners);
+               for (Iterator it = listeners.iterator(); it.hasNext();) {
+                       ITypingRunListener listener = (ITypingRunListener) it.next();
+                       listener.typingRunStarted(fRun);
+               }
+       }
+
+       /**
+        * Informs all listeners about an ended <code>TypingRun</code>.
+        * 
+        * @param run
+        *            the previously active run
+        * @param reason
+        *            the type of change that caused the run to be ended
+        */
+       private void fireRunEnded(TypingRun run, ChangeType reason) {
+               List listeners = new ArrayList(fListeners);
+               for (Iterator it = listeners.iterator(); it.hasNext();) {
+                       ITypingRunListener listener = (ITypingRunListener) it.next();
+                       listener.typingRunEnded(fRun, reason);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/comment/CommentFormattingContext.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/comment/CommentFormattingContext.java
new file mode 100644 (file)
index 0000000..127f285
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.comment;
+
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.jface.text.formatter.FormattingContext;
+
+/**
+ * Formatting context for the comment formatter.
+ * 
+ * @since 3.0
+ */
+public class CommentFormattingContext extends FormattingContext {
+
+       /*
+        * @see org.eclipse.jface.text.formatter.IFormattingContext#getPreferenceKeys()
+        */
+       public String[] getPreferenceKeys() {
+               return new String[] {
+                               PreferenceConstants.FORMATTER_COMMENT_FORMAT,
+                               PreferenceConstants.FORMATTER_COMMENT_FORMATHEADER,
+                               PreferenceConstants.FORMATTER_COMMENT_FORMATSOURCE,
+                               PreferenceConstants.FORMATTER_COMMENT_INDENTPARAMETERDESCRIPTION,
+                               PreferenceConstants.FORMATTER_COMMENT_INDENTROOTTAGS,
+                               PreferenceConstants.FORMATTER_COMMENT_NEWLINEFORPARAMETER,
+                               PreferenceConstants.FORMATTER_COMMENT_SEPARATEROOTTAGS,
+                               PreferenceConstants.FORMATTER_COMMENT_LINELENGTH,
+                               PreferenceConstants.FORMATTER_COMMENT_CLEARBLANKLINES,
+                               PreferenceConstants.FORMATTER_COMMENT_FORMATHTML };
+       }
+
+       /*
+        * @see org.eclipse.jface.text.formatter.IFormattingContext#isBooleanPreference(java.lang.String)
+        */
+       public boolean isBooleanPreference(String key) {
+               return !key.equals(PreferenceConstants.FORMATTER_COMMENT_LINELENGTH);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.formatter.IFormattingContext#isIntegerPreference(java.lang.String)
+        */
+       public boolean isIntegerPreference(String key) {
+               return key.equals(PreferenceConstants.FORMATTER_COMMENT_LINELENGTH);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java
new file mode 100644 (file)
index 0000000..42d14eb
--- /dev/null
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.folding;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.preferences.OverlayPreferenceStore;
+import net.sourceforge.phpdt.internal.ui.preferences.OverlayPreferenceStore.OverlayKey;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingPreferenceBlock;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+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.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Java default folding preferences.
+ * 
+ * @since 3.0
+ */
+public class DefaultJavaFoldingPreferenceBlock implements
+               IJavaFoldingPreferenceBlock {
+
+       private IPreferenceStore fStore;
+
+       private OverlayPreferenceStore fOverlayStore;
+
+       private OverlayKey[] fKeys;
+
+       private Map fCheckBoxes = new HashMap();
+
+       private SelectionListener fCheckBoxListener = new SelectionListener() {
+               public void widgetDefaultSelected(SelectionEvent e) {
+               }
+
+               public void widgetSelected(SelectionEvent e) {
+                       Button button = (Button) e.widget;
+                       fOverlayStore.setValue((String) fCheckBoxes.get(button), button
+                                       .getSelection());
+               }
+       };
+
+       public DefaultJavaFoldingPreferenceBlock() {
+               fStore = WebUI.getDefault().getPreferenceStore();
+               fKeys = createKeys();
+               fOverlayStore = new OverlayPreferenceStore(fStore, fKeys);
+       }
+
+       private OverlayKey[] createKeys() {
+               ArrayList overlayKeys = new ArrayList();
+
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_FOLDING_JAVADOC));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_FOLDING_HEADERS));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_FOLDING_INNERTYPES));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+                               OverlayPreferenceStore.BOOLEAN,
+                               PreferenceConstants.EDITOR_FOLDING_METHODS));
+               // overlayKeys.add(new
+               // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+               // PreferenceConstants.EDITOR_FOLDING_IMPORTS));
+
+               return (OverlayKey[]) overlayKeys.toArray(new OverlayKey[overlayKeys
+                               .size()]);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.IJavaFoldingPreferences#createControl(org.eclipse.swt.widgets.Group)
+        */
+       public Control createControl(Composite composite) {
+               fOverlayStore.load();
+               fOverlayStore.start();
+
+               Composite inner = new Composite(composite, SWT.NONE);
+               GridLayout layout = new GridLayout(1, true);
+               layout.verticalSpacing = 3;
+               layout.marginWidth = 0;
+               inner.setLayout(layout);
+
+               Label label = new Label(inner, SWT.LEFT);
+               label.setText(FoldingMessages
+                               .getString("DefaultJavaFoldingPreferenceBlock.title")); //$NON-NLS-1$
+
+               addCheckBox(
+                               inner,
+                               FoldingMessages
+                                               .getString("DefaultJavaFoldingPreferenceBlock.comments"), PreferenceConstants.EDITOR_FOLDING_JAVADOC, 0); //$NON-NLS-1$
+               addCheckBox(
+                               inner,
+                               FoldingMessages
+                                               .getString("DefaultJavaFoldingPreferenceBlock.headers"), PreferenceConstants.EDITOR_FOLDING_HEADERS, 0);//$NON-NLS-1$
+               addCheckBox(inner, FoldingMessages
+                               .getString("DefaultJavaFoldingPreferenceBlock.innerTypes"),
+                               PreferenceConstants.EDITOR_FOLDING_INNERTYPES, 0); //$NON-NLS-1$
+               addCheckBox(
+                               inner,
+                               FoldingMessages
+                                               .getString("DefaultJavaFoldingPreferenceBlock.methods"), PreferenceConstants.EDITOR_FOLDING_METHODS, 0); //$NON-NLS-1$
+               // addCheckBox(inner,
+               // FoldingMessages.getString("DefaultJavaFoldingPreferenceBlock.imports"),
+               // PreferenceConstants.EDITOR_FOLDING_IMPORTS, 0); //$NON-NLS-1$
+
+               return inner;
+       }
+
+       private Button addCheckBox(Composite parent, String label, String key,
+                       int indentation) {
+               Button checkBox = new Button(parent, SWT.CHECK);
+               checkBox.setText(label);
+
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indentation;
+               gd.horizontalSpan = 1;
+               gd.grabExcessVerticalSpace = false;
+               checkBox.setLayoutData(gd);
+               checkBox.addSelectionListener(fCheckBoxListener);
+
+               fCheckBoxes.put(checkBox, key);
+
+               return checkBox;
+       }
+
+       private void initializeFields() {
+               Iterator it = fCheckBoxes.keySet().iterator();
+               while (it.hasNext()) {
+                       Button b = (Button) it.next();
+                       String key = (String) fCheckBoxes.get(b);
+                       b.setSelection(fOverlayStore.getBoolean(key));
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.AbstractJavaFoldingPreferences#performOk()
+        */
+       public void performOk() {
+               fOverlayStore.propagate();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.AbstractJavaFoldingPreferences#initialize()
+        */
+       public void initialize() {
+               initializeFields();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.AbstractJavaFoldingPreferences#performDefaults()
+        */
+       public void performDefaults() {
+               fOverlayStore.loadDefaults();
+               initializeFields();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.AbstractJavaFoldingPreferences#dispose()
+        */
+       public void dispose() {
+               fOverlayStore.stop();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingStructureProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingStructureProvider.java
new file mode 100644 (file)
index 0000000..30efcd2
--- /dev/null
@@ -0,0 +1,1062 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.folding;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.ElementChangedEvent;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IElementChangedListener;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.IParent;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.ToolFactory;
+import net.sourceforge.phpdt.core.compiler.IScanner;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.ui.text.DocumentCharacterIterator;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.projection.IProjectionListener;
+import org.eclipse.jface.text.source.projection.IProjectionPosition;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Updates the projection model of a class file or compilation unit.
+ * 
+ * @since 3.0
+ */
+public class DefaultJavaFoldingStructureProvider implements
+               IProjectionListener, IJavaFoldingStructureProvider {
+
+       private static class JavaProjectionAnnotation extends ProjectionAnnotation {
+
+               private IJavaElement fJavaElement;
+
+               private boolean fIsComment;
+
+               public JavaProjectionAnnotation(IJavaElement element,
+                               boolean isCollapsed, boolean isComment) {
+                       super(isCollapsed);
+                       fJavaElement = element;
+                       fIsComment = isComment;
+               }
+
+               public IJavaElement getElement() {
+                       return fJavaElement;
+               }
+
+               public void setElement(IJavaElement element) {
+                       fJavaElement = element;
+               }
+
+               public boolean isComment() {
+                       return fIsComment;
+               }
+
+               public void setIsComment(boolean isComment) {
+                       fIsComment = isComment;
+               }
+
+               /*
+                * @see java.lang.Object#toString()
+                */
+               public String toString() {
+                       return "JavaProjectionAnnotation:\n" + //$NON-NLS-1$
+                                       "\telement: \t" + fJavaElement.toString() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
+                                       "\tcollapsed: \t" + isCollapsed() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
+                                       "\tcomment: \t" + fIsComment + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }
+
+       private static final class Tuple {
+               JavaProjectionAnnotation annotation;
+
+               Position position;
+
+               Tuple(JavaProjectionAnnotation annotation, Position position) {
+                       this.annotation = annotation;
+                       this.position = position;
+               }
+       }
+
+       private class ElementChangedListener implements IElementChangedListener {
+
+               /*
+                * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
+                */
+               public void elementChanged(ElementChangedEvent e) {
+                       IJavaElementDelta delta = findElement(fInput, e.getDelta());
+                       if (delta != null)
+                               processDelta(delta);
+               }
+
+               private IJavaElementDelta findElement(IJavaElement target,
+                               IJavaElementDelta delta) {
+
+                       if (delta == null || target == null)
+                               return null;
+
+                       IJavaElement element = delta.getElement();
+
+                       if (element.getElementType() > IJavaElement.CLASS_FILE)
+                               return null;
+
+                       if (target.equals(element))
+                               return delta;
+
+                       IJavaElementDelta[] children = delta.getAffectedChildren();
+
+                       for (int i = 0; i < children.length; i++) {
+                               IJavaElementDelta d = findElement(target, children[i]);
+                               if (d != null)
+                                       return d;
+                       }
+
+                       return null;
+               }
+       }
+
+       /**
+        * Projection position that will return two foldable regions: one folding
+        * away the region from after the '/**' to the beginning of the content, the
+        * other from after the first content line until after the comment.
+        * 
+        * @since 3.1
+        */
+       private static final class CommentPosition extends Position implements
+                       IProjectionPosition {
+               CommentPosition(int offset, int length) {
+                       super(offset, length);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeFoldingRegions(org.eclipse.jface.text.IDocument)
+                */
+               public IRegion[] computeProjectionRegions(IDocument document)
+                               throws BadLocationException {
+                       DocumentCharacterIterator sequence = new DocumentCharacterIterator(
+                                       document, offset, offset + length);
+                       int prefixEnd = 0;
+                       int contentStart = findFirstContent(sequence, prefixEnd);
+
+                       int firstLine = document.getLineOfOffset(offset + prefixEnd);
+                       int captionLine = document.getLineOfOffset(offset + contentStart);
+                       int lastLine = document.getLineOfOffset(offset + length);
+
+                       Assert.isTrue(firstLine <= captionLine,
+                                       "first folded line is greater than the caption line"); //$NON-NLS-1$
+                       Assert.isTrue(captionLine <= lastLine,
+                                       "caption line is greater than the last folded line"); //$NON-NLS-1$
+
+                       IRegion preRegion;
+                       if (firstLine < captionLine) {
+                               // preRegion= new Region(offset + prefixEnd, contentStart -
+                               // prefixEnd);
+                               int preOffset = document.getLineOffset(firstLine);
+                               IRegion preEndLineInfo = document
+                                               .getLineInformation(captionLine);
+                               int preEnd = preEndLineInfo.getOffset();
+                               preRegion = new Region(preOffset, preEnd - preOffset);
+                       } else {
+                               preRegion = null;
+                       }
+
+                       if (captionLine < lastLine) {
+                               int postOffset = document.getLineOffset(captionLine + 1);
+                               IRegion postRegion = new Region(postOffset, offset + length
+                                               - postOffset);
+
+                               if (preRegion == null)
+                                       return new IRegion[] { postRegion };
+
+                               return new IRegion[] { preRegion, postRegion };
+                       }
+
+                       if (preRegion != null)
+                               return new IRegion[] { preRegion };
+
+                       return null;
+               }
+
+               /**
+                * Finds the offset of the first identifier part within
+                * <code>content</code>. Returns 0 if none is found.
+                * 
+                * @param content
+                *            the content to search
+                * @return the first index of a unicode identifier part, or zero if none
+                *         can be found
+                */
+               private int findFirstContent(final CharSequence content, int prefixEnd) {
+                       int lenght = content.length();
+                       for (int i = prefixEnd; i < lenght; i++) {
+                               if (Character.isUnicodeIdentifierPart(content.charAt(i)))
+                                       return i;
+                       }
+                       return 0;
+               }
+
+               // /**
+               // * Finds the offset of the first identifier part within
+               // <code>content</code>.
+               // * Returns 0 if none is found.
+               // *
+               // * @param content the content to search
+               // * @return the first index of a unicode identifier part, or zero if
+               // none
+               // can
+               // * be found
+               // */
+               // private int findPrefixEnd(final CharSequence content) {
+               // // return the index after the leading '/*' or '/**'
+               // int len= content.length();
+               // int i= 0;
+               // while (i < len && isWhiteSpace(content.charAt(i)))
+               // i++;
+               // if (len >= i + 2 && content.charAt(i) == '/' && content.charAt(i + 1)
+               // ==
+               // '*')
+               // if (len >= i + 3 && content.charAt(i + 2) == '*')
+               // return i + 3;
+               // else
+               // return i + 2;
+               // else
+               // return i;
+               // }
+               //
+               // private boolean isWhiteSpace(char c) {
+               // return c == ' ' || c == '\t';
+               // }
+
+               /*
+                * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument)
+                */
+               public int computeCaptionOffset(IDocument document) {
+                       // return 0;
+                       DocumentCharacterIterator sequence = new DocumentCharacterIterator(
+                                       document, offset, offset + length);
+                       return findFirstContent(sequence, 0);
+               }
+       }
+
+       /**
+        * Projection position that will return two foldable regions: one folding
+        * away the lines before the one containing the simple name of the java
+        * element, one folding away any lines after the caption.
+        * 
+        * @since 3.1
+        */
+       private static final class JavaElementPosition extends Position implements
+                       IProjectionPosition {
+
+               private IMember fMember;
+
+               public JavaElementPosition(int offset, int length, IMember member) {
+                       super(offset, length);
+                       Assert.isNotNull(member);
+                       fMember = member;
+               }
+
+               public void setMember(IMember member) {
+                       Assert.isNotNull(member);
+                       fMember = member;
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeFoldingRegions(org.eclipse.jface.text.IDocument)
+                */
+               public IRegion[] computeProjectionRegions(IDocument document)
+                               throws BadLocationException {
+                       int nameStart = offset;
+                       try {
+                               /*
+                                * The member's name range may not be correct. However,
+                                * reconciling would trigger another element delta which would
+                                * lead to reentrant situations. Therefore, we optimistically
+                                * assume that the name range is correct, but double check the
+                                * received lines below.
+                                */
+                               ISourceRange nameRange = fMember.getNameRange();
+                               if (nameRange != null)
+                                       nameStart = nameRange.getOffset();
+
+                       } catch (JavaModelException e) {
+                               // ignore and use default
+                       }
+
+                       int firstLine = document.getLineOfOffset(offset);
+                       int captionLine = document.getLineOfOffset(nameStart);
+                       int lastLine = document.getLineOfOffset(offset + length);
+
+                       /*
+                        * see comment above - adjust the caption line to be inside the
+                        * entire folded region, and rely on later element deltas to correct
+                        * the name range.
+                        */
+                       if (captionLine < firstLine)
+                               captionLine = firstLine;
+                       if (captionLine > lastLine)
+                               captionLine = lastLine;
+
+                       IRegion preRegion;
+                       if (firstLine < captionLine) {
+                               int preOffset = document.getLineOffset(firstLine);
+                               IRegion preEndLineInfo = document
+                                               .getLineInformation(captionLine);
+                               int preEnd = preEndLineInfo.getOffset();
+                               preRegion = new Region(preOffset, preEnd - preOffset);
+                       } else {
+                               preRegion = null;
+                       }
+
+                       if (captionLine < lastLine) {
+                               int postOffset = document.getLineOffset(captionLine + 1);
+                               IRegion postRegion = new Region(postOffset, offset + length
+                                               - postOffset);
+
+                               if (preRegion == null)
+                                       return new IRegion[] { postRegion };
+
+                               return new IRegion[] { preRegion, postRegion };
+                       }
+
+                       if (preRegion != null)
+                               return new IRegion[] { preRegion };
+
+                       return null;
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument)
+                */
+               public int computeCaptionOffset(IDocument document)
+                               throws BadLocationException {
+                       int nameStart = offset;
+                       try {
+                               // need a reconcile here?
+                               ISourceRange nameRange = fMember.getNameRange();
+                               if (nameRange != null)
+                                       nameStart = nameRange.getOffset();
+                       } catch (JavaModelException e) {
+                               // ignore and use default
+                       }
+
+                       return nameStart - offset;
+               }
+
+       }
+
+       private IDocument fCachedDocument;
+
+       private ProjectionAnnotationModel fCachedModel;
+
+       private ITextEditor fEditor;
+
+       private ProjectionViewer fViewer;
+
+       private IJavaElement fInput;
+
+       private IElementChangedListener fElementListener;
+
+       private boolean fAllowCollapsing = false;
+
+       private boolean fCollapseJavadoc = false;
+
+       // private boolean fCollapseImportContainer = true;
+
+       private boolean fCollapseInnerTypes = true;
+
+       private boolean fCollapseMethods = false;
+
+       private boolean fCollapseHeaderComments = true;
+
+       /* caches for header comment extraction. */
+       private IType fFirstType;
+
+       private boolean fHasHeaderComment;
+
+       public DefaultJavaFoldingStructureProvider() {
+       }
+
+       public void install(ITextEditor editor, ProjectionViewer viewer) {
+               if (editor instanceof PHPEditor) {
+                       fEditor = editor;
+                       fViewer = viewer;
+                       fViewer.addProjectionListener(this);
+               }
+       }
+
+       public void uninstall() {
+               if (isInstalled()) {
+                       projectionDisabled();
+                       fViewer.removeProjectionListener(this);
+                       fViewer = null;
+                       fEditor = null;
+               }
+       }
+
+       protected boolean isInstalled() {
+               return fEditor != null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled()
+        */
+       public void projectionEnabled() {
+               // http://home.ott.oti.com/teams/wswb/anon/out/vms/index.html
+               // projectionEnabled messages are not always paired with
+               // projectionDisabled
+               // i.e. multiple enabled messages may be sent out.
+               // we have to make sure that we disable first when getting an enable
+               // message.
+               projectionDisabled();
+
+               if (fEditor instanceof PHPEditor) {
+                       initialize();
+                       fElementListener = new ElementChangedListener();
+                       JavaCore.addElementChangedListener(fElementListener);
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled()
+        */
+       public void projectionDisabled() {
+               fCachedDocument = null;
+               if (fElementListener != null) {
+                       JavaCore.removeElementChangedListener(fElementListener);
+                       fElementListener = null;
+               }
+       }
+
+       public void initialize() {
+
+               if (!isInstalled())
+                       return;
+
+               initializePreferences();
+
+               try {
+
+                       IDocumentProvider provider = fEditor.getDocumentProvider();
+                       fCachedDocument = provider.getDocument(fEditor.getEditorInput());
+                       fAllowCollapsing = true;
+
+                       fFirstType = null;
+                       fHasHeaderComment = false;
+
+                       if (fEditor instanceof PHPUnitEditor) {
+                               IWorkingCopyManager manager = WebUI.getDefault()
+                                               .getWorkingCopyManager();
+                               fInput = manager.getWorkingCopy(fEditor.getEditorInput());
+                       }
+                       // else if (fEditor instanceof ClassFileEditor) {
+                       // IClassFileEditorInput editorInput= (IClassFileEditorInput)
+                       // fEditor.getEditorInput();
+                       // fInput= editorInput.getClassFile();
+                       // }
+
+                       if (fInput != null) {
+                               ProjectionAnnotationModel model = (ProjectionAnnotationModel) fEditor
+                                               .getAdapter(ProjectionAnnotationModel.class);
+                               if (model != null) {
+                                       fCachedModel = model;
+                                       if (fInput instanceof ICompilationUnit) {
+                                               ICompilationUnit unit = (ICompilationUnit) fInput;
+                                               synchronized (unit) {
+                                                       try {
+                                                               // unit.reconcile(ICompilationUnit.NO_AST,
+                                                               // false, null, null);
+                                                               unit.reconcile();
+                                                       } catch (JavaModelException x) {
+                                                       }
+                                               }
+                                       }
+
+                                       Map additions = computeAdditions((IParent) fInput);
+                                       /*
+                                        * Minimize the events being sent out - as this happens in
+                                        * the UI thread merge everything into one call.
+                                        */
+                                       List removals = new LinkedList();
+                                       Iterator existing = model.getAnnotationIterator();
+                                       while (existing.hasNext())
+                                               removals.add(existing.next());
+                                       model.replaceAnnotations((Annotation[]) removals
+                                                       .toArray(new Annotation[removals.size()]),
+                                                       additions);
+                               }
+                       }
+
+               } finally {
+                       fCachedDocument = null;
+                       fCachedModel = null;
+                       fAllowCollapsing = false;
+
+                       fFirstType = null;
+                       fHasHeaderComment = false;
+               }
+       }
+
+       private void initializePreferences() {
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               fCollapseInnerTypes = store
+                               .getBoolean(PreferenceConstants.EDITOR_FOLDING_INNERTYPES);
+               // fCollapseImportContainer =
+               // store.getBoolean(PreferenceConstants.EDITOR_FOLDING_IMPORTS);
+               fCollapseJavadoc = store
+                               .getBoolean(PreferenceConstants.EDITOR_FOLDING_JAVADOC);
+               fCollapseMethods = store
+                               .getBoolean(PreferenceConstants.EDITOR_FOLDING_METHODS);
+               fCollapseHeaderComments = store
+                               .getBoolean(PreferenceConstants.EDITOR_FOLDING_HEADERS);
+       }
+
+       private Map computeAdditions(IParent parent) {
+               Map map = new LinkedHashMap(); // use a linked map to maintain ordering
+                                                                               // of
+               // comments
+               try {
+                       computeAdditions(parent.getChildren(), map);
+               } catch (JavaModelException x) {
+               }
+               return map;
+       }
+
+       private void computeAdditions(IJavaElement[] elements, Map map)
+                       throws JavaModelException {
+               for (int i = 0; i < elements.length; i++) {
+                       IJavaElement element = elements[i];
+
+                       computeAdditions(element, map);
+
+                       if (element instanceof IParent) {
+                               IParent parent = (IParent) element;
+                               computeAdditions(parent.getChildren(), map);
+                       }
+               }
+       }
+
+       private void computeAdditions(IJavaElement element, Map map) {
+
+               boolean createProjection = false;
+
+               boolean collapse = false;
+               switch (element.getElementType()) {
+
+               // case IJavaElement.IMPORT_CONTAINER:
+               // collapse = fAllowCollapsing && fCollapseImportContainer;
+               // createProjection = true;
+               // break;
+               case IJavaElement.TYPE:
+                       collapse = fAllowCollapsing;
+                       if (isInnerType((IType) element)) {
+                               collapse = collapse && fCollapseInnerTypes;
+                       } else {
+                               collapse = false; // don't allow the most outer type to be
+                                                                       // folded, may be changed in future versions
+                       }
+                       createProjection = true;
+                       break;
+               case IJavaElement.METHOD:
+                       collapse = fAllowCollapsing && fCollapseMethods;
+                       createProjection = true;
+                       break;
+               }
+
+               if (createProjection) {
+                       IRegion[] regions = computeProjectionRanges(element);
+                       if (regions != null) {
+                               // comments
+                               for (int i = 0; i < regions.length - 1; i++) {
+                                       Position position = createProjectionPosition(regions[i],
+                                                       null);
+                                       boolean commentCollapse;
+                                       if (position != null) {
+                                               if (i == 0 && (regions.length > 2 || fHasHeaderComment)
+                                                               && element == fFirstType) {
+                                                       commentCollapse = fAllowCollapsing
+                                                                       && fCollapseHeaderComments;
+                                               } else {
+                                                       commentCollapse = fAllowCollapsing
+                                                                       && fCollapseJavadoc;
+                                               }
+                                               map.put(new JavaProjectionAnnotation(element,
+                                                               commentCollapse, true), position);
+                                       }
+                               }
+                               // code
+                               Position position = createProjectionPosition(
+                                               regions[regions.length - 1], element);
+                               if (position != null)
+                                       map.put(new JavaProjectionAnnotation(element, collapse,
+                                                       false), position);
+                       }
+               }
+       }
+
+       private boolean isInnerType(IType type) {
+
+               try {
+                       return type.isMember();
+               } catch (JavaModelException x) {
+                       IJavaElement parent = type.getParent();
+                       if (parent != null) {
+                               int parentType = parent.getElementType();
+                               return (parentType != IJavaElement.COMPILATION_UNIT && parentType != IJavaElement.CLASS_FILE);
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Computes the projection ranges for a given <code>IJavaElement</code>.
+        * More than one range may be returned if the element has a leading comment
+        * which gets folded separately. If there are no foldable regions,
+        * <code>null</code> is returned.
+        * 
+        * @param element
+        *            the java element that can be folded
+        * @return the regions to be folded, or <code>null</code> if there are
+        *         none
+        */
+       private IRegion[] computeProjectionRanges(IJavaElement element) {
+
+               try {
+                       if (element instanceof ISourceReference) {
+                               ISourceReference reference = (ISourceReference) element;
+                               ISourceRange range = reference.getSourceRange();
+
+                               String contents = reference.getSource();
+                               if (contents == null)
+                                       return null;
+
+                               List regions = new ArrayList();
+                               // now add all comments first to the regions list
+                               if (fFirstType == null && element instanceof IType) {
+                                       fFirstType = (IType) element;
+                                       IRegion headerComment = computeHeaderComment(fFirstType);
+                                       if (headerComment != null) {
+                                               regions.add(headerComment);
+                                               fHasHeaderComment = true;
+                                       }
+                               }
+
+                               final int shift = range.getOffset();
+                               int start = shift;
+                               if (element instanceof IType) {
+                                       Scanner scanner = ToolFactory.createScanner(true, false,
+                                                       false, false);
+                                       scanner.setSource(contents.toCharArray());
+                                       scanner.setPHPMode(true);
+
+                                       int token = scanner.getNextToken();
+                                       while (token != ITerminalSymbols.TokenNameEOF) {
+
+                                               token = scanner.getNextToken();
+                                               start = shift + scanner.getCurrentTokenStartPosition();
+
+                                               switch (token) {
+                                               case ITerminalSymbols.TokenNameCOMMENT_PHPDOC:
+                                               case ITerminalSymbols.TokenNameCOMMENT_BLOCK: {
+                                                       int end = shift
+                                                                       + scanner.getCurrentTokenEndPosition() + 1;
+                                                       regions.add(new Region(start, end - start));
+                                               }
+                                               case ITerminalSymbols.TokenNameCOMMENT_LINE:
+                                                       continue;
+                                               }
+                                       }
+                               }
+                               // at the end add the element region
+                               regions.add(new Region(range.getOffset(), range.getLength()));
+
+                               if (regions.size() > 0) {
+                                       IRegion[] result = new IRegion[regions.size()];
+                                       regions.toArray(result);
+                                       return result;
+                               }
+
+                       }
+               } catch (JavaModelException e) {
+               } catch (InvalidInputException e) {
+               }
+
+               return null;
+       }
+
+       private IRegion computeHeaderComment(IType type) throws JavaModelException {
+               if (fCachedDocument == null)
+                       return null;
+
+               // search at most up to the first type
+               ISourceRange range = type.getSourceRange();
+               if (range == null)
+                       return null;
+               int start = 0;
+               int end = range.getOffset();
+
+               if (fInput instanceof ISourceReference) {
+                       String content;
+                       try {
+                               content = fCachedDocument.get(start, end - start);
+                       } catch (BadLocationException e) {
+                               return null; // ignore header comment in that case
+                       }
+
+                       /*
+                        * code adapted from CommentFormattingStrategy: scan the header
+                        * content up to the first type. Once a comment is found, accumulate
+                        * any additional comments up to the stop condition. The stop
+                        * condition is reaching a package declaration, import container, or
+                        * the end of the input.
+                        */
+                       IScanner scanner = ToolFactory.createScanner(true, false, false,
+                                       false);
+                       scanner.setSource(content.toCharArray());
+
+                       int headerStart = -1;
+                       int headerEnd = -1;
+                       try {
+                               boolean foundComment = false;
+                               int terminal = scanner.getNextToken();
+                               while (terminal != ITerminalSymbols.TokenNameEOF
+                                               && !(terminal == ITerminalSymbols.TokenNameclass
+                                                               || terminal == ITerminalSymbols.TokenNameinterface || foundComment)) {
+
+                                       if (terminal == ITerminalSymbols.TokenNameCOMMENT_PHPDOC
+                                                       || terminal == ITerminalSymbols.TokenNameCOMMENT_BLOCK
+                                                       || terminal == ITerminalSymbols.TokenNameCOMMENT_LINE) {
+                                               if (!foundComment)
+                                                       headerStart = scanner
+                                                                       .getCurrentTokenStartPosition();
+                                               headerEnd = scanner.getCurrentTokenEndPosition();
+                                               foundComment = true;
+                                       }
+                                       terminal = scanner.getNextToken();
+                               }
+
+                       } catch (InvalidInputException ex) {
+                               return null;
+                       }
+
+                       if (headerEnd != -1) {
+                               return new Region(headerStart, headerEnd - headerStart);
+                       }
+               }
+               return null;
+       }
+
+       private Position createProjectionPosition(IRegion region,
+                       IJavaElement element) {
+
+               if (fCachedDocument == null)
+                       return null;
+
+               try {
+
+                       int start = fCachedDocument.getLineOfOffset(region.getOffset());
+                       int end = fCachedDocument.getLineOfOffset(region.getOffset()
+                                       + region.getLength());
+                       if (start != end) {
+                               int offset = fCachedDocument.getLineOffset(start);
+                               int endOffset;
+                               if (fCachedDocument.getNumberOfLines() > end + 1)
+                                       endOffset = fCachedDocument.getLineOffset(end + 1);
+                               else if (end > start)
+                                       endOffset = fCachedDocument.getLineOffset(end)
+                                                       + fCachedDocument.getLineLength(end);
+                               else
+                                       return null;
+                               if (element instanceof IMember)
+                                       return new JavaElementPosition(offset, endOffset - offset,
+                                                       (IMember) element);
+                               else
+                                       return new CommentPosition(offset, endOffset - offset);
+                       }
+
+               } catch (BadLocationException x) {
+               }
+
+               return null;
+       }
+
+       protected void processDelta(IJavaElementDelta delta) {
+
+               if (!isInstalled())
+                       return;
+
+               if ((delta.getFlags() & (IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_CHILDREN)) == 0)
+                       return;
+
+               ProjectionAnnotationModel model = (ProjectionAnnotationModel) fEditor
+                               .getAdapter(ProjectionAnnotationModel.class);
+               if (model == null)
+                       return;
+
+               try {
+
+                       IDocumentProvider provider = fEditor.getDocumentProvider();
+                       fCachedDocument = provider.getDocument(fEditor.getEditorInput());
+                       fCachedModel = model;
+                       fAllowCollapsing = false;
+
+                       fFirstType = null;
+                       fHasHeaderComment = false;
+
+                       Map additions = new HashMap();
+                       List deletions = new ArrayList();
+                       List updates = new ArrayList();
+
+                       Map updated = computeAdditions((IParent) fInput);
+                       Map previous = createAnnotationMap(model);
+
+                       Iterator e = updated.keySet().iterator();
+                       while (e.hasNext()) {
+                               JavaProjectionAnnotation newAnnotation = (JavaProjectionAnnotation) e
+                                               .next();
+//+
+                               Position newPosition = (Position) updated.get(newAnnotation);
+                               additions.put(newAnnotation, newPosition);
+//-
+//                             IJavaElement element = newAnnotation.getElement();
+//                             Position newPosition = (Position) updated.get(newAnnotation);
+//
+//                             List annotations = (List) previous.get(element);
+//                             if (annotations == null) {
+//
+//                                     additions.put(newAnnotation, newPosition);
+//
+//                             } else {
+//                                     Iterator x = annotations.iterator();
+//                                     boolean matched = false;
+//                                     while (x.hasNext()) {
+//                                             Tuple tuple = (Tuple) x.next();
+//                                             JavaProjectionAnnotation existingAnnotation = tuple.annotation;
+//                                             Position existingPosition = tuple.position;
+//                                             if (newAnnotation.isComment() == existingAnnotation
+//                                                             .isComment()) {
+//                                                     if (existingPosition != null
+//                                                                     && (!newPosition.equals(existingPosition))) {
+//                                                             existingPosition.setOffset(newPosition
+//                                                                             .getOffset());
+//                                                             existingPosition.setLength(newPosition
+//                                                                             .getLength());
+//                                                             updates.add(existingAnnotation);
+//                                                     }
+//                                                     matched = true;
+//                                                     x.remove();
+//                                                     break;
+//                                             }
+//                                     }
+//                                     if (!matched)
+//                                             additions.put(newAnnotation, newPosition);
+//
+//                                     if (annotations.isEmpty())
+//                                             previous.remove(element);
+//                             }
+//-
+                       }
+
+                       e = previous.values().iterator();
+                       while (e.hasNext()) {
+                               List list = (List) e.next();
+                               int size = list.size();
+                               for (int i = 0; i < size; i++)
+                                       deletions.add(((Tuple) list.get(i)).annotation);
+                       }
+
+                       match(deletions, additions, updates);
+
+                       Annotation[] removals = new Annotation[deletions.size()];
+                       deletions.toArray(removals);
+                       Annotation[] changes = new Annotation[updates.size()];
+                       updates.toArray(changes);
+                       model.modifyAnnotations(removals, additions, changes);
+
+               } finally {
+                       fCachedDocument = null;
+                       fAllowCollapsing = true;
+                       fCachedModel = null;
+
+                       fFirstType = null;
+                       fHasHeaderComment = false;
+               }
+       }
+
+       /**
+        * Matches deleted annotations to changed or added ones. A deleted
+        * annotation/position tuple that has a matching addition / change is
+        * updated and marked as changed. The matching tuple is not added (for
+        * additions) or marked as deletion instead (for changes). The result is
+        * that more annotations are changed and fewer get deleted/re-added.
+        */
+       private void match(List deletions, Map additions, List changes) {
+               if (deletions.isEmpty() || (additions.isEmpty() && changes.isEmpty()))
+                       return;
+
+               List newDeletions = new ArrayList();
+               List newChanges = new ArrayList();
+
+               Iterator deletionIterator = deletions.iterator();
+               while (deletionIterator.hasNext()) {
+                       JavaProjectionAnnotation deleted = (JavaProjectionAnnotation) deletionIterator
+                                       .next();
+                       Position deletedPosition = fCachedModel.getPosition(deleted);
+                       if (deletedPosition == null)
+                               continue;
+
+                       Tuple deletedTuple = new Tuple(deleted, deletedPosition);
+
+                       Tuple match = findMatch(deletedTuple, changes, null);
+                       boolean addToDeletions = true;
+                       if (match == null) {
+                               match = findMatch(deletedTuple, additions.keySet(), additions);
+                               addToDeletions = false;
+                       }
+
+                       if (match != null) {
+                               IJavaElement element = match.annotation.getElement();
+                               deleted.setElement(element);
+                               deletedPosition.setLength(match.position.getLength());
+                               if (deletedPosition instanceof JavaElementPosition
+                                               && element instanceof IMember) {
+                                       JavaElementPosition jep = (JavaElementPosition) deletedPosition;
+                                       jep.setMember((IMember) element);
+                               }
+
+                               deletionIterator.remove();
+                               newChanges.add(deleted);
+
+                               if (addToDeletions)
+                                       newDeletions.add(match.annotation);
+                       }
+               }
+
+               deletions.addAll(newDeletions);
+               changes.addAll(newChanges);
+       }
+
+       /**
+        * Finds a match for <code>tuple</code> in a collection of annotations.
+        * The positions for the <code>JavaProjectionAnnotation</code> instances
+        * in <code>annotations</code> can be found in the passed
+        * <code>positionMap</code> or <code>fCachedModel</code> if
+        * <code>positionMap</code> is <code>null</code>.
+        * <p>
+        * A tuple is said to match another if their annotations have the same
+        * comment flag and their position offsets are equal.
+        * </p>
+        * <p>
+        * If a match is found, the annotation gets removed from
+        * <code>annotations</code>.
+        * </p>
+        * 
+        * @param tuple
+        *            the tuple for which we want to find a match
+        * @param annotations
+        *            collection of <code>JavaProjectionAnnotation</code>
+        * @param positionMap
+        *            a <code>Map&lt;Annotation, Position&gt;</code> or
+        *            <code>null</code>
+        * @return a matching tuple or <code>null</code> for no match
+        */
+       private Tuple findMatch(Tuple tuple, Collection annotations, Map positionMap) {
+               Iterator it = annotations.iterator();
+               while (it.hasNext()) {
+                       JavaProjectionAnnotation annotation = (JavaProjectionAnnotation) it
+                                       .next();
+                       if (tuple.annotation.isComment() == annotation.isComment()) {
+                               Position position = positionMap == null ? fCachedModel
+                                               .getPosition(annotation) : (Position) positionMap
+                                               .get(annotation);
+                               if (position == null)
+                                       continue;
+
+                               if (tuple.position.getOffset() == position.getOffset()) {
+                                       it.remove();
+                                       return new Tuple(annotation, position);
+                               }
+                       }
+               }
+
+               return null;
+       }
+
+       private Map createAnnotationMap(IAnnotationModel model) {
+               Map map = new HashMap();
+               Iterator e = model.getAnnotationIterator();
+               while (e.hasNext()) {
+                       Object annotation = e.next();
+                       if (annotation instanceof JavaProjectionAnnotation) {
+                               JavaProjectionAnnotation java = (JavaProjectionAnnotation) annotation;
+                               Position position = model.getPosition(java);
+                               Assert.isNotNull(position);
+                               List list = (List) map.get(java.getElement());
+                               if (list == null) {
+                                       list = new ArrayList(2);
+                                       map.put(java.getElement(), list);
+                               }
+                               list.add(new Tuple(java, position));
+                       }
+               }
+
+               Comparator comparator = new Comparator() {
+                       public int compare(Object o1, Object o2) {
+                               return ((Tuple) o1).position.getOffset()
+                                               - ((Tuple) o2).position.getOffset();
+                       }
+               };
+               for (Iterator it = map.values().iterator(); it.hasNext();) {
+                       List list = (List) it.next();
+                       Collections.sort(list, comparator);
+               }
+               return map;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/EmptyJavaFoldingPreferenceBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/EmptyJavaFoldingPreferenceBlock.java
new file mode 100644 (file)
index 0000000..5ccaeaa
--- /dev/null
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.folding;
+
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingPreferenceBlock;
+
+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.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Empty preference block for extensions to the
+ * <code>net.sourceforge.phpdt.ui.javaFoldingStructureProvider</code>
+ * extension point that do not specify their own.
+ * 
+ * @since 3.0
+ */
+class EmptyJavaFoldingPreferenceBlock implements IJavaFoldingPreferenceBlock {
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.IJavaFoldingPreferences#createControl(org.eclipse.swt.widgets.Group)
+        */
+       public Control createControl(Composite composite) {
+               Composite inner = new Composite(composite, SWT.NONE);
+               inner.setLayout(new GridLayout(3, false));
+
+               Label label = new Label(inner, SWT.CENTER);
+               GridData gd = new GridData(GridData.FILL_BOTH);
+               gd.widthHint = 30;
+               label.setLayoutData(gd);
+
+               label = new Label(inner, SWT.CENTER);
+               label.setText(FoldingMessages
+                               .getString("EmptyJavaFoldingPreferenceBlock.emptyCaption")); //$NON-NLS-1$
+               gd = new GridData(GridData.CENTER);
+               label.setLayoutData(gd);
+
+               label = new Label(inner, SWT.CENTER);
+               gd = new GridData(GridData.FILL_BOTH);
+               gd.widthHint = 30;
+               label.setLayoutData(gd);
+
+               return inner;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.IJavaFoldingPreferenceBlock#initialize()
+        */
+       public void initialize() {
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.IJavaFoldingPreferenceBlock#performOk()
+        */
+       public void performOk() {
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.IJavaFoldingPreferenceBlock#performDefaults()
+        */
+       public void performDefaults() {
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.folding.IJavaFoldingPreferenceBlock#dispose()
+        */
+       public void dispose() {
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/FoldingMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/FoldingMessages.java
new file mode 100644 (file)
index 0000000..2f641d3
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.folding;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @since 3.0
+ */
+class FoldingMessages {
+
+       private static final String BUNDLE_NAME = FoldingMessages.class.getName();
+
+       private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+                       .getBundle(BUNDLE_NAME);
+
+       private FoldingMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return RESOURCE_BUNDLE.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/FoldingMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/FoldingMessages.properties
new file mode 100644 (file)
index 0000000..b89b15e
--- /dev/null
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2000, 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+DefaultJavaFoldingPreferenceBlock.title= Initially fold these region types:
+DefaultJavaFoldingPreferenceBlock.comments= &Comments
+DefaultJavaFoldingPreferenceBlock.headers= &Header Comments
+DefaultJavaFoldingPreferenceBlock.innerTypes= Inner &types
+DefaultJavaFoldingPreferenceBlock.methods= &Methods
+DefaultJavaFoldingPreferenceBlock.imports= &Imports
+
+EmptyJavaFoldingPreferenceBlock.emptyCaption=
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/JavaFoldingStructureProviderDescriptor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/JavaFoldingStructureProviderDescriptor.java
new file mode 100644 (file)
index 0000000..a810ba8
--- /dev/null
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.folding;
+
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingPreferenceBlock;
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.text.Assert;
+
+/**
+ * Describes a contribution to the folding provider extension point.
+ * 
+ * @since 3.0
+ */
+public final class JavaFoldingStructureProviderDescriptor {
+
+       /* extension point attribute names */
+
+       private static final String PREFERENCES_CLASS = "preferencesClass"; //$NON-NLS-1$
+
+       private static final String CLASS = "class"; //$NON-NLS-1$
+
+       private static final String NAME = "name"; //$NON-NLS-1$
+
+       private static final String ID = "id"; //$NON-NLS-1$
+
+       /** The identifier of the extension. */
+       private String fId;
+
+       /** The name of the extension. */
+       private String fName;
+
+       /** The class name of the provided <code>IJavaFoldingStructureProvider</code>. */
+       private String fClass;
+
+       /**
+        * <code>true</code> if the extension specifies a custom
+        * <code>IJavaFoldingPreferenceBlock</code>.
+        */
+       private boolean fHasPreferences;
+
+       /** The configuration element of this extension. */
+       private IConfigurationElement fElement;
+
+       /**
+        * Creates a new descriptor.
+        * 
+        * @param element
+        *            the configuration element to read
+        */
+       JavaFoldingStructureProviderDescriptor(IConfigurationElement element) {
+               fElement = element;
+               fId = element.getAttributeAsIs(ID);
+               Assert.isLegal(fId != null);
+
+               fName = element.getAttribute(NAME);
+               if (fName == null)
+                       fName = fId;
+
+               fClass = element.getAttributeAsIs(CLASS);
+               Assert.isLegal(fClass != null);
+
+               if (element.getAttributeAsIs(PREFERENCES_CLASS) == null)
+                       fHasPreferences = false;
+               else
+                       fHasPreferences = true;
+       }
+
+       /**
+        * Creates a folding provider as described in the extension's xml.
+        * 
+        * @return a new instance of the folding provider described by this
+        *         descriptor
+        * @throws CoreException
+        *             if creation fails
+        */
+       public IJavaFoldingStructureProvider createProvider() throws CoreException {
+               IJavaFoldingStructureProvider prov = (IJavaFoldingStructureProvider) fElement
+                               .createExecutableExtension(CLASS);
+               return prov;
+       }
+
+       /**
+        * Creates a preferences object as described in the extension's xml.
+        * 
+        * @return a new instance of the reference provider described by this
+        *         descriptor
+        * @throws CoreException
+        *             if creation fails
+        */
+       public IJavaFoldingPreferenceBlock createPreferences() throws CoreException {
+               if (fHasPreferences) {
+                       IJavaFoldingPreferenceBlock prefs = (IJavaFoldingPreferenceBlock) fElement
+                                       .createExecutableExtension(PREFERENCES_CLASS);
+                       return prefs;
+               } else {
+                       return new EmptyJavaFoldingPreferenceBlock();
+               }
+       }
+
+       /**
+        * Returns the identifier of the described extension.
+        * 
+        * @return Returns the id
+        */
+       public String getId() {
+               return fId;
+       }
+
+       /**
+        * Returns the name of the described extension.
+        * 
+        * @return Returns the name
+        */
+       public String getName() {
+               return fName;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/JavaFoldingStructureProviderRegistry.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/folding/JavaFoldingStructureProviderRegistry.java
new file mode 100644 (file)
index 0000000..2228c68
--- /dev/null
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.folding;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * @since 3.0
+ */
+public class JavaFoldingStructureProviderRegistry {
+
+       private static final String EXTENSION_POINT = "foldingStructureProviders"; //$NON-NLS-1$
+
+       /** The map of descriptors, indexed by their identifiers. */
+       private Map fDescriptors;
+
+       /**
+        * Creates a new instance.
+        */
+       public JavaFoldingStructureProviderRegistry() {
+       }
+
+       /**
+        * Returns an array of <code>IJavaFoldingProviderDescriptor</code>
+        * describing all extension to the <code>foldingProviders</code> extension
+        * point.
+        * 
+        * @return the list of extensions to the
+        *         <code>quickDiffReferenceProvider</code> extension point.
+        */
+       public JavaFoldingStructureProviderDescriptor[] getFoldingProviderDescriptors() {
+               synchronized (this) {
+                       ensureRegistered();
+                       return (JavaFoldingStructureProviderDescriptor[]) fDescriptors
+                                       .values()
+                                       .toArray(
+                                                       new JavaFoldingStructureProviderDescriptor[fDescriptors
+                                                                       .size()]);
+               }
+       }
+
+       /**
+        * Returns the folding provider with identifier <code>id</code> or
+        * <code>null</code> if no such provider is registered.
+        * 
+        * @param id
+        *            the identifier for which a provider is wanted
+        * @return the corresponding provider, or <code>null</code> if none can be
+        *         found
+        */
+       public JavaFoldingStructureProviderDescriptor getFoldingProviderDescriptor(
+                       String id) {
+               synchronized (this) {
+                       ensureRegistered();
+                       return (JavaFoldingStructureProviderDescriptor) fDescriptors
+                                       .get(id);
+               }
+       }
+
+       /**
+        * Instantiates and returns the provider that is currently configured in the
+        * preferences.
+        * 
+        * @return the current provider according to the preferences
+        */
+       public IJavaFoldingStructureProvider getCurrentFoldingProvider() {
+               String id = WebUI.getDefault().getPreferenceStore()
+                               .getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
+               JavaFoldingStructureProviderDescriptor desc = getFoldingProviderDescriptor(id);
+               if (desc != null) {
+                       try {
+                               return desc.createProvider();
+                       } catch (CoreException e) {
+                               WebUI.log(e);
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Ensures that the extensions are read and stored in
+        * <code>fDescriptors</code>.
+        */
+       private void ensureRegistered() {
+               if (fDescriptors == null)
+                       reloadExtensions();
+       }
+
+       /**
+        * Reads all extensions.
+        * <p>
+        * This method can be called more than once in order to reload from a
+        * changed extension registry.
+        * </p>
+        */
+       public void reloadExtensions() {
+               IExtensionRegistry registry = Platform.getExtensionRegistry();
+               Map map = new HashMap();
+
+               IConfigurationElement[] elements = registry
+                               .getConfigurationElementsFor(PHPeclipsePlugin.getPluginId(),
+                                               EXTENSION_POINT);
+               for (int i = 0; i < elements.length; i++) {
+                       JavaFoldingStructureProviderDescriptor desc = new JavaFoldingStructureProviderDescriptor(
+                                       elements[i]);
+                       map.put(desc.getId(), desc);
+               }
+
+               synchronized (this) {
+                       fDescriptors = Collections.unmodifiableMap(map);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IInvocationContext.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IInvocationContext.java
new file mode 100644 (file)
index 0000000..ca5dec2
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.dom.CompilationUnit;
+
+/**
+ * Context information for quick fix and quick assist processors.
+ * <p>
+ * Note: this interface is not intended to be implemented.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public interface IInvocationContext {
+
+       /**
+        * @return Returns the current compilation unit.
+        */
+       ICompilationUnit getCompilationUnit();
+
+       /**
+        * @return Returns the offset of the current selection
+        */
+       int getSelectionOffset();
+
+       /**
+        * @return Returns the length of the current selection
+        */
+       int getSelectionLength();
+
+       /**
+        * Returns an AST of the compilation unit, possibly only a partial AST
+        * focused on the selection offset (see
+        * {@link net.sourceforge.phpdt.core.dom.ASTParser#setFocalPosition(int)}).
+        * The returned AST is shared and therefore protected and cannot be
+        * modified. The client must check the AST API level and do nothing if they
+        * are given an AST they can't handle. (see
+        * {@link net.sourceforge.phpdt.core.dom.AST#apiLevel()}).
+        * 
+        * @return Returns the root of the AST corresponding to the current
+        *         compilation unit.
+        */
+       CompilationUnit getASTRoot();
+
+       /**
+        * Convenience method to evaluate the AST node covering the current
+        * selection.
+        * 
+        * @return Returns the node that covers the location of the problem
+        */
+       // ASTNode getCoveringNode();
+       /**
+        * Convenience method to evaluate the AST node that is covered by the
+        * current selection.
+        * 
+        * @return Returns the node that is covered by the location of the problem
+        */
+       // ASTNode getCoveredNode();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaReconcilingListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaReconcilingListener.java
new file mode 100644 (file)
index 0000000..12aad9a
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import net.sourceforge.phpdt.core.dom.CompilationUnit;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Interface of an object listening to Java reconciling.
+ * 
+ * @since 3.0
+ */
+public interface IJavaReconcilingListener {
+
+       /**
+        * Called before reconciling is started.
+        */
+       void aboutToBeReconciled();
+
+       /**
+        * Called after reconciling has been finished.
+        * 
+        * @param ast
+        *            the compilation unit AST or <code>null</code> if the working
+        *            copy was consistent or reconciliation has been cancelled
+        * @param forced
+        *            <code>true</code> iff this reconciliation was forced
+        * @param progressMonitor
+        *            the progress monitor
+        */
+       void reconciled(CompilationUnit ast, boolean forced,
+                       IProgressMonitor progressMonitor);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IPHPCompletionProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IPHPCompletionProposal.java
new file mode 100644 (file)
index 0000000..98ae9ba
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+
+/*
+ * CompletionProposal with a relevance value. The relevance value is used to
+ * sort the completion proposals. Proposals with higher relevance should be
+ * listed before proposals with lower relevance.
+ */
+public interface IPHPCompletionProposal extends ICompletionProposal {
+
+       /**
+        * Returns the relevance of the proposal.
+        */
+       int getRelevance();
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IProblemRequestorExtension.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IProblemRequestorExtension.java
new file mode 100644 (file)
index 0000000..b9dcb85
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Extension to <code>IProblemRequestor</code>.
+ */
+public interface IProblemRequestorExtension {
+
+       /**
+        * Sets the progress monitor to this problem requestor.
+        * 
+        * @param monitor
+        *            the progress monitor to be used
+        */
+       void setProgressMonitor(IProgressMonitor monitor);
+
+       /**
+        * Sets the active state of this problem requestor.
+        * 
+        * @param isActive
+        *            the state of this problem requestor
+        */
+       void setIsActive(boolean isActive);
+
+       /**
+        * Informs the problem requestor that a sequence of reportings is about to
+        * start. While a sequence is active, multiple peering calls of
+        * <code>beginReporting</code> and <code>endReporting</code> can appear.
+        * 
+        * @since 3.0
+        */
+       void beginReportingSequence();
+
+       /**
+        * Informs the problem requestor that the sequence of reportings has been
+        * finished.
+        * 
+        * @since 3.0
+        */
+       void endReportingSequence();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IReconcilingParticipant.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/IReconcilingParticipant.java
new file mode 100644 (file)
index 0000000..9878725
--- /dev/null
@@ -0,0 +1,17 @@
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * Interface of an object participating in reconciling.
+ */
+public interface IReconcilingParticipant {
+
+       /**
+        * Called after reconciling has been finished.
+        */
+       void reconciled();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaFormattingStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaFormattingStrategy.java
new file mode 100644 (file)
index 0000000..0fd345d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001. All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import net.sourceforge.phpdt.core.ICodeFormatter;
+import net.sourceforge.phpdt.core.ToolFactory;
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+import net.sourceforge.phpdt.internal.corext.util.Strings;
+import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.formatter.IFormattingStrategy;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+public class JavaFormattingStrategy implements IFormattingStrategy {
+
+       private String fInitialIndentation;
+
+       private ISourceViewer fViewer;
+
+       public JavaFormattingStrategy(ISourceViewer viewer) {
+               fViewer = viewer;
+       }
+
+       /**
+        * @see IFormattingStrategy#formatterStarts(String)
+        */
+       public void formatterStarts(String initialIndentation) {
+               fInitialIndentation = initialIndentation;
+       }
+
+       /**
+        * @see IFormattingStrategy#formatterStops()
+        */
+       public void formatterStops() {
+       }
+
+       /**
+        * @see IFormattingStrategy#format(String, boolean, String, int[])
+        */
+       public String format(String content, boolean isLineStart,
+                       String indentation, int[] positions) {
+               ICodeFormatter formatter = ToolFactory.createCodeFormatter();
+
+               IDocument doc = fViewer.getDocument();
+               String lineDelimiter = StubUtility.getLineDelimiterFor(doc);
+
+               int indent = 0;
+               if (fInitialIndentation != null) {
+                       indent = Strings.computeIndent(fInitialIndentation,
+                                       CodeFormatterPreferencePage.getTabSize());
+               }
+
+               return formatter.format(content, indent, positions, lineDelimiter);
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.java
new file mode 100644 (file)
index 0000000..bedafbc
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+class JavaHoverMessages {
+
+       private static final String RESOURCE_BUNDLE = JavaHoverMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private JavaHoverMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        * @since 3.0
+        */
+       public static String getFormattedString(String key, Object arg) {
+               String format = null;
+               try {
+                       format = fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+               if (arg == null)
+                       arg = ""; //$NON-NLS-1$
+               return MessageFormat.format(format, new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the arguments
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        * @since 3.0
+        */
+       public static String getFormattedString(String key, Object arg1, Object arg2) {
+               String format = null;
+               try {
+                       format = fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+               if (arg1 == null)
+                       arg1 = ""; //$NON-NLS-1$
+               if (arg2 == null)
+                       arg2 = ""; //$NON-NLS-1$
+               return MessageFormat.format(format, new Object[] { arg1, arg2 });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        * @since 3.0
+        */
+       public static String getFormattedString(String key, boolean arg) {
+               String format = null;
+               try {
+                       format = fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+               return MessageFormat.format(format, new Object[] { new Boolean(arg) });
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.properties
new file mode 100644 (file)
index 0000000..01f64aa
--- /dev/null
@@ -0,0 +1,18 @@
+###############################################################################
+# Copyright (c) 2000, 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+TypeHover.more_to_come=\ ...
+
+JavaTextHover.createTextHover= Could not create PHP text hover
+
+JavaTextHover.makeStickyHint= Press ''{0}'' for focus.
+
+NoBreakpointAnnotation.addBreakpoint= Add a breakpoint
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaParameterListValidator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaParameterListValidator.java
new file mode 100644 (file)
index 0000000..71bf6ff
--- /dev/null
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.text.java;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+
+public class JavaParameterListValidator implements
+               IContextInformationValidator, IContextInformationPresenter {
+
+       private int fPosition;
+
+       private ITextViewer fViewer;
+
+       private IContextInformation fInformation;
+
+       private int fCurrentParameter;
+
+       public JavaParameterListValidator() {
+       }
+
+       /**
+        * @see IContextInformationValidator#install(IContextInformation,
+        *      ITextViewer, int)
+        * @see IContextInformationPresenter#install(IContextInformation,
+        *      ITextViewer, int)
+        */
+       public void install(IContextInformation info, ITextViewer viewer,
+                       int documentPosition) {
+               fPosition = documentPosition;
+               fViewer = viewer;
+               fInformation = info;
+
+               fCurrentParameter = -1;
+       }
+
+       private int getCommentEnd(IDocument d, int pos, int end)
+                       throws BadLocationException {
+               while (pos < end) {
+                       char curr = d.getChar(pos);
+                       pos++;
+                       if (curr == '*') {
+                               if (pos < end && d.getChar(pos) == '/') {
+                                       return pos + 1;
+                               }
+                       }
+               }
+               return end;
+       }
+
+       private int getStringEnd(IDocument d, int pos, int end, char ch)
+                       throws BadLocationException {
+               while (pos < end) {
+                       char curr = d.getChar(pos);
+                       pos++;
+                       if (curr == '\\') {
+                               // ignore escaped characters
+                               pos++;
+                       } else if (curr == ch) {
+                               return pos;
+                       }
+               }
+               return end;
+       }
+
+       private int getCharCount(IDocument document, int start, int end,
+                       String increments, String decrements, boolean considerNesting)
+                       throws BadLocationException {
+
+               Assert.isTrue((increments.length() != 0 || decrements.length() != 0)
+                               && !increments.equals(decrements));
+
+               int nestingLevel = 0;
+               int charCount = 0;
+               while (start < end) {
+                       char curr = document.getChar(start++);
+                       switch (curr) {
+                       case '/':
+                               if (start < end) {
+                                       char next = document.getChar(start);
+                                       if (next == '*') {
+                                               // a comment starts, advance to the comment end
+                                               start = getCommentEnd(document, start + 1, end);
+                                       } else if (next == '/') {
+                                               // '//'-comment: nothing to do anymore on this line
+                                               start = end;
+                                       }
+                               }
+                               break;
+                       case '*':
+                               if (start < end) {
+                                       char next = document.getChar(start);
+                                       if (next == '/') {
+                                               // we have been in a comment: forget what we read before
+                                               charCount = 0;
+                                               ++start;
+                                       }
+                               }
+                               break;
+                       case '"':
+                       case '\'':
+                               start = getStringEnd(document, start, end, curr);
+                               break;
+                       default:
+
+                               if (considerNesting) {
+
+                                       if ('(' == curr)
+                                               ++nestingLevel;
+                                       else if (')' == curr)
+                                               --nestingLevel;
+
+                                       if (nestingLevel != 0)
+                                               break;
+                               }
+
+                               if (increments.indexOf(curr) >= 0) {
+                                       ++charCount;
+                               }
+
+                               if (decrements.indexOf(curr) >= 0) {
+                                       --charCount;
+                               }
+                       }
+               }
+
+               return charCount;
+       }
+
+       /**
+        * @see IContextInformationValidator#isContextInformationValid(int)
+        */
+       public boolean isContextInformationValid(int position) {
+
+               try {
+                       if (position < fPosition)
+                               return false;
+
+                       IDocument document = fViewer.getDocument();
+                       IRegion line = document.getLineInformationOfOffset(fPosition);
+
+                       if (position < line.getOffset() || position >= document.getLength())
+                               return false;
+
+                       return getCharCount(document, fPosition, position,
+                                       "(<", ")>", false) >= 0; //$NON-NLS-1$//$NON-NLS-2$
+
+               } catch (BadLocationException x) {
+                       return false;
+               }
+       }
+
+       /**
+        * @see IContextInformationPresenter#updatePresentation(int,
+        *      TextPresentation)
+        */
+       public boolean updatePresentation(int position,
+                       TextPresentation presentation) {
+
+               int currentParameter = -1;
+
+               try {
+                       currentParameter = getCharCount(fViewer.getDocument(), fPosition,
+                                       position, ",", "", true); //$NON-NLS-1$//$NON-NLS-2$
+               } catch (BadLocationException x) {
+                       return false;
+               }
+
+               if (fCurrentParameter != -1) {
+                       if (currentParameter == fCurrentParameter)
+                               return false;
+               }
+
+               presentation.clear();
+               fCurrentParameter = currentParameter;
+
+               String s = fInformation.getInformationDisplayString();
+               int start = 0;
+               int occurrences = 0;
+               while (occurrences < fCurrentParameter) {
+                       int found = s.indexOf(',', start);
+                       if (found == -1)
+                               break;
+                       start = found + 1;
+                       ++occurrences;
+               }
+
+               if (occurrences < fCurrentParameter) {
+                       presentation.addStyleRange(new StyleRange(0, s.length(), null,
+                                       null, SWT.NORMAL));
+                       return true;
+               }
+
+               if (start == -1)
+                       start = 0;
+
+               int end = s.indexOf(',', start);
+               if (end == -1)
+                       end = s.length();
+
+               if (start > 0)
+                       presentation.addStyleRange(new StyleRange(0, start, null, null,
+                                       SWT.NORMAL));
+
+               if (end > start)
+                       presentation.addStyleRange(new StyleRange(start, end - start, null,
+                                       null, SWT.BOLD));
+
+               if (end < s.length())
+                       presentation.addStyleRange(new StyleRange(end, s.length() - end,
+                                       null, null, SWT.NORMAL));
+
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaReconcilingStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaReconcilingStrategy.java
new file mode 100644 (file)
index 0000000..7f91e31
--- /dev/null
@@ -0,0 +1,218 @@
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ **********************************************************************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class JavaReconcilingStrategy implements IReconcilingStrategy,
+               IReconcilingStrategyExtension {
+
+       private ITextEditor fEditor;
+
+       private IWorkingCopyManager fManager;
+
+       private IDocumentProvider fDocumentProvider;
+
+       private IProgressMonitor fProgressMonitor;
+
+       private boolean fNotify = true;
+
+       private IJavaReconcilingListener fJavaReconcilingListener;
+
+       private boolean fIsJavaReconcilingListener;
+
+       public JavaReconcilingStrategy(ITextEditor editor) {
+               fEditor = editor;
+               fManager = WebUI.getDefault().getWorkingCopyManager();
+               fDocumentProvider = WebUI.getDefault()
+                               .getCompilationUnitDocumentProvider();
+               fIsJavaReconcilingListener = fEditor instanceof IJavaReconcilingListener;
+               if (fIsJavaReconcilingListener)
+                       fJavaReconcilingListener = (IJavaReconcilingListener) fEditor;
+       }
+
+       private IProblemRequestorExtension getProblemRequestorExtension() {
+               IAnnotationModel model = fDocumentProvider.getAnnotationModel(fEditor
+                               .getEditorInput());
+               if (model instanceof IProblemRequestorExtension)
+                       return (IProblemRequestorExtension) model;
+               return null;
+       }
+
+       private void reconcile() {
+               // // try {
+               //
+               // /* fix for missing cancel flag communication */
+               // IProblemRequestorExtension extension =
+               // getProblemRequestorExtension();
+               // if (extension != null)
+               // extension.setProgressMonitor(fProgressMonitor);
+               //
+               // // reconcile
+               // // synchronized (unit) {
+               // // unit.reconcile(true, fProgressMonitor);
+               // // }
+               //
+               // Parser parser = new Parser();
+               // parser.initializeScanner();
+               // // actualParser.setFileToParse(fileToParse);
+               // String text =
+               // fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput()).get();
+               // parser.init(text);
+               // parser.reportSyntaxError();
+               // // checkAndReportBracketAnomalies(parser.problemReporter());
+               //
+               // /* fix for missing cancel flag communication */
+               // if (extension != null)
+               // extension.setProgressMonitor(null);
+               //
+               // // update participants
+               // try {
+               // if (fEditor instanceof IReconcilingParticipant && fNotify &&
+               // !fProgressMonitor.isCanceled()) {
+               // IReconcilingParticipant p = (IReconcilingParticipant) fEditor;
+               // p.reconciled();
+               // }
+               // } finally {
+               // fNotify = true;
+               // }
+
+               // JDT implementation:
+               try {
+                       ICompilationUnit unit = fManager.getWorkingCopy(fEditor
+                                       .getEditorInput());
+                       if (unit != null) {
+                               try {
+
+                                       /* fix for missing cancel flag communication */
+                                       IProblemRequestorExtension extension = getProblemRequestorExtension();
+                                       if (extension != null)
+                                               extension.setProgressMonitor(fProgressMonitor);
+
+                                       // reconcile
+                                       synchronized (unit) {
+                                               unit.reconcile(true, fProgressMonitor);
+                                       }
+
+                                       /* fix for missing cancel flag communication */
+                                       if (extension != null)
+                                               extension.setProgressMonitor(null);
+
+                                       // update participants
+                                       try {
+                                               if (fEditor instanceof IReconcilingParticipant
+                                                               && fNotify && !fProgressMonitor.isCanceled()) {
+                                                       IReconcilingParticipant p = (IReconcilingParticipant) fEditor;
+                                                       p.reconciled();
+                                               }
+                                       } finally {
+                                               fNotify = true;
+                                       }
+
+                               } catch (JavaModelException x) {
+                                       // swallow exception
+                               }
+                       }
+               } finally {
+                       // Always notify listeners, see
+                       // https://bugs.eclipse.org/bugs/show_bug.cgi?id=55969 for the final
+                       // solution
+                       try {
+                               if (fIsJavaReconcilingListener) {
+                                       IProgressMonitor pm = fProgressMonitor;
+                                       if (pm == null)
+                                               pm = new NullProgressMonitor();
+                                       fJavaReconcilingListener.reconciled(null, !fNotify, pm);
+                               }
+                       } finally {
+                               fNotify = true;
+                       }
+
+               }
+       }
+
+       /*
+        * @see IReconcilingStrategy#reconcile(IRegion)
+        */
+       public void reconcile(IRegion partition) {
+               reconcile();
+       }
+
+       /*
+        * @see IReconcilingStrategy#reconcile(DirtyRegion, IRegion)
+        */
+       public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+               reconcile();
+       }
+
+       /*
+        * @see IReconcilingStrategy#setDocument(IDocument)
+        */
+       public void setDocument(IDocument document) {
+       }
+
+       /*
+        * @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
+        */
+       public void setProgressMonitor(IProgressMonitor monitor) {
+               fProgressMonitor = monitor;
+       }
+
+       /*
+        * @see IReconcilingStrategyExtension#initialReconcile()
+        */
+       public void initialReconcile() {
+               reconcile();
+       }
+
+       /**
+        * Tells this strategy whether to inform its participants.
+        * 
+        * @param notify
+        *            <code>true</code> if participant should be notified
+        */
+       public void notifyParticipants(boolean notify) {
+               fNotify = notify;
+       }
+
+       /**
+        * Tells this strategy whether to inform its listeners.
+        * 
+        * @param notify
+        *            <code>true</code> if listeners should be notified
+        */
+       public void notifyListeners(boolean notify) {
+               fNotify = notify;
+       }
+
+       /**
+        * Called before reconciling is started.
+        * 
+        * @since 3.0
+        */
+       public void aboutToBeReconciled() {
+               if (fIsJavaReconcilingListener)
+                       fJavaReconcilingListener.aboutToBeReconciled();
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategyDQ.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategyDQ.java
new file mode 100644 (file)
index 0000000..0f18909
--- /dev/null
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.texteditor.ITextEditorExtension3;
+
+/**
+ * Auto indent strategy for java strings
+ */
+public class JavaStringAutoIndentStrategyDQ extends
+               DefaultIndentLineAutoEditStrategy {
+
+       private String fPartitioning;
+
+       /**
+        * The input string doesn't contain any line delimiter.
+        * 
+        * @param inputString
+        *            the given input string
+        * @return the displayable string.
+        */
+       private String displayString(String inputString, String indentation,
+                       String delimiter) {
+
+               int length = inputString.length();
+               StringBuffer buffer = new StringBuffer(length);
+               java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(
+                               inputString, "\n\r", true); //$NON-NLS-1$
+               while (tokenizer.hasMoreTokens()) {
+
+                       String token = tokenizer.nextToken();
+                       if (token.equals("\r")) { //$NON-NLS-1$
+                               buffer.append("\\r"); //$NON-NLS-1$
+                               if (tokenizer.hasMoreTokens()) {
+                                       token = tokenizer.nextToken();
+                                       if (token.equals("\n")) { //$NON-NLS-1$
+                                               buffer.append("\\n"); //$NON-NLS-1$
+                                               buffer.append("\" . " + delimiter); //$NON-NLS-1$
+                                               buffer.append(indentation);
+                                               buffer.append("\""); //$NON-NLS-1$
+                                               continue;
+                                       } else {
+                                               buffer.append("\" . " + delimiter); //$NON-NLS-1$
+                                               buffer.append(indentation);
+                                               buffer.append("\""); //$NON-NLS-1$
+                                       }
+                               } else {
+                                       continue;
+                               }
+                       } else if (token.equals("\n")) { //$NON-NLS-1$
+                               buffer.append("\\n"); //$NON-NLS-1$
+                               buffer.append("\" . " + delimiter); //$NON-NLS-1$
+                               buffer.append(indentation);
+                               buffer.append("\""); //$NON-NLS-1$
+                               continue;
+                       }
+
+                       StringBuffer tokenBuffer = new StringBuffer();
+                       for (int i = 0; i < token.length(); i++) {
+                               char c = token.charAt(i);
+                               switch (c) {
+                               case '\r':
+                                       tokenBuffer.append("\\r"); //$NON-NLS-1$
+                                       break;
+                               case '\n':
+                                       tokenBuffer.append("\\n"); //$NON-NLS-1$
+                                       break;
+                               case '\b':
+                                       tokenBuffer.append("\\b"); //$NON-NLS-1$
+                                       break;
+                               case '\t':
+                                       // keep tabs verbatim
+                                       tokenBuffer.append("\t"); //$NON-NLS-1$
+                                       break;
+                               case '\f':
+                                       tokenBuffer.append("\\f"); //$NON-NLS-1$
+                                       break;
+                               case '\"':
+                                       tokenBuffer.append("\\\""); //$NON-NLS-1$
+                                       break;
+                               case '\'':
+                                       tokenBuffer.append("\\'"); //$NON-NLS-1$
+                                       break;
+                               case '\\':
+                                       tokenBuffer.append("\\\\"); //$NON-NLS-1$
+                                       break;
+                               default:
+                                       tokenBuffer.append(c);
+                               }
+                       }
+                       buffer.append(tokenBuffer);
+               }
+               return buffer.toString();
+       }
+
+       /**
+        * Creates a new Java string auto indent strategy for the given document
+        * partitioning.
+        * 
+        * @param partitioning
+        *            the document partitioning
+        */
+       public JavaStringAutoIndentStrategyDQ(String partitioning) {
+               super();
+               fPartitioning = partitioning;
+       }
+
+       private boolean isLineDelimiter(IDocument document, String text) {
+               String[] delimiters = document.getLegalLineDelimiters();
+               if (delimiters != null)
+                       return TextUtilities.equals(delimiters, text) > -1;
+               return false;
+       }
+
+       private String getLineIndentation(IDocument document, int offset)
+                       throws BadLocationException {
+
+               // find start of line
+               int adjustedOffset = (offset == document.getLength() ? offset - 1
+                               : offset);
+               IRegion line = document.getLineInformationOfOffset(adjustedOffset);
+               int start = line.getOffset();
+
+               // find white spaces
+               int end = findEndOfWhiteSpace(document, start, offset);
+
+               return document.get(start, end - start);
+       }
+
+       private String getModifiedText(String string, String indentation,
+                       String delimiter) throws BadLocationException {
+               return displayString(string, indentation, delimiter);
+       }
+
+       private void javaStringIndentAfterNewLine(IDocument document,
+                       DocumentCommand command) throws BadLocationException {
+
+               ITypedRegion partition = TextUtilities.getPartition(document,
+                               fPartitioning, command.offset, false);
+               int offset = partition.getOffset();
+               int length = partition.getLength();
+
+               if (command.offset == offset) {
+                       // we are really just before the string partition -> feet the event
+                       // through the java indenter
+                       // new
+                       // JavaAutoIndentStrategy(fPartitioning).customizeDocumentCommand(document,
+                       // command);
+                       return;
+               }
+
+               if (command.offset == offset + length
+                               && document.getChar(offset + length - 1) == '\"')
+                       return;
+
+               String indentation = getLineIndentation(document, command.offset);
+               String delimiter = TextUtilities.getDefaultLineDelimiter(document);
+
+               IRegion line = document.getLineInformationOfOffset(offset);
+               String string = document.get(line.getOffset(), offset
+                               - line.getOffset());
+               if (string.trim().length() != 0)
+                       indentation += String.valueOf("\t\t"); //$NON-NLS-1$
+
+               IPreferenceStore preferenceStore = WebUI.getDefault()
+                               .getPreferenceStore();
+               if (isLineDelimiter(document, command.text))
+                       command.text = "\" ." + command.text + indentation + "\""; //$NON-NLS-1$//$NON-NLS-2$
+               else if (command.text.length() > 1
+                               && preferenceStore
+                                               .getBoolean(PreferenceConstants.EDITOR_ESCAPE_STRINGS_DQ))
+                       command.text = getModifiedText(command.text, indentation, delimiter);
+       }
+
+       private boolean isSmartMode() {
+               IWorkbenchPage page = WebUI.getActivePage();
+               if (page != null) {
+                       IEditorPart part = page.getActiveEditor();
+                       if (part instanceof ITextEditorExtension3) {
+                               ITextEditorExtension3 extension = (ITextEditorExtension3) part;
+                               return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
+                       }
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IAutoIndentStrategy#customizeDocumentCommand(IDocument,
+        *      DocumentCommand)
+        */
+       public void customizeDocumentCommand(IDocument document,
+                       DocumentCommand command) {
+               try {
+                       if (command.length != 0 || command.text == null)
+                               return;
+
+                       IPreferenceStore preferenceStore = WebUI.getDefault()
+                                       .getPreferenceStore();
+
+                       if (preferenceStore
+                                       .getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS_DQ)
+                                       && isSmartMode())
+                               javaStringIndentAfterNewLine(document, command);
+
+               } catch (BadLocationException e) {
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategySQ.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategySQ.java
new file mode 100644 (file)
index 0000000..72e6e67
--- /dev/null
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.texteditor.ITextEditorExtension3;
+
+/**
+ * Auto indent strategy for java strings
+ */
+public class JavaStringAutoIndentStrategySQ extends
+               DefaultIndentLineAutoEditStrategy {
+
+       private String fPartitioning;
+
+       /**
+        * The input string doesn't contain any line delimiter.
+        * 
+        * @param inputString
+        *            the given input string
+        * @return the displayable string.
+        */
+       private String displayString(String inputString, String indentation,
+                       String delimiter) {
+
+               int length = inputString.length();
+               StringBuffer buffer = new StringBuffer(length);
+               java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(
+                               inputString, "\n\r", true); //$NON-NLS-1$
+               while (tokenizer.hasMoreTokens()) {
+
+                       String token = tokenizer.nextToken();
+                       if (token.equals("\r")) { //$NON-NLS-1$
+                               buffer.append("\\r"); //$NON-NLS-1$
+                               if (tokenizer.hasMoreTokens()) {
+                                       token = tokenizer.nextToken();
+                                       if (token.equals("\n")) { //$NON-NLS-1$
+                                               buffer.append("\\n"); //$NON-NLS-1$
+                                               buffer.append("\' . " + delimiter); //$NON-NLS-1$
+                                               buffer.append(indentation);
+                                               buffer.append("\'"); //$NON-NLS-1$
+                                               continue;
+                                       } else {
+                                               buffer.append("\' . " + delimiter); //$NON-NLS-1$
+                                               buffer.append(indentation);
+                                               buffer.append("\'"); //$NON-NLS-1$
+                                       }
+                               } else {
+                                       continue;
+                               }
+                       } else if (token.equals("\n")) { //$NON-NLS-1$
+                               buffer.append("\\n"); //$NON-NLS-1$
+                               buffer.append("\' . " + delimiter); //$NON-NLS-1$
+                               buffer.append(indentation);
+                               buffer.append("\'"); //$NON-NLS-1$
+                               continue;
+                       }
+
+                       StringBuffer tokenBuffer = new StringBuffer();
+                       for (int i = 0; i < token.length(); i++) {
+                               char c = token.charAt(i);
+                               switch (c) {
+                               case '\r':
+                                       tokenBuffer.append("\\r"); //$NON-NLS-1$
+                                       break;
+                               case '\n':
+                                       tokenBuffer.append("\\n"); //$NON-NLS-1$
+                                       break;
+                               case '\b':
+                                       tokenBuffer.append("\\b"); //$NON-NLS-1$
+                                       break;
+                               case '\t':
+                                       // keep tabs verbatim
+                                       tokenBuffer.append("\t"); //$NON-NLS-1$
+                                       break;
+                               case '\f':
+                                       tokenBuffer.append("\\f"); //$NON-NLS-1$
+                                       break;
+                               case '\"':
+                                       tokenBuffer.append("\\\""); //$NON-NLS-1$
+                                       break;
+                               case '\'':
+                                       tokenBuffer.append("\\'"); //$NON-NLS-1$
+                                       break;
+                               case '\\':
+                                       tokenBuffer.append("\\\\"); //$NON-NLS-1$
+                                       break;
+                               default:
+                                       tokenBuffer.append(c);
+                               }
+                       }
+                       buffer.append(tokenBuffer);
+               }
+               return buffer.toString();
+       }
+
+       /**
+        * Creates a new Java string auto indent strategy for the given document
+        * partitioning.
+        * 
+        * @param partitioning
+        *            the document partitioning
+        */
+       public JavaStringAutoIndentStrategySQ(String partitioning) {
+               super();
+               fPartitioning = partitioning;
+       }
+
+       private boolean isLineDelimiter(IDocument document, String text) {
+               String[] delimiters = document.getLegalLineDelimiters();
+               if (delimiters != null)
+                       return TextUtilities.equals(delimiters, text) > -1;
+               return false;
+       }
+
+       private String getLineIndentation(IDocument document, int offset)
+                       throws BadLocationException {
+
+               // find start of line
+               int adjustedOffset = (offset == document.getLength() ? offset - 1
+                               : offset);
+               IRegion line = document.getLineInformationOfOffset(adjustedOffset);
+               int start = line.getOffset();
+
+               // find white spaces
+               int end = findEndOfWhiteSpace(document, start, offset);
+
+               return document.get(start, end - start);
+       }
+
+       private String getModifiedText(String string, String indentation,
+                       String delimiter) throws BadLocationException {
+               return displayString(string, indentation, delimiter);
+       }
+
+       private void javaStringIndentAfterNewLine(IDocument document,
+                       DocumentCommand command) throws BadLocationException {
+
+               ITypedRegion partition = TextUtilities.getPartition(document,
+                               fPartitioning, command.offset, false);
+               int offset = partition.getOffset();
+               int length = partition.getLength();
+
+               if (command.offset == offset) {
+                       // we are really just before the string partition -> feet the event
+                       // through the java indenter
+                       // new
+                       // JavaAutoIndentStrategy(fPartitioning).customizeDocumentCommand(document,
+                       // command);
+                       return;
+               }
+
+               if (command.offset == offset + length
+                               && document.getChar(offset + length - 1) == '\'')
+                       return;
+
+               String indentation = getLineIndentation(document, command.offset);
+               String delimiter = TextUtilities.getDefaultLineDelimiter(document);
+
+               IRegion line = document.getLineInformationOfOffset(offset);
+               String string = document.get(line.getOffset(), offset
+                               - line.getOffset());
+               if (string.trim().length() != 0)
+                       indentation += String.valueOf("\t\t"); //$NON-NLS-1$
+
+               IPreferenceStore preferenceStore = WebUI.getDefault()
+                               .getPreferenceStore();
+               if (isLineDelimiter(document, command.text))
+                       command.text = "\' ." + command.text + indentation + "\'"; //$NON-NLS-1$//$NON-NLS-2$
+               else if (command.text.length() > 1
+                               && preferenceStore
+                                               .getBoolean(PreferenceConstants.EDITOR_ESCAPE_STRINGS_SQ))
+                       command.text = getModifiedText(command.text, indentation, delimiter);
+       }
+
+       private boolean isSmartMode() {
+               IWorkbenchPage page = WebUI.getActivePage();
+               if (page != null) {
+                       IEditorPart part = page.getActiveEditor();
+                       if (part instanceof ITextEditorExtension3) {
+                               ITextEditorExtension3 extension = (ITextEditorExtension3) part;
+                               return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
+                       }
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IAutoIndentStrategy#customizeDocumentCommand(IDocument,
+        *      DocumentCommand)
+        */
+       public void customizeDocumentCommand(IDocument document,
+                       DocumentCommand command) {
+               try {
+                       if (command.length != 0 || command.text == null)
+                               return;
+
+                       IPreferenceStore preferenceStore = WebUI.getDefault()
+                                       .getPreferenceStore();
+
+                       if (preferenceStore
+                                       .getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS_SQ)
+                                       && isSmartMode())
+                               javaStringIndentAfterNewLine(document, command);
+
+               } catch (BadLocationException e) {
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/PHPCompletionProposalComparator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/PHPCompletionProposalComparator.java
new file mode 100644 (file)
index 0000000..bad8e94
--- /dev/null
@@ -0,0 +1,36 @@
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import java.util.Comparator;
+
+public class PHPCompletionProposalComparator implements Comparator {
+
+       private boolean fOrderAlphabetically;
+
+       /**
+        * Constructor for CompletionProposalComparator.
+        */
+       // public PHPCompletionProposalComparator() {
+       // fOrderAlphabetically= false;
+       // }
+       public void setOrderAlphabetically(boolean orderAlphabetically) {
+               fOrderAlphabetically = orderAlphabetically;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see Comparator#compare(Object, Object)
+        */
+       public int compare(Object o1, Object o2) {
+               IPHPCompletionProposal c1 = (IPHPCompletionProposal) o1;
+               IPHPCompletionProposal c2 = (IPHPCompletionProposal) o2;
+               if (!fOrderAlphabetically) {
+                       int relevanceDif = c2.getRelevance() - c1.getRelevance();
+                       if (relevanceDif != 0) {
+                               return relevanceDif;
+                       }
+               }
+               return c1.getDisplayString().compareToIgnoreCase(c2.getDisplayString());
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractAnnotationHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractAnnotationHover.java
new file mode 100644 (file)
index 0000000..c1bbbdb
--- /dev/null
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.internal.ui.text.HTMLPrinter;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.JavaAnnotationIterator;
+import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+
+/**
+ * Abstract super class for annotation hovers.
+ * 
+ * @since 3.0
+ */
+public abstract class AbstractAnnotationHover extends
+               AbstractJavaEditorTextHover {
+
+       private IPreferenceStore fStore = WebUI.getDefault()
+                       .getCombinedPreferenceStore();
+
+       private DefaultMarkerAnnotationAccess fAnnotationAccess = new DefaultMarkerAnnotationAccess();
+
+       private boolean fAllAnnotations;
+
+       public AbstractAnnotationHover(boolean allAnnotations) {
+               fAllAnnotations = allAnnotations;
+       }
+
+       /*
+        * Formats a message as HTML text.
+        */
+       private String formatMessage(String message) {
+               StringBuffer buffer = new StringBuffer();
+               HTMLPrinter.addPageProlog(buffer);
+               HTMLPrinter.addParagraph(buffer, HTMLPrinter
+                               .convertToHTMLContent(message));
+               HTMLPrinter.addPageEpilog(buffer);
+               return buffer.toString();
+       }
+
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+
+               if (getEditor() == null)
+                       return null;
+
+               IDocumentProvider provider = WebUI.getDefault()
+                               .getCompilationUnitDocumentProvider();
+               IAnnotationModel model = provider.getAnnotationModel(getEditor()
+                               .getEditorInput());
+
+               if (model != null) {
+                       Iterator e = new JavaAnnotationIterator(model, true,
+                                       fAllAnnotations);
+                       int layer = -1;
+                       String message = null;
+                       while (e.hasNext()) {
+                               Annotation a = (Annotation) e.next();
+
+                               AnnotationPreference preference = getAnnotationPreference(a);
+                               if (preference == null
+                                               || !(preference.getTextPreferenceKey() != null
+                                                               && fStore.getBoolean(preference
+                                                                               .getTextPreferenceKey()) || (preference
+                                                               .getHighlightPreferenceKey() != null && fStore
+                                                               .getBoolean(preference
+                                                                               .getHighlightPreferenceKey()))))
+                                       continue;
+
+                               Position p = model.getPosition(a);
+
+                               int l = fAnnotationAccess.getLayer(a);
+
+                               if (l > layer
+                                               && p != null
+                                               && p.overlapsWith(hoverRegion.getOffset(), hoverRegion
+                                                               .getLength())) {
+                                       String msg = a.getText();
+                                       if (msg != null && msg.trim().length() > 0) {
+                                               message = msg;
+                                               layer = l;
+                                       }
+                               }
+                       }
+                       if (layer > -1)
+                               return formatMessage(message);
+               }
+
+               return null;
+       }
+
+       /*
+        * @see IJavaEditorTextHover#setEditor(IEditorPart)
+        */
+       public void setEditor(IEditorPart editor) {
+               if (editor instanceof PHPUnitEditor)
+                       super.setEditor(editor);
+               else
+                       super.setEditor(null);
+       }
+
+       /**
+        * Returns the annotation preference for the given annotation.
+        * 
+        * @param annotation
+        *            the annotation
+        * @return the annotation preference or <code>null</code> if none
+        */
+       private AnnotationPreference getAnnotationPreference(Annotation annotation) {
+
+               if (annotation.isMarkedDeleted())
+                       return null;
+               return EditorsUI.getAnnotationPreferenceLookup()
+                               .getAnnotationPreference(annotation);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java
new file mode 100644 (file)
index 0000000..70669e4
--- /dev/null
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.List;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
+import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommand;
+import org.eclipse.ui.commands.ICommandManager;
+import org.eclipse.ui.commands.IKeySequenceBinding;
+import org.eclipse.ui.keys.KeySequence;
+
+/**
+ * Abstract class for providing hover information for Java elements.
+ * 
+ * @since 2.1
+ */
+public abstract class AbstractJavaEditorTextHover implements
+               IJavaEditorTextHover {
+
+       private IEditorPart fEditor;
+
+       private ICommand fCommand;
+       {
+               ICommandManager commandManager = PlatformUI.getWorkbench()
+                               .getCommandSupport().getCommandManager();
+               // fCommand=
+               // commandManager.getCommand(PHPEditorActionDefinitionIds.SHOW_JAVADOC);
+               // if (!fCommand.isDefined())
+               fCommand = null;
+       }
+
+       /*
+        * @see IJavaEditorTextHover#setEditor(IEditorPart)
+        */
+       public void setEditor(IEditorPart editor) {
+               fEditor = editor;
+       }
+
+       protected IEditorPart getEditor() {
+               return fEditor;
+       }
+
+       // protected ICodeAssist getCodeAssist() {
+       // if (fEditor != null) {
+       // IEditorInput input= fEditor.getEditorInput();
+       // if (input instanceof IClassFileEditorInput) {
+       // IClassFileEditorInput cfeInput= (IClassFileEditorInput) input;
+       // return cfeInput.getClassFile();
+       // }
+       //
+       // IWorkingCopyManager manager=
+       // PHPeclipsePlugin.getDefault().getWorkingCopyManager();
+       // return manager.getWorkingCopy(input);
+       // }
+       //
+       // return null;
+       // }
+
+       /*
+        * @see ITextHover#getHoverRegion(ITextViewer, int)
+        */
+       public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+               return JavaWordFinder.findWord(textViewer.getDocument(), offset);
+       }
+
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+
+               // ICodeAssist resolve= getCodeAssist();
+               // if (resolve != null) {
+               // try {
+               // IJavaElement[] result= null;
+               //
+               // synchronized (resolve) {
+               // result= resolve.codeSelect(hoverRegion.getOffset(),
+               // hoverRegion.getLength());
+               // }
+               //
+               // if (result == null)
+               // return null;
+               //
+               // int nResults= result.length;
+               // if (nResults == 0)
+               // return null;
+               //
+               // return getHoverInfo(result);
+               //
+               // } catch (JavaModelException x) {
+               // PHPeclipsePlugin.log(x.getStatus());
+               // }
+               // }
+               return null;
+       }
+
+       /**
+        * Provides hover information for the given Java elements.
+        * 
+        * @return the hover information string
+        * @since 2.1
+        */
+       protected String getHoverInfo(IJavaElement[] javaElements) {
+               return null;
+       }
+
+       /*
+        * @see ITextHoverExtension#getHoverControlCreator()
+        * @since 3.0
+        */
+       public IInformationControlCreator getHoverControlCreator() {
+               return new IInformationControlCreator() {
+                       public IInformationControl createInformationControl(Shell parent) {
+                               return new DefaultInformationControl(parent, SWT.NONE,
+                                               new HTMLTextPresenter(true),
+                                               getTooltipAffordanceString());
+                       }
+               };
+       }
+
+       /**
+        * Returns the tool tip affordance string.
+        * 
+        * @return the affordance string or <code>null</code> if disabled or no
+        *         key binding is defined
+        * @since 3.0
+        */
+       protected String getTooltipAffordanceString() {
+               if (!WebUI.getDefault().getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE))
+                       return null;
+
+               KeySequence[] sequences = getKeySequences();
+               if (sequences == null)
+                       return null;
+
+               String keySequence = sequences[0].format();
+               return JavaHoverMessages.getFormattedString(
+                               "JavaTextHover.makeStickyHint", keySequence); //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the array of valid key sequence bindings for the show tool tip
+        * description command.
+        * 
+        * @return the array with the {@link KeySequence}s
+        * 
+        * @since 3.0
+        */
+       private KeySequence[] getKeySequences() {
+               if (fCommand != null) {
+                       List list = fCommand.getKeySequenceBindings();
+                       if (!list.isEmpty()) {
+                               KeySequence[] keySequences = new KeySequence[list.size()];
+                               for (int i = 0; i < keySequences.length; i++) {
+                                       keySequences[i] = ((IKeySequenceBinding) list.get(i))
+                                                       .getKeySequence();
+                               }
+                               return keySequences;
+                       }
+               }
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java
new file mode 100644 (file)
index 0000000..581517a
--- /dev/null
@@ -0,0 +1,337 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.text.java.hover.AnnotationExpansionControl.AnnotationHoverInput;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IInformationControlCreatorExtension;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.CompositeRuler;
+import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IAnnotationAccessExtension;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationHoverExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ILineRange;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRulerListener;
+import org.eclipse.jface.text.source.LineRange;
+import org.eclipse.jface.text.source.VerticalRulerEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This class got moved here form Platform Text since it was not used there and
+ * caused discouraged access warnings. It will be moved down again once
+ * annotation roll-over support is provided by Platform Text.
+ * 
+ * @since 3.2
+ */
+public class AnnotationExpandHover implements IAnnotationHover,
+               IAnnotationHoverExtension {
+
+       private class InformationControlCreator implements
+                       IInformationControlCreator, IInformationControlCreatorExtension {
+
+               /*
+                * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell)
+                */
+               public IInformationControl createInformationControl(Shell parent) {
+                       return new AnnotationExpansionControl(parent, SWT.NONE,
+                                       fAnnotationAccess);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReuse(org.eclipse.jface.text.IInformationControl)
+                */
+               public boolean canReuse(IInformationControl control) {
+                       return control instanceof AnnotationExpansionControl;
+               }
+
+               /*
+                * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReplace(org.eclipse.jface.text.IInformationControlCreator)
+                */
+               public boolean canReplace(IInformationControlCreator creator) {
+                       return creator == this;
+               }
+       }
+
+       private class VerticalRulerListener implements IVerticalRulerListener {
+
+               /*
+                * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationSelected(org.eclipse.jface.text.source.VerticalRulerEvent)
+                */
+               public void annotationSelected(VerticalRulerEvent event) {
+                       fCompositeRuler.fireAnnotationSelected(event);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationDefaultSelected(org.eclipse.jface.text.source.VerticalRulerEvent)
+                */
+               public void annotationDefaultSelected(VerticalRulerEvent event) {
+                       fCompositeRuler.fireAnnotationDefaultSelected(event);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationContextMenuAboutToShow(org.eclipse.jface.text.source.VerticalRulerEvent,
+                *      org.eclipse.swt.widgets.Menu)
+                */
+               public void annotationContextMenuAboutToShow(VerticalRulerEvent event,
+                               Menu menu) {
+                       fCompositeRuler.fireAnnotationContextMenuAboutToShow(event, menu);
+               }
+       }
+
+       private final IInformationControlCreator fgCreator = new InformationControlCreator();
+
+       protected final IVerticalRulerListener fgListener = new VerticalRulerListener();
+
+       protected CompositeRuler fCompositeRuler;
+
+       protected IDoubleClickListener fDblClickListener;
+
+       protected IAnnotationAccess fAnnotationAccess;
+
+       /**
+        * Creates a new hover instance.
+        * 
+        * @param ruler
+        * @param access
+        * @param doubleClickListener
+        */
+       public AnnotationExpandHover(CompositeRuler ruler,
+                       IAnnotationAccess access, IDoubleClickListener doubleClickListener) {
+               fCompositeRuler = ruler;
+               fAnnotationAccess = access;
+               fDblClickListener = doubleClickListener;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer,
+        *      int)
+        */
+       public String getHoverInfo(ISourceViewer sourceViewer, int line) {
+               // we don't have any sensible return value as text
+               return null;
+       }
+
+       protected Object getHoverInfoForLine(ISourceViewer viewer, int line) {
+               IAnnotationModel model = viewer.getAnnotationModel();
+               IDocument document = viewer.getDocument();
+
+               if (model == null)
+                       return null;
+
+               List exact = new ArrayList();
+               HashMap messagesAtPosition = new HashMap();
+
+               Iterator e = model.getAnnotationIterator();
+               while (e.hasNext()) {
+                       Annotation annotation = (Annotation) e.next();
+                       Position position = model.getPosition(annotation);
+                       if (position == null)
+                               continue;
+
+                       if (compareRulerLine(position, document, line) == 1) {
+                               if (isDuplicateMessage(messagesAtPosition, position, annotation
+                                               .getText()))
+                                       continue;
+
+                               exact.add(annotation);
+                       }
+               }
+
+               if (exact.size() < 1)
+                       return null;
+
+               sort(exact, model);
+
+               if (exact.size() > 0)
+                       setLastRulerMouseLocation(viewer, line);
+
+               AnnotationHoverInput input = new AnnotationHoverInput();
+               input.fAnnotations = (Annotation[]) exact.toArray(new Annotation[0]);
+               input.fViewer = viewer;
+               input.fRulerInfo = fCompositeRuler;
+               input.fAnnotationListener = fgListener;
+               input.fDoubleClickListener = fDblClickListener;
+               input.model = model;
+
+               return input;
+       }
+
+       protected void sort(List exact, final IAnnotationModel model) {
+               class AnnotationComparator implements Comparator {
+
+                       /*
+                        * @see java.util.Comparator#compare(java.lang.Object,
+                        *      java.lang.Object)
+                        */
+                       public int compare(Object o1, Object o2) {
+                               Annotation a1 = (Annotation) o1;
+                               Annotation a2 = (Annotation) o2;
+
+                               Position p1 = model.getPosition(a1);
+                               Position p2 = model.getPosition(a2);
+
+                               // annotation order:
+                               // primary order: by position in line
+                               // secondary: annotation importance
+                               if (p1.offset == p2.offset)
+                                       return getOrder(a2) - getOrder(a1);
+                               return p1.offset - p2.offset;
+                       }
+               }
+
+               Collections.sort(exact, new AnnotationComparator());
+
+       }
+
+       protected int getOrder(Annotation annotation) {
+               if (fAnnotationAccess instanceof IAnnotationAccessExtension) {
+                       IAnnotationAccessExtension extension = (IAnnotationAccessExtension) fAnnotationAccess;
+                       return extension.getLayer(annotation);
+               }
+               return IAnnotationAccessExtension.DEFAULT_LAYER;
+       }
+
+       protected boolean isDuplicateMessage(Map messagesAtPosition,
+                       Position position, String message) {
+               if (message == null)
+                       return false;
+
+               if (messagesAtPosition.containsKey(position)) {
+                       Object value = messagesAtPosition.get(position);
+                       if (message == null || message.equals(value))
+                               return true;
+
+                       if (value instanceof List) {
+                               List messages = (List) value;
+                               if (messages.contains(message))
+                                       return true;
+                               messages.add(message);
+                       } else {
+                               ArrayList messages = new ArrayList();
+                               messages.add(value);
+                               messages.add(message);
+                               messagesAtPosition.put(position, messages);
+                       }
+               } else
+                       messagesAtPosition.put(position, message);
+               return false;
+       }
+
+       protected void setLastRulerMouseLocation(ISourceViewer viewer, int line) {
+               // set last mouse activity in order to get the correct context menu
+               if (fCompositeRuler != null) {
+                       StyledText st = viewer.getTextWidget();
+                       if (st != null && !st.isDisposed()) {
+                               if (viewer instanceof ITextViewerExtension5) {
+                                       int widgetLine = ((ITextViewerExtension5) viewer)
+                                                       .modelLine2WidgetLine(line);
+                                       Point loc = st.getLocationAtOffset(st
+                                                       .getOffsetAtLine(widgetLine));
+                                       fCompositeRuler.setLocationOfLastMouseButtonActivity(0,
+                                                       loc.y);
+                               } else if (viewer instanceof TextViewer) {
+                                       // TODO remove once TextViewer implements the extension
+                                       int widgetLine = ((TextViewer) viewer)
+                                                       .modelLine2WidgetLine(line);
+                                       Point loc = st.getLocationAtOffset(st
+                                                       .getOffsetAtLine(widgetLine));
+                                       fCompositeRuler.setLocationOfLastMouseButtonActivity(0,
+                                                       loc.y);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Returns the distance to the ruler line.
+        * 
+        * @param position
+        *            the position
+        * @param document
+        *            the document
+        * @param line
+        *            the line number
+        * @return the distance to the ruler line
+        */
+       protected int compareRulerLine(Position position, IDocument document,
+                       int line) {
+
+               if (position.getOffset() > -1 && position.getLength() > -1) {
+                       try {
+                               int firstLine = document.getLineOfOffset(position.getOffset());
+                               if (line == firstLine)
+                                       return 1;
+                               if (firstLine <= line
+                                               && line <= document.getLineOfOffset(position
+                                                               .getOffset()
+                                                               + position.getLength()))
+                                       return 2;
+                       } catch (BadLocationException x) {
+                       }
+               }
+
+               return 0;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator()
+        */
+       public IInformationControlCreator getHoverControlCreator() {
+               return fgCreator;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer,
+        *      org.eclipse.jface.text.source.ILineRange, int)
+        */
+       public Object getHoverInfo(ISourceViewer sourceViewer,
+                       ILineRange lineRange, int visibleLines) {
+               return getHoverInfoForLine(sourceViewer, lineRange.getStartLine());
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(org.eclipse.jface.text.source.ISourceViewer,
+        *      int)
+        */
+       public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) {
+               return new LineRange(lineNumber, 1);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor()
+        */
+       public boolean canHandleMouseCursor() {
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java
new file mode 100644 (file)
index 0000000..199eaaf
--- /dev/null
@@ -0,0 +1,890 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.AbstractInformationControlManager;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IInformationControlExtension;
+import org.eclipse.jface.text.IInformationControlExtension2;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.IViewportListener;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IAnnotationAccessExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.text.source.IVerticalRulerListener;
+import org.eclipse.jface.text.source.VerticalRulerEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+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.Canvas;
+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.Layout;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * A control that can display a number of annotations. The control can decide
+ * how it layouts the annotations to present them to the user.
+ * <p>
+ * This class got moved here form Platform Text since it was not used there and
+ * caused discouraged access warnings. It will be moved down again once
+ * annotation roll-over support is provided by Platform Text.
+ * </p>
+ * <p>
+ * Each annotation can have its custom context menu and hover.
+ * </p>
+ * 
+ * @since 3.2
+ */
+public class AnnotationExpansionControl implements IInformationControl,
+               IInformationControlExtension, IInformationControlExtension2 {
+
+       public interface ICallback {
+               void run(IInformationControlExtension2 control);
+       }
+
+       /**
+        * Input used by the control to display the annotations. TODO move to
+        * top-level class TODO encapsulate fields
+        * 
+        * @since 3.0
+        */
+       public static class AnnotationHoverInput {
+               public Annotation[] fAnnotations;
+
+               public ISourceViewer fViewer;
+
+               public IVerticalRulerInfo fRulerInfo;
+
+               public IVerticalRulerListener fAnnotationListener;
+
+               public IDoubleClickListener fDoubleClickListener;
+
+               public ICallback redoAction;
+
+               public IAnnotationModel model;
+       }
+
+       private final class Item {
+               Annotation fAnnotation;
+
+               Canvas canvas;
+
+               StyleRange[] oldStyles;
+
+               public void selected() {
+                       Display disp = fShell.getDisplay();
+                       canvas.setCursor(fHandCursor);
+                       // TODO: shade - for now: set grey background
+                       canvas.setBackground(getSelectionColor(disp));
+
+                       // highlight the viewer background at its position
+                       oldStyles = setViewerBackground(fAnnotation);
+
+                       // set the selection
+                       fSelection = this;
+
+                       if (fHoverManager != null)
+                               fHoverManager.showInformation();
+
+                       if (fInput.fAnnotationListener != null) {
+                               VerticalRulerEvent event = new VerticalRulerEvent(fAnnotation);
+                               fInput.fAnnotationListener.annotationSelected(event);
+                       }
+
+               }
+
+               public void defaultSelected() {
+                       if (fInput.fAnnotationListener != null) {
+                               VerticalRulerEvent event = new VerticalRulerEvent(fAnnotation);
+                               fInput.fAnnotationListener.annotationDefaultSelected(event);
+                       }
+
+                       dispose();
+               }
+
+               public void showContextMenu(Menu menu) {
+                       if (fInput.fAnnotationListener != null) {
+                               VerticalRulerEvent event = new VerticalRulerEvent(fAnnotation);
+                               fInput.fAnnotationListener.annotationContextMenuAboutToShow(
+                                               event, menu);
+                       }
+               }
+
+               public void deselect() {
+                       // hide the popup
+                       // fHoverManager.disposeInformationControl();
+
+                       // deselect
+                       fSelection = null;
+
+                       resetViewerBackground(oldStyles);
+                       oldStyles = null;
+
+                       Display disp = fShell.getDisplay();
+                       canvas.setCursor(null);
+                       // TODO: remove shading - for now: set standard background
+                       canvas
+                                       .setBackground(disp
+                                                       .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+
+               }
+
+       }
+
+       /**
+        * Disposes of an item
+        */
+       private final static class MyDisposeListener implements DisposeListener {
+               /*
+                * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+                */
+               public void widgetDisposed(DisposeEvent e) {
+                       Item item = (Item) ((Widget) e.getSource()).getData();
+                       item.deselect();
+                       item.canvas = null;
+                       item.fAnnotation = null;
+                       item.oldStyles = null;
+
+                       ((Widget) e.getSource()).setData(null);
+               }
+       }
+
+       /**
+        * Listener on context menu invocation on the items
+        */
+       private final class MyMenuDetectListener implements Listener {
+               /*
+                * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+                */
+               public void handleEvent(Event event) {
+                       if (event.type == SWT.MenuDetect) {
+                               // TODO: show per-item menu
+                               // for now: show ruler context menu
+                               if (fInput != null) {
+                                       Control ruler = fInput.fRulerInfo.getControl();
+                                       if (ruler != null && !ruler.isDisposed()) {
+                                               Menu menu = ruler.getMenu();
+                                               if (menu != null && !menu.isDisposed()) {
+                                                       menu.setLocation(event.x, event.y);
+                                                       menu.addMenuListener(new MenuListener() {
+
+                                                               public void menuHidden(MenuEvent e) {
+                                                                       dispose();
+                                                               }
+
+                                                               public void menuShown(MenuEvent e) {
+                                                               }
+
+                                                       });
+                                                       menu.setVisible(true);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Listener on mouse events on the items.
+        */
+       private final class MyMouseListener extends MouseAdapter {
+               /*
+                * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseDoubleClick(MouseEvent e) {
+                       Item item = (Item) ((Widget) e.getSource()).getData();
+                       if (e.button == 1 && item.fAnnotation == fInput.fAnnotations[0]
+                                       && fInput.fDoubleClickListener != null) {
+                               fInput.fDoubleClickListener.doubleClick(null);
+                               // special code for JDT to renew the annotation set.
+                               if (fInput.redoAction != null)
+                                       fInput.redoAction.run(AnnotationExpansionControl.this);
+                       }
+                       // dispose();
+                       // TODO special action to invoke double-click action on the vertical
+                       // ruler
+                       // how about
+                       // Canvas can= (Canvas) e.getSource();
+                       // Annotation a= (Annotation) can.getData();
+                       // if (a != null) {
+                       // a.getDoubleClickAction().run();
+                       // }
+               }
+
+               /*
+                * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseUp(MouseEvent e) {
+                       Item item = (Item) ((Widget) e.getSource()).getData();
+                       // TODO for now, to make double click work: disable single click on
+                       // the first item
+                       // disable later when the annotationlistener selectively handles
+                       // input
+                       if (item != null && e.button == 1) // && item.fAnnotation !=
+                                                                                               // fInput.fAnnotations[0])
+                               item.defaultSelected();
+               }
+
+               /*
+                * @see org.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseDown(MouseEvent e) {
+                       super.mouseDown(e);
+               }
+       }
+
+       /**
+        * Listener on mouse track events on the items.
+        */
+       private final class MyMouseTrackListener implements MouseTrackListener {
+               /*
+                * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseEnter(MouseEvent e) {
+                       Item item = (Item) ((Widget) e.getSource()).getData();
+                       if (item != null)
+                               item.selected();
+               }
+
+               /*
+                * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseExit(MouseEvent e) {
+
+                       Item item = (Item) ((Widget) e.getSource()).getData();
+                       if (item != null)
+                               item.deselect();
+
+                       // if the event lies outside the entire popup, dispose
+                       org.eclipse.swt.graphics.Region region = fShell.getRegion();
+                       Canvas can = (Canvas) e.getSource();
+                       Point p = can.toDisplay(e.x, e.y);
+                       if (region == null) {
+                               Rectangle bounds = fShell.getBounds();
+                               // p= fShell.toControl(p);
+                               if (!bounds.contains(p))
+                                       dispose();
+                       } else {
+                               p = fShell.toControl(p);
+                               if (!region.contains(p))
+                                       dispose();
+                       }
+
+               }
+
+               /*
+                * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseHover(MouseEvent e) {
+                       if (fHoverManager == null) {
+                               fHoverManager = new HoverManager();
+                               fHoverManager.takesFocusWhenVisible(false);
+                               fHoverManager.install(fComposite);
+                               fHoverManager.showInformation();
+                       }
+               }
+       }
+
+       /**
+        * 
+        * 
+        * @since 3.0
+        */
+       public class LinearLayouter {
+
+               private static final int ANNOTATION_SIZE = 14;
+
+               private static final int BORDER_WIDTH = 2;
+
+               public Layout getLayout(int itemCount) {
+                       // simple layout: a row of items
+                       GridLayout layout = new GridLayout(itemCount, true);
+                       layout.horizontalSpacing = 1;
+                       layout.verticalSpacing = 0;
+                       layout.marginHeight = 1;
+                       layout.marginWidth = 1;
+                       return layout;
+               }
+
+               public Object getLayoutData() {
+                       GridData gridData = new GridData(
+                                       ANNOTATION_SIZE + 2 * BORDER_WIDTH, ANNOTATION_SIZE + 2
+                                                       * BORDER_WIDTH);
+                       gridData.horizontalAlignment = GridData.CENTER;
+                       gridData.verticalAlignment = GridData.CENTER;
+                       return gridData;
+               }
+
+               public int getAnnotationSize() {
+                       return ANNOTATION_SIZE;
+               }
+
+               public int getBorderWidth() {
+                       return BORDER_WIDTH;
+               }
+
+               public org.eclipse.swt.graphics.Region getShellRegion(int itemCount) {
+                       // no special region - set to null for default shell size
+                       return null;
+               }
+
+       }
+
+       /**
+        * Listener on paint events on the items. Paints the annotation image on the
+        * given <code>GC</code>.
+        */
+       private final class MyPaintListener implements PaintListener {
+               /*
+                * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
+                */
+               public void paintControl(PaintEvent e) {
+                       Canvas can = (Canvas) e.getSource();
+                       Annotation a = ((Item) can.getData()).fAnnotation;
+                       if (a != null) {
+                               Rectangle rect = new Rectangle(fLayouter.getBorderWidth(),
+                                               fLayouter.getBorderWidth(), fLayouter
+                                                               .getAnnotationSize(), fLayouter
+                                                               .getAnnotationSize());
+                               if (fAnnotationAccessExtension != null)
+                                       fAnnotationAccessExtension.paint(a, e.gc, can, rect);
+                       }
+               }
+       }
+
+       /**
+        * Our own private hover manager used to shop per-item pop-ups.
+        */
+       private final class HoverManager extends AbstractInformationControlManager {
+
+               /**
+                * 
+                */
+               public HoverManager() {
+                       super(new IInformationControlCreator() {
+                               public IInformationControl createInformationControl(Shell parent) {
+                                       return new DefaultInformationControl(parent);
+                               }
+                       });
+
+                       setMargins(5, 10);
+                       setAnchor(ANCHOR_BOTTOM);
+                       setFallbackAnchors(new Anchor[] { ANCHOR_BOTTOM, ANCHOR_LEFT,
+                                       ANCHOR_RIGHT });
+               }
+
+               /*
+                * @see org.eclipse.jface.text.AbstractInformationControlManager#computeInformation()
+                */
+               protected void computeInformation() {
+                       if (fSelection != null) {
+                               Rectangle subjectArea = fSelection.canvas.getBounds();
+                               Annotation annotation = fSelection.fAnnotation;
+                               String msg;
+                               if (annotation != null)
+                                       msg = annotation.getText();
+                               else
+                                       msg = null;
+
+                               setInformation(msg, subjectArea);
+                       }
+               }
+
+       }
+
+       /** Model data. */
+       protected AnnotationHoverInput fInput;
+
+       /** The control's shell */
+       private Shell fShell;
+
+       /** The composite combining all the items. */
+       protected Composite fComposite;
+
+       /** The hand cursor. */
+       private Cursor fHandCursor;
+
+       /** The currently selected item, or <code>null</code> if none is selected. */
+       private Item fSelection;
+
+       /** The hover manager for the per-item hovers. */
+       private HoverManager fHoverManager;
+
+       /** The annotation access extension. */
+       private IAnnotationAccessExtension fAnnotationAccessExtension;
+
+       /* listener legion */
+       private final MyPaintListener fPaintListener;
+
+       private final MyMouseTrackListener fMouseTrackListener;
+
+       private final MyMouseListener fMouseListener;
+
+       private final MyMenuDetectListener fMenuDetectListener;
+
+       private final DisposeListener fDisposeListener;
+
+       private final IViewportListener fViewportListener;
+
+       private LinearLayouter fLayouter;
+
+       /**
+        * Creates a new control.
+        * 
+        * @param parent
+        * @param shellStyle
+        * @param access
+        */
+       public AnnotationExpansionControl(Shell parent, int shellStyle,
+                       IAnnotationAccess access) {
+               fPaintListener = new MyPaintListener();
+               fMouseTrackListener = new MyMouseTrackListener();
+               fMouseListener = new MyMouseListener();
+               fMenuDetectListener = new MyMenuDetectListener();
+               fDisposeListener = new MyDisposeListener();
+               fViewportListener = new IViewportListener() {
+
+                       public void viewportChanged(int verticalOffset) {
+                               dispose();
+                       }
+
+               };
+               fLayouter = new LinearLayouter();
+
+               if (access instanceof IAnnotationAccessExtension)
+                       fAnnotationAccessExtension = (IAnnotationAccessExtension) access;
+
+               fShell = new Shell(parent, shellStyle | SWT.NO_FOCUS | SWT.ON_TOP);
+               Display display = fShell.getDisplay();
+               fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+               fComposite = new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE
+                               | SWT.NO_TRIM);
+               // fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE
+               // | SWT.NO_TRIM | SWT.V_SCROLL);
+
+               GridLayout layout = new GridLayout(1, true);
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               fShell.setLayout(layout);
+
+               GridData data = new GridData(GridData.FILL_BOTH);
+               data.heightHint = fLayouter.getAnnotationSize() + 2
+                               * fLayouter.getBorderWidth() + 4;
+               fComposite.setLayoutData(data);
+               fComposite.addMouseTrackListener(new MouseTrackAdapter() {
+
+                       public void mouseExit(MouseEvent e) {
+                               if (fComposite == null)
+                                       return;
+                               Control[] children = fComposite.getChildren();
+                               Rectangle bounds = null;
+                               for (int i = 0; i < children.length; i++) {
+                                       if (bounds == null)
+                                               bounds = children[i].getBounds();
+                                       else
+                                               bounds.add(children[i].getBounds());
+                                       if (bounds.contains(e.x, e.y))
+                                               return;
+                               }
+
+                               // if none of the children contains the event, we leave the
+                               // popup
+                               dispose();
+                       }
+
+               });
+
+               // fComposite.getVerticalBar().addListener(SWT.Selection, new Listener()
+               // {
+               //
+               // public void handleEvent(Event event) {
+               // Rectangle bounds= fShell.getBounds();
+               // int x= bounds.x - fLayouter.getAnnotationSize() -
+               // fLayouter.getBorderWidth();
+               // int y= bounds.y;
+               // fShell.setBounds(x, y, bounds.width, bounds.height);
+               // }
+               //
+               // });
+
+               fHandCursor = new Cursor(display, SWT.CURSOR_HAND);
+               fShell.setCursor(fHandCursor);
+               fComposite.setCursor(fHandCursor);
+
+               setInfoSystemColor();
+       }
+
+       private void setInfoSystemColor() {
+               Display display = fShell.getDisplay();
+               setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+               setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
+        */
+       public void setInformation(String information) {
+               setInput(null);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
+        */
+       public void setInput(Object input) {
+               if (fInput != null && fInput.fViewer != null)
+                       fInput.fViewer.removeViewportListener(fViewportListener);
+
+               if (input instanceof AnnotationHoverInput)
+                       fInput = (AnnotationHoverInput) input;
+               else
+                       fInput = null;
+
+               inputChanged(fInput, null);
+       }
+
+       protected void inputChanged(Object newInput, Object newSelection) {
+               refresh();
+       }
+
+       protected void refresh() {
+               adjustItemNumber();
+
+               if (fInput == null)
+                       return;
+
+               if (fInput.fAnnotations == null)
+                       return;
+
+               if (fInput.fViewer != null)
+                       fInput.fViewer.addViewportListener(fViewportListener);
+
+               fShell.setRegion(fLayouter.getShellRegion(fInput.fAnnotations.length));
+
+               Layout layout = fLayouter.getLayout(fInput.fAnnotations.length);
+               fComposite.setLayout(layout);
+
+               Control[] children = fComposite.getChildren();
+               for (int i = 0; i < fInput.fAnnotations.length; i++) {
+                       Canvas canvas = (Canvas) children[i];
+                       Item item = new Item();
+                       item.canvas = canvas;
+                       item.fAnnotation = fInput.fAnnotations[i];
+                       canvas.setData(item);
+                       canvas.redraw();
+               }
+
+       }
+
+       protected void adjustItemNumber() {
+               if (fComposite == null)
+                       return;
+
+               Control[] children = fComposite.getChildren();
+               int oldSize = children.length;
+               int newSize = fInput == null ? 0 : fInput.fAnnotations.length;
+
+               Display display = fShell.getDisplay();
+
+               // add missing items
+               for (int i = oldSize; i < newSize; i++) {
+                       Canvas canvas = new Canvas(fComposite, SWT.NONE);
+                       Object gridData = fLayouter.getLayoutData();
+                       canvas.setLayoutData(gridData);
+                       canvas.setBackground(display
+                                       .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+
+                       canvas.addPaintListener(fPaintListener);
+
+                       canvas.addMouseTrackListener(fMouseTrackListener);
+
+                       canvas.addMouseListener(fMouseListener);
+
+                       canvas.addListener(SWT.MenuDetect, fMenuDetectListener);
+
+                       canvas.addDisposeListener(fDisposeListener);
+               }
+
+               // dispose of exceeding resources
+               for (int i = oldSize; i > newSize; i--) {
+                       Item item = (Item) children[i - 1].getData();
+                       item.deselect();
+                       children[i - 1].dispose();
+               }
+
+       }
+
+       /*
+        * @see IInformationControl#setVisible(boolean)
+        */
+       public void setVisible(boolean visible) {
+               fShell.setVisible(visible);
+       }
+
+       /*
+        * @see IInformationControl#dispose()
+        */
+       public void dispose() {
+               if (fShell != null) {
+                       if (!fShell.isDisposed())
+                               fShell.dispose();
+                       fShell = null;
+                       fComposite = null;
+                       if (fHandCursor != null)
+                               fHandCursor.dispose();
+                       fHandCursor = null;
+                       if (fHoverManager != null)
+                               fHoverManager.dispose();
+                       fHoverManager = null;
+                       fSelection = null;
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
+        */
+       public boolean hasContents() {
+               return fInput.fAnnotations != null && fInput.fAnnotations.length > 0;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int,
+        *      int)
+        */
+       public void setSizeConstraints(int maxWidth, int maxHeight) {
+               // fMaxWidth= maxWidth;
+               // fMaxHeight= maxHeight;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
+        */
+       public Point computeSizeHint() {
+               return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+       }
+
+       /*
+        * @see IInformationControl#setLocation(Point)
+        */
+       public void setLocation(Point location) {
+               fShell.setLocation(location);
+       }
+
+       /*
+        * @see IInformationControl#setSize(int, int)
+        */
+       public void setSize(int width, int height) {
+               fShell.setSize(width, height);
+       }
+
+       /*
+        * @see IInformationControl#addDisposeListener(DisposeListener)
+        */
+       public void addDisposeListener(DisposeListener listener) {
+               fShell.addDisposeListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#removeDisposeListener(DisposeListener)
+        */
+       public void removeDisposeListener(DisposeListener listener) {
+               fShell.removeDisposeListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#setForegroundColor(Color)
+        */
+       public void setForegroundColor(Color foreground) {
+               fComposite.setForeground(foreground);
+       }
+
+       /*
+        * @see IInformationControl#setBackgroundColor(Color)
+        */
+       public void setBackgroundColor(Color background) {
+               fComposite.setBackground(background);
+       }
+
+       /*
+        * @see IInformationControl#isFocusControl()
+        */
+       public boolean isFocusControl() {
+               if (fComposite.isFocusControl())
+                       return true;
+
+               Control[] children = fComposite.getChildren();
+               for (int i = 0; i < children.length; i++) {
+                       if (children[i].isFocusControl())
+                               return true;
+               }
+               return false;
+       }
+
+       /*
+        * @see IInformationControl#setFocus()
+        */
+       public void setFocus() {
+               fShell.forceFocus();
+       }
+
+       /*
+        * @see IInformationControl#addFocusListener(FocusListener)
+        */
+       public void addFocusListener(FocusListener listener) {
+               fShell.addFocusListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#removeFocusListener(FocusListener)
+        */
+       public void removeFocusListener(FocusListener listener) {
+               fShell.removeFocusListener(listener);
+       }
+
+       private StyleRange[] setViewerBackground(Annotation annotation) {
+               StyledText text = fInput.fViewer.getTextWidget();
+               if (text == null || text.isDisposed())
+                       return null;
+
+               Display disp = text.getDisplay();
+
+               Position pos = fInput.model.getPosition(annotation);
+               if (pos == null)
+                       return null;
+
+               IRegion region = ((TextViewer) fInput.fViewer)
+                               .modelRange2WidgetRange(new Region(pos.offset, pos.length));
+               if (region == null)
+                       return null;
+
+               StyleRange[] ranges = text.getStyleRanges(region.getOffset(), region
+                               .getLength());
+
+               List undoRanges = new ArrayList(ranges.length);
+               for (int i = 0; i < ranges.length; i++) {
+                       undoRanges.add(ranges[i].clone());
+               }
+
+               int offset = region.getOffset();
+               StyleRange current = undoRanges.size() > 0 ? (StyleRange) undoRanges
+                               .get(0) : null;
+               int curStart = current != null ? current.start : region.getOffset()
+                               + region.getLength();
+               int curEnd = current != null ? current.start + current.length : -1;
+               int index = 0;
+
+               // fill no-style regions
+               while (curEnd < region.getOffset() + region.getLength()) {
+                       // add empty range
+                       if (curStart > offset) {
+                               StyleRange undoRange = new StyleRange(offset,
+                                               curStart - offset, null, null);
+                               undoRanges.add(index, undoRange);
+                               index++;
+                       }
+
+                       // step
+                       index++;
+                       if (index < undoRanges.size()) {
+                               offset = curEnd;
+                               current = (StyleRange) undoRanges.get(index);
+                               curStart = current.start;
+                               curEnd = current.start + current.length;
+                       } else if (index == undoRanges.size()) {
+                               // last one
+                               offset = curEnd;
+                               current = null;
+                               curStart = region.getOffset() + region.getLength();
+                               curEnd = -1;
+                       } else
+                               curEnd = region.getOffset() + region.getLength();
+               }
+
+               // create modified styles (with background)
+               List shadedRanges = new ArrayList(undoRanges.size());
+               for (Iterator it = undoRanges.iterator(); it.hasNext();) {
+                       StyleRange range = (StyleRange) ((StyleRange) it.next()).clone();
+                       shadedRanges.add(range);
+                       range.background = getHighlightColor(disp);
+               }
+
+               // set the ranges one by one
+               for (Iterator iter = shadedRanges.iterator(); iter.hasNext();) {
+                       text.setStyleRange((StyleRange) iter.next());
+
+               }
+
+               return (StyleRange[]) undoRanges.toArray(undoRanges
+                               .toArray(new StyleRange[0]));
+       }
+
+       private void resetViewerBackground(StyleRange[] oldRanges) {
+
+               if (oldRanges == null)
+                       return;
+
+               if (fInput == null)
+                       return;
+
+               StyledText text = fInput.fViewer.getTextWidget();
+               if (text == null || text.isDisposed())
+                       return;
+
+               // set the ranges one by one
+               for (int i = 0; i < oldRanges.length; i++) {
+                       text.setStyleRange(oldRanges[i]);
+               }
+       }
+
+       private Color getHighlightColor(Display disp) {
+               return disp.getSystemColor(SWT.COLOR_GRAY);
+       }
+
+       private Color getSelectionColor(Display disp) {
+               return disp.getSystemColor(SWT.COLOR_GRAY);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationHover.java
new file mode 100644 (file)
index 0000000..d18653e
--- /dev/null
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.internal.ui.text.HTMLPrinter;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.JavaAnnotationIterator;
+import net.sourceforge.phpeclipse.phpeditor.PHPTextHover;
+import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+
+public class AnnotationHover extends AbstractJavaEditorTextHover {
+
+       // private IPreferenceStore fStore =
+       // PHPeclipsePlugin.getDefault().getPreferenceStore();
+       private IPreferenceStore fStore = EditorsUI.getPreferenceStore();
+
+       private DefaultMarkerAnnotationAccess fAnnotationAccess = new DefaultMarkerAnnotationAccess();
+
+       private PHPTextHover fPHPTextHover = null;
+
+       /*
+        * Formats a message as HTML text.
+        */
+       private String formatMessage(String message) {
+               StringBuffer buffer = new StringBuffer();
+               HTMLPrinter.addPageProlog(buffer);
+               HTMLPrinter.addParagraph(buffer, message); // HTMLPrinter.convertToHTMLContent(message));
+               HTMLPrinter.addPageEpilog(buffer);
+               return buffer.toString();
+       }
+
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+
+               if (getEditor() == null)
+                       return null;
+
+               IDocumentProvider provider = WebUI.getDefault()
+                               .getCompilationUnitDocumentProvider();
+               IAnnotationModel model = provider.getAnnotationModel(getEditor()
+                               .getEditorInput());
+               String message = null;
+               if (model != null) {
+                       Iterator e = new JavaAnnotationIterator(model, true);
+                       int layer = -1;
+
+                       while (e.hasNext()) {
+                               Annotation a = (Annotation) e.next();
+
+                               AnnotationPreference preference = getAnnotationPreference(a);
+                               if (preference == null
+                                               || !(fStore.getBoolean(preference
+                                                               .getTextPreferenceKey()) || (preference
+                                                               .getHighlightPreferenceKey() != null && fStore
+                                                               .getBoolean(preference
+                                                                               .getHighlightPreferenceKey()))))
+                                       continue;
+
+                               Position p = model.getPosition(a);
+
+                               int l = fAnnotationAccess.getLayer(a);
+
+                               if (l > layer
+                                               && p != null
+                                               && p.overlapsWith(hoverRegion.getOffset(), hoverRegion
+                                                               .getLength())) {
+                                       String msg = a.getText();
+                                       if (msg != null && msg.trim().length() > 0) {
+                                               message = msg;
+                                               layer = l;
+                                       }
+                               }
+                       }
+                       if (layer > -1)
+                               return formatMessage(message);
+               }
+               // Added as long as the above doesn't work
+               if (fPHPTextHover != null) {
+                       message = fPHPTextHover.getHoverInfo(textViewer, hoverRegion);
+                       if (message != null) {
+                               return formatMessage(message);
+                       }
+               }
+               return null;
+       }
+
+       /*
+        * @see IJavaEditorTextHover#setEditor(IEditorPart)
+        */
+       public void setEditor(IEditorPart editor) {
+               if (editor instanceof PHPUnitEditor) {
+                       super.setEditor(editor);
+                       if (editor != null) {
+                               IEditorInput editorInput = editor.getEditorInput();
+                               if (editorInput instanceof IFileEditorInput) {
+                                       try {
+                                               IFile f = ((IFileEditorInput) editorInput).getFile();
+                                               fPHPTextHover = new PHPTextHover(f.getProject());
+                                               return;
+                                       } catch (NullPointerException e) {
+                                               // this exception occurs, if getTextHover is called by
+                                               // preference pages !
+                                       }
+                               }
+                       }
+                       fPHPTextHover = new PHPTextHover(null);
+               } else {
+                       super.setEditor(null);
+               }
+       }
+
+       /**
+        * Returns the annotation preference for the given annotation.
+        * 
+        * @param annotation
+        *            the annotation
+        * @return the annotation preference or <code>null</code> if none
+        */
+       private AnnotationPreference getAnnotationPreference(Annotation annotation) {
+
+               if (annotation.isMarkedDeleted())
+                       return null;
+               return EditorsUI.getAnnotationPreferenceLookup()
+                               .getAnnotationPreference(annotation);
+       }
+
+       static boolean isJavaProblemHover(String id) {
+               return PreferenceConstants.ID_PROBLEM_HOVER.equals(id);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/BestMatchHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/BestMatchHover.java
new file mode 100644 (file)
index 0000000..97b1b75
--- /dev/null
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextHoverExtension;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.information.IInformationProviderExtension2;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Caution: this implementation is a layer breaker and contains some "shortcuts"
+ */
+public class BestMatchHover extends AbstractJavaEditorTextHover implements
+               ITextHoverExtension, IInformationProviderExtension2 {
+
+       private List fTextHoverSpecifications;
+
+       private List fInstantiatedTextHovers;
+
+       private ITextHover fBestHover;
+
+       public BestMatchHover() {
+               installTextHovers();
+       }
+
+       public BestMatchHover(IEditorPart editor) {
+               this();
+               setEditor(editor);
+       }
+
+       /**
+        * Installs all text hovers.
+        */
+       private void installTextHovers() {
+
+               // initialize lists - indicates that the initialization happened
+               fTextHoverSpecifications = new ArrayList(2);
+               fInstantiatedTextHovers = new ArrayList(2);
+
+               // populate list
+               JavaEditorTextHoverDescriptor[] hoverDescs = WebUI
+                               .getDefault().getJavaEditorTextHoverDescriptors();
+               for (int i = 0; i < hoverDescs.length; i++) {
+                       // ensure that we don't add ourselves to the list
+                       if (!PreferenceConstants.ID_BESTMATCH_HOVER.equals(hoverDescs[i]
+                                       .getId()))
+                               fTextHoverSpecifications.add(hoverDescs[i]);
+               }
+       }
+
+       private void checkTextHovers() {
+               if (fTextHoverSpecifications.size() == 0)
+                       return;
+
+               for (Iterator iterator = new ArrayList(fTextHoverSpecifications)
+                               .iterator(); iterator.hasNext();) {
+                       JavaEditorTextHoverDescriptor spec = (JavaEditorTextHoverDescriptor) iterator
+                                       .next();
+
+                       IJavaEditorTextHover hover = spec.createTextHover();
+                       if (hover != null) {
+                               hover.setEditor(getEditor());
+                               addTextHover(hover);
+                               fTextHoverSpecifications.remove(spec);
+                       }
+               }
+       }
+
+       protected void addTextHover(ITextHover hover) {
+               if (!fInstantiatedTextHovers.contains(hover))
+                       fInstantiatedTextHovers.add(hover);
+       }
+
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+
+               checkTextHovers();
+               fBestHover = null;
+
+               if (fInstantiatedTextHovers == null)
+                       return null;
+
+               for (Iterator iterator = fInstantiatedTextHovers.iterator(); iterator
+                               .hasNext();) {
+                       ITextHover hover = (ITextHover) iterator.next();
+
+                       String s = hover.getHoverInfo(textViewer, hoverRegion);
+                       if (s != null && s.trim().length() > 0) {
+                               fBestHover = hover;
+                               return s;
+                       }
+               }
+
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
+        * @since 3.0
+        */
+       public IInformationControlCreator getHoverControlCreator() {
+               if (fBestHover instanceof ITextHoverExtension)
+                       return ((ITextHoverExtension) fBestHover).getHoverControlCreator();
+
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
+        * @since 3.0
+        */
+       public IInformationControlCreator getInformationPresenterControlCreator() {
+               if (fBestHover instanceof IInformationProviderExtension2)
+                       return ((IInformationProviderExtension2) fBestHover)
+                                       .getInformationPresenterControlCreator();
+
+               return null;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverDescriptor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverDescriptor.java
new file mode 100644 (file)
index 0000000..3d65241
--- /dev/null
@@ -0,0 +1,366 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.EditorUtility;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.swt.SWT;
+import org.osgi.framework.Bundle;
+
+/**
+ * Describes a Java editor text hover.
+ * 
+ * @since 2.1
+ */
+public class JavaEditorTextHoverDescriptor implements Comparable {
+
+       private static final String JAVA_EDITOR_TEXT_HOVER_EXTENSION_POINT = "net.sourceforge.phpeclipse.phpEditorTextHovers"; //$NON-NLS-1$
+
+       private static final String HOVER_TAG = "hover"; //$NON-NLS-1$
+
+       private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
+
+       private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
+
+       private static final String LABEL_ATTRIBUTE = "label"; //$NON-NLS-1$
+
+       private static final String ACTIVATE_PLUG_IN_ATTRIBUTE = "activate"; //$NON-NLS-1$
+
+       private static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$
+
+       public static final String NO_MODIFIER = "0"; //$NON-NLS-1$
+
+       public static final String DISABLED_TAG = "!"; //$NON-NLS-1$
+
+       public static final String VALUE_SEPARATOR = ";"; //$NON-NLS-1$
+
+       private int fStateMask;
+
+       private String fModifierString;
+
+       private boolean fIsEnabled;
+
+       private IConfigurationElement fElement;
+
+       /**
+        * Returns all Java editor text hovers contributed to the workbench.
+        */
+       public static JavaEditorTextHoverDescriptor[] getContributedHovers() {
+               IExtensionRegistry registry = Platform.getExtensionRegistry();
+               IConfigurationElement[] elements = registry
+                               .getConfigurationElementsFor(JAVA_EDITOR_TEXT_HOVER_EXTENSION_POINT);
+               JavaEditorTextHoverDescriptor[] hoverDescs = createDescriptors(elements);
+               initializeFromPreferences(hoverDescs);
+               return hoverDescs;
+       }
+
+       /**
+        * Computes the state mask for the given modifier string.
+        * 
+        * @param modifiers
+        *            the string with the modifiers, separated by '+', '-', ';', ','
+        *            or '.'
+        * @return the state mask or -1 if the input is invalid
+        */
+       public static int computeStateMask(String modifiers) {
+               if (modifiers == null)
+                       return -1;
+
+               if (modifiers.length() == 0)
+                       return SWT.NONE;
+
+               int stateMask = 0;
+               StringTokenizer modifierTokenizer = new StringTokenizer(modifiers,
+                               ",;.:+-* "); //$NON-NLS-1$
+               while (modifierTokenizer.hasMoreTokens()) {
+                       int modifier = EditorUtility
+                                       .findLocalizedModifier(modifierTokenizer.nextToken());
+                       if (modifier == 0 || (stateMask & modifier) == modifier)
+                               return -1;
+                       stateMask = stateMask | modifier;
+               }
+               return stateMask;
+       }
+
+       /**
+        * Creates a new Java Editor text hover descriptor from the given
+        * configuration element.
+        */
+       private JavaEditorTextHoverDescriptor(IConfigurationElement element) {
+               Assert.isNotNull(element);
+               fElement = element;
+       }
+
+       /**
+        * Creates the Java editor text hover.
+        */
+       public IJavaEditorTextHover createTextHover() {
+               String pluginId = fElement.getDeclaringExtension().getNamespace();
+               boolean isHoversPlugInActivated = Platform.getBundle(pluginId)
+                               .getState() == Bundle.ACTIVE;
+               if (isHoversPlugInActivated || canActivatePlugIn()) {
+                       try {
+                               return (IJavaEditorTextHover) fElement
+                                               .createExecutableExtension(CLASS_ATTRIBUTE);
+                       } catch (CoreException x) {
+                               WebUI.log(new Status(IStatus.ERROR, WebUI
+                                               .getPluginId(), 0, JavaHoverMessages
+                                               .getString("JavaTextHover.createTextHover"), null)); //$NON-NLS-1$
+                       }
+               }
+
+               return null;
+       }
+
+       // ---- XML Attribute accessors
+       // ---------------------------------------------
+
+       /**
+        * Returns the hover's id.
+        */
+       public String getId() {
+               return fElement.getAttribute(ID_ATTRIBUTE);
+       }
+
+       /**
+        * Returns the hover's class name.
+        */
+       public String getHoverClassName() {
+               return fElement.getAttribute(CLASS_ATTRIBUTE);
+       }
+
+       /**
+        * Returns the hover's label.
+        */
+       public String getLabel() {
+               String label = fElement.getAttribute(LABEL_ATTRIBUTE);
+               if (label != null)
+                       return label;
+
+               // Return simple class name
+               label = getHoverClassName();
+               int lastDot = label.lastIndexOf('.');
+               if (lastDot >= 0 && lastDot < label.length() - 1)
+                       return label.substring(lastDot + 1);
+               else
+                       return label;
+       }
+
+       /**
+        * Returns the hover's description.
+        * 
+        * @return the hover's description or <code>null</code> if not provided
+        */
+       public String getDescription() {
+               return fElement.getAttribute(DESCRIPTION_ATTRIBUTE);
+       }
+
+       public boolean canActivatePlugIn() {
+               return Boolean.valueOf(
+                               fElement.getAttribute(ACTIVATE_PLUG_IN_ATTRIBUTE))
+                               .booleanValue();
+       }
+
+       public boolean equals(Object obj) {
+               if (obj == null || !obj.getClass().equals(this.getClass())
+                               || getId() == null)
+                       return false;
+               return getId().equals(((JavaEditorTextHoverDescriptor) obj).getId());
+       }
+
+       public int hashCode() {
+               return getId().hashCode();
+       }
+
+       /*
+        * Implements a method from IComparable
+        */
+       public int compareTo(Object o) {
+               return Collator.getInstance().compare(getLabel(),
+                               ((JavaEditorTextHoverDescriptor) o).getLabel());
+       }
+
+       // /**
+       // * @param descriptor a JavaEditorTextHoverDescriptor
+       // * @return <code>true</code> if this contributed hover depends on the
+       // other one
+       // */
+       // public boolean dependsOn(JavaEditorTextHoverDescriptor descriptor) {
+       // if (descriptor == null)
+       // return false;
+       //              
+       // IPluginDescriptor thisPluginDescriptor=
+       // fElement.getDeclaringExtension().getDeclaringPluginDescriptor();
+       // IPluginDescriptor otherPluginDescriptor=
+       // descriptor.fElement.getDeclaringExtension().getDeclaringPluginDescriptor();
+       // return dependsOn(thisPluginDescriptor, otherPluginDescriptor);
+       // }
+
+       // private boolean dependsOn(IPluginDescriptor descriptor0,
+       // IPluginDescriptor descriptor1) {
+       //
+       // IPluginRegistry registry= Platform.getPluginRegistry();
+       // IPluginPrerequisite[] prerequisites=
+       // descriptor0.getPluginPrerequisites();
+       //
+       // for (int i= 0; i < prerequisites.length; i++) {
+       // IPluginPrerequisite prerequisite= prerequisites[i];
+       // String id= prerequisite.getUniqueIdentifier();
+       // IPluginDescriptor descriptor= registry.getPluginDescriptor(id);
+       //                      
+       // if (descriptor != null && (descriptor.equals(descriptor1) ||
+       // dependsOn(descriptor, descriptor1)))
+       // return true;
+       // }
+       //              
+       // return false;
+       // }
+
+       private static JavaEditorTextHoverDescriptor[] createDescriptors(
+                       IConfigurationElement[] elements) {
+               List result = new ArrayList(elements.length);
+               for (int i = 0; i < elements.length; i++) {
+                       IConfigurationElement element = elements[i];
+                       if (HOVER_TAG.equals(element.getName())) {
+                               JavaEditorTextHoverDescriptor desc = new JavaEditorTextHoverDescriptor(
+                                               element);
+                               result.add(desc);
+                       }
+               }
+               Collections.sort(result);
+               return (JavaEditorTextHoverDescriptor[]) result
+                               .toArray(new JavaEditorTextHoverDescriptor[result.size()]);
+       }
+
+       private static void initializeFromPreferences(
+                       JavaEditorTextHoverDescriptor[] hovers) {
+               String compiledTextHoverModifiers = WebUI.getDefault()
+                               .getPreferenceStore().getString(
+                                               PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
+
+               StringTokenizer tokenizer = new StringTokenizer(
+                               compiledTextHoverModifiers, VALUE_SEPARATOR);
+               HashMap idToModifier = new HashMap(tokenizer.countTokens() / 2);
+
+               while (tokenizer.hasMoreTokens()) {
+                       String id = tokenizer.nextToken();
+                       if (tokenizer.hasMoreTokens())
+                               idToModifier.put(id, tokenizer.nextToken());
+               }
+
+               String compiledTextHoverModifierMasks = WebUI.getDefault()
+                               .getPreferenceStore().getString(
+                                               PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
+
+               tokenizer = new StringTokenizer(compiledTextHoverModifierMasks,
+                               VALUE_SEPARATOR);
+               HashMap idToModifierMask = new HashMap(tokenizer.countTokens() / 2);
+
+               while (tokenizer.hasMoreTokens()) {
+                       String id = tokenizer.nextToken();
+                       if (tokenizer.hasMoreTokens())
+                               idToModifierMask.put(id, tokenizer.nextToken());
+               }
+
+               for (int i = 0; i < hovers.length; i++) {
+                       String modifierString = (String) idToModifier
+                                       .get(hovers[i].getId());
+                       boolean enabled = true;
+                       if (modifierString == null)
+                               modifierString = DISABLED_TAG;
+
+                       if (modifierString.startsWith(DISABLED_TAG)) {
+                               enabled = false;
+                               modifierString = modifierString.substring(1);
+                       }
+
+                       if (modifierString.equals(NO_MODIFIER))
+                               modifierString = ""; //$NON-NLS-1$
+
+                       hovers[i].fModifierString = modifierString;
+                       hovers[i].fIsEnabled = enabled;
+                       hovers[i].fStateMask = computeStateMask(modifierString);
+                       if (hovers[i].fStateMask == -1) {
+                               // Fallback: use stored modifier masks
+                               try {
+                                       hovers[i].fStateMask = Integer
+                                                       .parseInt((String) idToModifierMask.get(hovers[i]
+                                                                       .getId()));
+                               } catch (NumberFormatException ex) {
+                                       hovers[i].fStateMask = -1;
+                               }
+                               // Fix modifier string
+                               int stateMask = hovers[i].fStateMask;
+                               if (stateMask == -1)
+                                       hovers[i].fModifierString = ""; //$NON-NLS-1$
+                               else
+                                       hovers[i].fModifierString = EditorUtility
+                                                       .getModifierString(stateMask);
+                       }
+               }
+       }
+
+       /**
+        * Returns the configured modifier getStateMask for this hover.
+        * 
+        * @return the hover modifier stateMask or -1 if no hover is configured
+        */
+       public int getStateMask() {
+               return fStateMask;
+       }
+
+       /**
+        * Returns the modifier String as set in the preference store.
+        * 
+        * @return the modifier string
+        */
+       public String getModifierString() {
+               return fModifierString;
+       }
+
+       /**
+        * Returns whether this hover is enabled or not.
+        * 
+        * @return <code>true</code> if enabled
+        */
+       public boolean isEnabled() {
+               return fIsEnabled;
+       }
+
+       /**
+        * Returns this hover descriptors configuration element.
+        * 
+        * @return the configuration element
+        * @since 3.0
+        */
+       public IConfigurationElement getConfigurationElement() {
+               return fElement;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverProxy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaEditorTextHoverProxy.java
new file mode 100644 (file)
index 0000000..7304174
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Proxy for JavaEditorTextHovers.
+ * 
+ * @since 2.1
+ */
+public class JavaEditorTextHoverProxy extends AbstractJavaEditorTextHover {
+
+       private JavaEditorTextHoverDescriptor fHoverDescriptor;
+
+       private IJavaEditorTextHover fHover;
+
+       public JavaEditorTextHoverProxy(JavaEditorTextHoverDescriptor descriptor,
+                       IEditorPart editor) {
+               fHoverDescriptor = descriptor;
+               setEditor(editor);
+       }
+
+       /*
+        * @see IJavaEditorTextHover#setEditor(IEditorPart)
+        */
+       public void setEditor(IEditorPart editor) {
+               super.setEditor(editor);
+
+               if (fHover != null)
+                       fHover.setEditor(getEditor());
+       }
+
+       public boolean isEnabled() {
+               return true;
+       }
+
+       /*
+        * @see ITextHover#getHoverRegion(ITextViewer, int)
+        */
+       public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+               if (!isEnabled() || fHoverDescriptor == null)
+                       return null;
+
+               if (isCreated() || createHover())
+                       return fHover.getHoverRegion(textViewer, offset);
+               else
+                       return null;
+       }
+
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+               if (!isEnabled() || fHoverDescriptor == null)
+                       return null;
+
+               if (isCreated() || createHover())
+                       return fHover.getHoverInfo(textViewer, hoverRegion);
+               else
+                       return null;
+       }
+
+       private boolean isCreated() {
+               return fHover != null;
+       }
+
+       private boolean createHover() {
+               fHover = fHoverDescriptor.createTextHover();
+               if (fHover != null)
+                       fHover.setEditor(getEditor());
+               return isCreated();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java
new file mode 100644 (file)
index 0000000..cd37c94
--- /dev/null
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.AnnotationExpansionControl.AnnotationHoverInput;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.IJavaAnnotation;
+import net.sourceforge.phpeclipse.phpeditor.JavaMarkerAnnotation;
+import net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider.ProblemAnnotation;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControlExtension2;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.CompositeRuler;
+import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IAnnotationAccessExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationPresentation;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.ImageUtilities;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.AnnotationPreferenceLookup;
+
+/**
+ * 
+ * 
+ * @since 3.0
+ */
+public class JavaExpandHover extends AnnotationExpandHover {
+
+       /** Id of the no breakpoint fake annotation */
+       public static final String NO_BREAKPOINT_ANNOTATION = "net.sourceforge.phpdt.internal.ui.NoBreakpointAnnotation"; //$NON-NLS-1$
+
+       private static class NoBreakpointAnnotation extends Annotation implements
+                       IAnnotationPresentation {
+
+               public NoBreakpointAnnotation() {
+                       super(NO_BREAKPOINT_ANNOTATION, false, JavaHoverMessages
+                                       .getString("NoBreakpointAnnotation.addBreakpoint"));
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC,
+                *      org.eclipse.swt.widgets.Canvas,
+                *      org.eclipse.swt.graphics.Rectangle)
+                */
+               public void paint(GC gc, Canvas canvas, Rectangle bounds) {
+                       // draw affordance so the user know she can click here to get a
+                       // breakpoint
+                       Image fImage = PHPUiImages.get(PHPUiImages.IMG_FIELD_PUBLIC);
+                       ImageUtilities.drawImage(fImage, gc, canvas, bounds, SWT.CENTER);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer()
+                */
+               public int getLayer() {
+                       return IAnnotationPresentation.DEFAULT_LAYER;
+               }
+       }
+
+       private AnnotationPreferenceLookup fLookup = new AnnotationPreferenceLookup();
+
+       private IPreferenceStore fStore = WebUI.getDefault()
+                       .getCombinedPreferenceStore();
+
+       public JavaExpandHover(CompositeRuler ruler, IAnnotationAccess access,
+                       IDoubleClickListener doubleClickListener) {
+               super(ruler, access, doubleClickListener);
+       }
+
+       /*
+        * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getHoverInfoForLine(org.eclipse.jface.text.source.ISourceViewer,
+        *      int)
+        */
+       protected Object getHoverInfoForLine(final ISourceViewer viewer,
+                       final int line) {
+               final boolean showTemporaryProblems = PreferenceConstants
+                               .getPreferenceStore().getBoolean(
+                                               PreferenceConstants.EDITOR_CORRECTION_INDICATION);
+               IAnnotationModel model = viewer.getAnnotationModel();
+               IDocument document = viewer.getDocument();
+
+               if (model == null)
+                       return null;
+
+               List exact = new ArrayList();
+               HashMap messagesAtPosition = new HashMap();
+
+               Iterator e = model.getAnnotationIterator();
+               while (e.hasNext()) {
+                       Annotation annotation = (Annotation) e.next();
+
+                       if (fAnnotationAccess instanceof IAnnotationAccessExtension)
+                               if (!((IAnnotationAccessExtension) fAnnotationAccess)
+                                               .isPaintable(annotation))
+                                       continue;
+
+                       if (annotation instanceof IJavaAnnotation
+                                       && !isIncluded((IJavaAnnotation) annotation,
+                                                       showTemporaryProblems))
+                               continue;
+
+                       AnnotationPreference pref = fLookup
+                                       .getAnnotationPreference(annotation);
+                       if (pref != null) {
+                               String key = pref.getVerticalRulerPreferenceKey();
+                               if (key != null && !fStore.getBoolean(key))
+                                       continue;
+                       }
+
+                       Position position = model.getPosition(annotation);
+                       if (position == null)
+                               continue;
+
+                       if (compareRulerLine(position, document, line) == 1) {
+
+                               if (isDuplicateMessage(messagesAtPosition, position, annotation
+                                               .getText()))
+                                       continue;
+
+                               exact.add(annotation);
+                       }
+               }
+
+               sort(exact, model);
+
+               if (exact.size() > 0)
+                       setLastRulerMouseLocation(viewer, line);
+
+               if (exact.size() > 0) {
+                       Annotation first = (Annotation) exact.get(0);
+                       if (!isBreakpointAnnotation(first))
+                               exact.add(0, new NoBreakpointAnnotation());
+               }
+
+               if (exact.size() <= 1)
+                       return null;
+
+               AnnotationHoverInput input = new AnnotationHoverInput();
+               input.fAnnotations = (Annotation[]) exact.toArray(new Annotation[0]);
+               input.fViewer = viewer;
+               input.fRulerInfo = fCompositeRuler;
+               input.fAnnotationListener = fgListener;
+               input.fDoubleClickListener = fDblClickListener;
+               input.redoAction = new AnnotationExpansionControl.ICallback() {
+
+                       public void run(IInformationControlExtension2 control) {
+                               control.setInput(getHoverInfoForLine(viewer, line));
+                       }
+
+               };
+               input.model = model;
+
+               return input;
+       }
+
+       private boolean isIncluded(IJavaAnnotation annotation,
+                       boolean showTemporaryProblems) {
+
+               // XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=138601
+               if (annotation instanceof ProblemAnnotation
+                               && JavaMarkerAnnotation.TASK_ANNOTATION_TYPE.equals(annotation
+                                               .getType()))
+                       return false;
+
+               if (!annotation.isProblem())
+                       return true;
+
+               if (annotation.isMarkedDeleted() && !annotation.hasOverlay())
+                       return true;
+
+               if (annotation.hasOverlay() && !annotation.isMarkedDeleted())
+                       return true;
+
+               if (annotation.hasOverlay())
+                       return (!isIncluded(annotation.getOverlay(), showTemporaryProblems));
+
+               return showTemporaryProblems; // &&
+                                                                               // JavaCorrectionProcessor.hasCorrections((Annotation)annotation);
+       }
+
+       /*
+        * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getOrder(org.eclipse.jface.text.source.Annotation)
+        */
+       protected int getOrder(Annotation annotation) {
+               if (isBreakpointAnnotation(annotation))
+                       return 1000;
+               else
+                       return super.getOrder(annotation);
+       }
+
+       private boolean isBreakpointAnnotation(Annotation a) {
+               if (a instanceof JavaMarkerAnnotation) {
+                       JavaMarkerAnnotation jma = (JavaMarkerAnnotation) a;
+                       // HACK to get breakpoints to show up first
+                       return jma.getType().equals("org.eclipse.debug.core.breakpoint"); //$NON-NLS-1$
+               }
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.java
new file mode 100644 (file)
index 0000000..3582118
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+class JavaHoverMessages {
+
+       private static final String RESOURCE_BUNDLE = "net.sourceforge.phpdt.internal.ui.text.java.hover.JavaHoverMessages";//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private JavaHoverMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        * @since 3.0
+        */
+       public static String getFormattedString(String key, Object arg) {
+               String format = null;
+               try {
+                       format = fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+               if (arg == null)
+                       arg = ""; //$NON-NLS-1$
+               return MessageFormat.format(format, new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the arguments
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        * @since 3.0
+        */
+       public static String getFormattedString(String key, Object arg1, Object arg2) {
+               String format = null;
+               try {
+                       format = fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+               if (arg1 == null)
+                       arg1 = ""; //$NON-NLS-1$
+               if (arg2 == null)
+                       arg2 = ""; //$NON-NLS-1$
+               return MessageFormat.format(format, new Object[] { arg1, arg2 });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        * @since 3.0
+        */
+       public static String getFormattedString(String key, boolean arg) {
+               String format = null;
+               try {
+                       format = fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+               return MessageFormat.format(format, new Object[] { new Boolean(arg) });
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties
new file mode 100644 (file)
index 0000000..ea58cad
--- /dev/null
@@ -0,0 +1,18 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+TypeHover.more_to_come=\ ...
+
+JavaTextHover.createTextHover= Could not create PHP text hover
+
+JavaTextHover.makeStickyHint= Press ''{0}'' for focus.
+
+NoBreakpointAnnotation.addBreakpoint= Add a breakpoint
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java
new file mode 100644 (file)
index 0000000..a8f3a8e
--- /dev/null
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder;
+import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.information.IInformationProvider;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+
+public class JavaInformationProvider implements IInformationProvider {
+
+       class EditorWatcher implements IPartListener {
+
+               /**
+                * @see IPartListener#partOpened(IWorkbenchPart)
+                */
+               public void partOpened(IWorkbenchPart part) {
+               }
+
+               /**
+                * @see IPartListener#partDeactivated(IWorkbenchPart)
+                */
+               public void partDeactivated(IWorkbenchPart part) {
+               }
+
+               /**
+                * @see IPartListener#partClosed(IWorkbenchPart)
+                */
+               public void partClosed(IWorkbenchPart part) {
+                       if (part == fEditor) {
+                               fEditor.getSite().getWorkbenchWindow().getPartService()
+                                               .removePartListener(fPartListener);
+                               fPartListener = null;
+                       }
+               }
+
+               /**
+                * @see IPartListener#partActivated(IWorkbenchPart)
+                */
+               public void partActivated(IWorkbenchPart part) {
+                       update();
+               }
+
+               public void partBroughtToTop(IWorkbenchPart part) {
+                       update();
+               }
+       }
+
+       protected IEditorPart fEditor;
+
+       protected IPartListener fPartListener;
+
+       protected String fCurrentPerspective;
+
+       protected IJavaEditorTextHover fImplementation;
+
+       public JavaInformationProvider(IEditorPart editor) {
+
+               fEditor = editor;
+
+               if (fEditor != null) {
+
+                       fPartListener = new EditorWatcher();
+                       IWorkbenchWindow window = fEditor.getSite().getWorkbenchWindow();
+                       window.getPartService().addPartListener(fPartListener);
+
+                       update();
+               }
+       }
+
+       protected void update() {
+
+               IWorkbenchWindow window = fEditor.getSite().getWorkbenchWindow();
+               IWorkbenchPage page = window.getActivePage();
+               if (page != null) {
+
+                       IPerspectiveDescriptor perspective = page.getPerspective();
+                       if (perspective != null) {
+                               String perspectiveId = perspective.getId();
+
+                               if (fCurrentPerspective == null
+                                               || fCurrentPerspective != perspectiveId) {
+                                       fCurrentPerspective = perspectiveId;
+
+                                       fImplementation = new JavaTypeHover();
+                                       fImplementation.setEditor(fEditor);
+                               }
+                       }
+               }
+       }
+
+       /*
+        * @see IInformationProvider#getSubject(ITextViewer, int)
+        */
+       public IRegion getSubject(ITextViewer textViewer, int offset) {
+
+               if (textViewer != null)
+                       return JavaWordFinder.findWord(textViewer.getDocument(), offset);
+
+               return null;
+       }
+
+       /*
+        * @see IInformationProvider#getInformation(ITextViewer, IRegion)
+        */
+       public String getInformation(ITextViewer textViewer, IRegion subject) {
+               if (fImplementation != null) {
+                       String s = fImplementation.getHoverInfo(textViewer, subject);
+                       if (s != null && s.trim().length() > 0)
+                               return s;
+               }
+
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaSourceHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaSourceHover.java
new file mode 100644 (file)
index 0000000..f8dd369
--- /dev/null
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.io.IOException;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.text.HTMLPrinter;
+import net.sourceforge.phpdt.internal.ui.text.PHPCodeReader;
+import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementLabels;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * Provides source as hover info for Java elements.
+ */
+public class JavaSourceHover extends AbstractJavaEditorTextHover {
+
+       private final int LABEL_FLAGS = JavaElementLabels.ALL_FULLY_QUALIFIED
+                       | JavaElementLabels.M_PRE_RETURNTYPE
+                       | JavaElementLabels.M_PARAMETER_TYPES
+                       | JavaElementLabels.M_PARAMETER_NAMES
+                       | JavaElementLabels.M_EXCEPTIONS
+                       | JavaElementLabels.F_PRE_TYPE_SIGNATURE;
+
+       /*
+        * @see JavaElementHover
+        */
+       protected String getHoverInfo(IJavaElement[] result) {
+               int nResults = result.length;
+               StringBuffer buffer = new StringBuffer();
+
+               if (nResults > 1) {
+
+                       for (int i = 0; i < result.length; i++) {
+                               HTMLPrinter.startBulletList(buffer);
+                               IJavaElement curr = result[i];
+                               if (curr instanceof IMember)
+                                       HTMLPrinter.addBullet(buffer, getInfoText((IMember) curr));
+                               HTMLPrinter.endBulletList(buffer);
+                       }
+
+               } else {
+
+                       IJavaElement curr = result[0];
+                       if (curr instanceof IMember && curr instanceof ISourceReference) {
+                               HTMLPrinter.addSmallHeader(buffer,
+                                               getInfoText(((IMember) curr)));
+                               try {
+                                       String source = ((ISourceReference) curr).getSource();
+                                       source = removeLeadingComments(source);
+                                       HTMLPrinter.addParagraph(buffer, "<pre>"); //$NON-NLS-1$
+                                       HTMLPrinter.addParagraph(buffer, source);
+                                       HTMLPrinter.addParagraph(buffer, "</pre>"); //$NON-NLS-1$
+                               } catch (JavaModelException ex) {
+                                       // only write small header
+                               }
+                       }
+               }
+
+               if (buffer.length() > 0) {
+                       HTMLPrinter.insertPageProlog(buffer, 0);
+                       HTMLPrinter.addPageEpilog(buffer);
+                       return buffer.toString();
+               }
+
+               return null;
+       }
+
+       private String getInfoText(IMember member) {
+               return JavaElementLabels.getElementLabel(member, LABEL_FLAGS);
+       }
+
+       private String removeLeadingComments(String source) {
+               PHPCodeReader reader = new PHPCodeReader();
+               IDocument document = new Document(source);
+               int i;
+               try {
+                       reader.configureForwardReader(document, 0, document.getLength(),
+                                       true, false);
+                       int c = reader.read();
+                       while (c != -1 && (c == '\r' || c == '\n')) {
+                               c = reader.read();
+                       }
+                       i = reader.getOffset();
+                       reader.close();
+               } catch (IOException ex) {
+                       i = 0;
+               } finally {
+                       try {
+                               if (reader != null)
+                                       reader.close();
+                       } catch (IOException ex) {
+                               WebUI.log(ex);
+                       }
+               }
+
+               if (i < 0)
+                       return source;
+               return source.substring(i);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaTypeHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaTypeHover.java
new file mode 100644 (file)
index 0000000..a2b08f1
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.IEditorPart;
+
+public class JavaTypeHover implements IJavaEditorTextHover {
+
+       private IJavaEditorTextHover fAnnotationHover;
+
+       // private IJavaEditorTextHover fJavadocHover;
+
+       public JavaTypeHover() {
+               fAnnotationHover = new AnnotationHover();
+               // fJavadocHover= new JavadocHover();
+       }
+
+       /**
+        * @see IJavaEditorTextHover#setEditor(IEditorPart)
+        */
+       public void setEditor(IEditorPart editor) {
+               fAnnotationHover.setEditor(editor);
+               // fJavadocHover.setEditor(editor);
+       }
+
+       /*
+        * @see ITextHover#getHoverRegion(ITextViewer, int)
+        */
+       public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+               // return fJavadocHover.getHoverRegion(textViewer, offset);
+               return null;
+       }
+
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+               String hoverInfo = fAnnotationHover.getHoverInfo(textViewer,
+                               hoverRegion);
+               if (hoverInfo != null)
+                       return hoverInfo;
+
+               // return fJavadocHover.getHoverInfo(textViewer, hoverRegion);
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/ProblemHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/ProblemHover.java
new file mode 100644 (file)
index 0000000..ea51f8e
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+/**
+ * This annotation hover shows the description of the selected java annotation.
+ * 
+ * XXX: Currently this problem hover only works for Java problems. see:
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=62081
+ * 
+ * @since 3.0
+ */
+public class ProblemHover extends AbstractAnnotationHover {
+
+       public ProblemHover() {
+               super(false);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/SourceViewerInformationControl.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/java/hover/SourceViewerInformationControl.java
new file mode 100644 (file)
index 0000000..d2760fc
--- /dev/null
@@ -0,0 +1,447 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlExtension;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+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.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+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.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Source viewer based implementation of <code>IInformationControl</code>.
+ * Displays information in a source viewer.
+ * 
+ * @since 3.0
+ */
+public class SourceViewerInformationControl implements IInformationControl,
+               IInformationControlExtension, DisposeListener {
+
+       /** Border thickness in pixels. */
+       private static final int BORDER = 1;
+
+       /** The control's shell */
+       private Shell fShell;
+
+       /** The control's text widget */
+       private StyledText fText;
+
+       /** The control's source viewer */
+       private SourceViewer fViewer;
+
+       /**
+        * The optional status field.
+        * 
+        * @since 3.0
+        */
+       private Label fStatusField;
+
+       /**
+        * The separator for the optional status field.
+        * 
+        * @since 3.0
+        */
+       private Label fSeparator;
+
+       /**
+        * The font of the optional status text label.
+        * 
+        * @since 3.0
+        */
+       private Font fStatusTextFont;
+
+       /**
+        * Creates a default information control with the given shell as parent. The
+        * given information presenter is used to process the information to be
+        * displayed. The given styles are applied to the created styled text
+        * widget.
+        * 
+        * @param parent
+        *            the parent shell
+        * @param shellStyle
+        *            the additional styles for the shell
+        * @param style
+        *            the additional styles for the styled text widget
+        */
+       public SourceViewerInformationControl(Shell parent, int shellStyle,
+                       int style) {
+               this(parent, shellStyle, style, null);
+       }
+
+       /**
+        * Creates a default information control with the given shell as parent. The
+        * given information presenter is used to process the information to be
+        * displayed. The given styles are applied to the created styled text
+        * widget.
+        * 
+        * @param parent
+        *            the parent shell
+        * @param shellStyle
+        *            the additional styles for the shell
+        * @param style
+        *            the additional styles for the styled text widget
+        * @param statusFieldText
+        *            the text to be used in the optional status field or
+        *            <code>null</code> if the status field should be hidden
+        * @since 3.0
+        */
+       public SourceViewerInformationControl(Shell parent, int shellStyle,
+                       int style, String statusFieldText) {
+               GridLayout layout;
+               GridData gd;
+
+               fShell = new Shell(parent, SWT.NO_FOCUS | SWT.ON_TOP | shellStyle);
+               Display display = fShell.getDisplay();
+               fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+
+               Composite composite = fShell;
+               layout = new GridLayout(1, false);
+               int border = ((shellStyle & SWT.NO_TRIM) == 0) ? 0 : BORDER;
+               layout.marginHeight = border;
+               layout.marginWidth = border;
+               composite.setLayout(layout);
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               composite.setLayoutData(gd);
+
+               if (statusFieldText != null) {
+                       composite = new Composite(composite, SWT.NONE);
+                       layout = new GridLayout(1, false);
+                       layout.marginHeight = 0;
+                       layout.marginWidth = 0;
+                       composite.setLayout(layout);
+                       gd = new GridData(GridData.FILL_BOTH);
+                       composite.setLayoutData(gd);
+                       composite.setForeground(display
+                                       .getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+                       composite.setBackground(display
+                                       .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+               }
+
+               // Source viewer
+               IPreferenceStore store = WebUI.getDefault()
+                               .getCombinedPreferenceStore();
+               fViewer = new JavaSourceViewer(composite, null, null, false, style,
+                               store);
+               fViewer.configure(new PHPSourceViewerConfiguration(WebUI
+                               .getDefault().getJavaTextTools().getColorManager(), store,
+                               null, null));
+               fViewer.setEditable(false);
+
+               fText = fViewer.getTextWidget();
+               gd = new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
+               fText.setLayoutData(gd);
+               fText.setForeground(parent.getDisplay().getSystemColor(
+                               SWT.COLOR_INFO_FOREGROUND));
+               fText.setBackground(parent.getDisplay().getSystemColor(
+                               SWT.COLOR_INFO_BACKGROUND));
+
+               fText.addKeyListener(new KeyListener() {
+
+                       public void keyPressed(KeyEvent e) {
+                               if (e.character == 0x1B) // ESC
+                                       fShell.dispose();
+                       }
+
+                       public void keyReleased(KeyEvent e) {
+                       }
+               });
+
+               // Status field
+               if (statusFieldText != null) {
+
+                       // Horizontal separator line
+                       fSeparator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL
+                                       | SWT.LINE_DOT);
+                       fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+                       // Status field label
+                       fStatusField = new Label(composite, SWT.RIGHT);
+                       fStatusField.setText(statusFieldText);
+                       Font font = fStatusField.getFont();
+                       FontData[] fontDatas = font.getFontData();
+                       for (int i = 0; i < fontDatas.length; i++)
+                               fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
+                       fStatusTextFont = new Font(fStatusField.getDisplay(), fontDatas);
+                       fStatusField.setFont(fStatusTextFont);
+                       GridData gd2 = new GridData(GridData.FILL_VERTICAL
+                                       | GridData.FILL_HORIZONTAL
+                                       | GridData.HORIZONTAL_ALIGN_BEGINNING
+                                       | GridData.VERTICAL_ALIGN_BEGINNING);
+                       fStatusField.setLayoutData(gd2);
+
+                       // Regarding the color see bug 41128
+                       fStatusField.setForeground(display
+                                       .getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
+
+                       fStatusField.setBackground(display
+                                       .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+               }
+
+               addDisposeListener(this);
+       }
+
+       /**
+        * Creates a default information control with the given shell as parent. The
+        * given information presenter is used to process the information to be
+        * displayed. The given styles are applied to the created styled text
+        * widget.
+        * 
+        * @param parent
+        *            the parent shell
+        * @param style
+        *            the additional styles for the styled text widget
+        */
+       public SourceViewerInformationControl(Shell parent, int style) {
+               this(parent, SWT.NO_TRIM, style);
+       }
+
+       /**
+        * Creates a default information control with the given shell as parent. The
+        * given information presenter is used to process the information to be
+        * displayed. The given styles are applied to the created styled text
+        * widget.
+        * 
+        * @param parent
+        *            the parent shell
+        * @param style
+        *            the additional styles for the styled text widget
+        * @param statusFieldText
+        *            the text to be used in the optional status field or
+        *            <code>null</code> if the status field should be hidden
+        * @since 3.0
+        */
+       public SourceViewerInformationControl(Shell parent, int style,
+                       String statusFieldText) {
+               this(parent, SWT.NO_TRIM, style, statusFieldText);
+       }
+
+       /**
+        * Creates a default information control with the given shell as parent. No
+        * information presenter is used to process the information to be displayed.
+        * No additional styles are applied to the styled text widget.
+        * 
+        * @param parent
+        *            the parent shell
+        */
+       public SourceViewerInformationControl(Shell parent) {
+               this(parent, SWT.NONE);
+       }
+
+       /**
+        * Creates a default information control with the given shell as parent. No
+        * information presenter is used to process the information to be displayed.
+        * No additional styles are applied to the styled text widget.
+        * 
+        * @param parent
+        *            the parent shell
+        * @param statusFieldText
+        *            the text to be used in the optional status field or
+        *            <code>null</code> if the status field should be hidden
+        * @since 3.0
+        */
+       public SourceViewerInformationControl(Shell parent, String statusFieldText) {
+               this(parent, SWT.NONE, statusFieldText);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
+        */
+       public void setInput(Object input) {
+               if (input instanceof String)
+                       setInformation((String) input);
+               else
+                       setInformation(null);
+       }
+
+       /*
+        * @see IInformationControl#setInformation(String)
+        */
+       public void setInformation(String content) {
+               if (content == null) {
+                       fViewer.setInput(null);
+                       return;
+               }
+
+               IDocument doc = new Document(content);
+               WebUI.getDefault().getJavaTextTools()
+                               .setupJavaDocumentPartitioner(doc);
+
+               fViewer.setInput(doc);
+       }
+
+       /*
+        * @see IInformationControl#setVisible(boolean)
+        */
+       public void setVisible(boolean visible) {
+               fShell.setVisible(visible);
+       }
+
+       /**
+        * {@inheritDoc}
+        * 
+        * @since 3.0
+        */
+       public void widgetDisposed(DisposeEvent event) {
+               if (fStatusTextFont != null && !fStatusTextFont.isDisposed())
+                       fStatusTextFont.dispose();
+
+               fStatusTextFont = null;
+               fShell = null;
+               fText = null;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public final void dispose() {
+               if (fShell != null && !fShell.isDisposed())
+                       fShell.dispose();
+               else
+                       widgetDisposed(null);
+       }
+
+       /*
+        * @see IInformationControl#setSize(int, int)
+        */
+       public void setSize(int width, int height) {
+
+               if (fStatusField != null) {
+                       GridData gd = (GridData) fViewer.getTextWidget().getLayoutData();
+                       Point statusSize = fStatusField.computeSize(SWT.DEFAULT,
+                                       SWT.DEFAULT, true);
+                       Point separatorSize = fSeparator.computeSize(SWT.DEFAULT,
+                                       SWT.DEFAULT, true);
+                       gd.heightHint = height - statusSize.y - separatorSize.y;
+               }
+               fShell.setSize(width, height);
+
+               if (fStatusField != null)
+                       fShell.pack(true);
+       }
+
+       /*
+        * @see IInformationControl#setLocation(Point)
+        */
+       public void setLocation(Point location) {
+               Rectangle trim = fShell.computeTrim(0, 0, 0, 0);
+               Point textLocation = fText.getLocation();
+               location.x += trim.x - textLocation.x;
+               location.y += trim.y - textLocation.y;
+               fShell.setLocation(location);
+       }
+
+       /*
+        * @see IInformationControl#setSizeConstraints(int, int)
+        */
+       public void setSizeConstraints(int maxWidth, int maxHeight) {
+               maxWidth = maxHeight;
+       }
+
+       /*
+        * @see IInformationControl#computeSizeHint()
+        */
+       public Point computeSizeHint() {
+               return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+       }
+
+       /*
+        * @see IInformationControl#addDisposeListener(DisposeListener)
+        */
+       public void addDisposeListener(DisposeListener listener) {
+               fShell.addDisposeListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#removeDisposeListener(DisposeListener)
+        */
+       public void removeDisposeListener(DisposeListener listener) {
+               fShell.removeDisposeListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#setForegroundColor(Color)
+        */
+       public void setForegroundColor(Color foreground) {
+               fText.setForeground(foreground);
+       }
+
+       /*
+        * @see IInformationControl#setBackgroundColor(Color)
+        */
+       public void setBackgroundColor(Color background) {
+               fText.setBackground(background);
+       }
+
+       /*
+        * @see IInformationControl#isFocusControl()
+        */
+       public boolean isFocusControl() {
+               return fText.isFocusControl();
+       }
+
+       /*
+        * @see IInformationControl#setFocus()
+        */
+       public void setFocus() {
+               fShell.forceFocus();
+               fText.setFocus();
+       }
+
+       /*
+        * @see IInformationControl#addFocusListener(FocusListener)
+        */
+       public void addFocusListener(FocusListener listener) {
+               fText.addFocusListener(listener);
+       }
+
+       /*
+        * @see IInformationControl#removeFocusListener(FocusListener)
+        */
+       public void removeFocusListener(FocusListener listener) {
+               fText.removeFocusListener(listener);
+       }
+
+       /*
+        * @see IInformationControlExtension#hasContents()
+        */
+       public boolean hasContents() {
+               return fText.getCharCount() > 0;
+       }
+
+       protected ISourceViewer getViewer() {
+               return fViewer;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/ILinkedPositionListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/ILinkedPositionListener.java
new file mode 100644 (file)
index 0000000..b462ede
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.link;
+
+import org.eclipse.jface.text.Position;
+
+/**
+ * A listener for highlight change notification and exititing linked mode.
+ */
+public interface ILinkedPositionListener {
+
+       /**
+        * Notifies that the linked mode has been left. On success, all changes are
+        * kept, otherwise all changes made to the linked positions are restored to
+        * the state before entering linked mode.
+        */
+       void exit(int flags);
+
+       /**
+        * Notifies the changed linked position. The listener is asked to reposition
+        * the caret at the given offset.
+        * 
+        * @param position
+        *            the linked position which initiated the change.
+        * @param caretOffset
+        *            the caret offset relative to the position.
+        */
+       void setCurrentPosition(Position position, int caretOffset);
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionListener.java
new file mode 100644 (file)
index 0000000..f204eb1
--- /dev/null
@@ -0,0 +1,39 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.link;
+
+import org.eclipse.jface.text.Position;
+
+/**
+ * A listener for highlight change notification and exititing linked mode.
+ */
+public interface LinkedPositionListener {
+
+       /**
+        * Notifies that the linked mode has been left. On success, all changes are
+        * kept, otherwise all changes made to the linked positions are restored to
+        * the state before entering linked mode.
+        */
+       void exit(boolean success);
+
+       /**
+        * Notifies the changed linked position. The listener is asked to reposition
+        * the caret at the given offset.
+        * 
+        * @param position
+        *            the linked position which initiated the change.
+        * @param caretOffset
+        *            the caret offset relative to the position.
+        */
+       void setCurrentPosition(Position position, int caretOffset);
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionManager.java
new file mode 100644 (file)
index 0000000..3a89914
--- /dev/null
@@ -0,0 +1,831 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.link;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IPositionUpdater;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.TypedPosition;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+
+/**
+ * This class manages linked positions in a document. Positions are linked by
+ * type names. If positions have the same type name, they are considered as
+ * <em>linked</em>.
+ * 
+ * The manager remains active on a document until any of the following actions
+ * occurs:
+ * 
+ * <ul>
+ * <li>A document change is performed which would invalidate any of the above
+ * constraints.</li>
+ * 
+ * <li>The method <code>uninstall()</code> is called.</li>
+ * 
+ * <li>Another instance of <code>LinkedPositionManager</code> tries to gain
+ * control of the same document.
+ * </ul>
+ */
+public class LinkedPositionManager implements IDocumentListener,
+               IPositionUpdater, IAutoEditStrategy {
+
+       // This class still exists to properly handle code assist.
+       // This is due to the fact that it cannot be distinguished betweeen document
+       // changes which are
+       // issued by code assist and document changes which origin from another text
+       // viewer.
+       // There is a conflict in interest since in the latter case the linked mode
+       // should be left, but in the former case
+       // the linked mode should remain.
+       // To support content assist, document changes have to be propagated to
+       // connected positions
+       // by registering replace commands using IDocumentExtension.
+       // if it wasn't for the support of content assist, the documentChanged()
+       // method could be reduced to
+       // a simple call to leave(true)
+       private class Replace implements IDocumentExtension.IReplace {
+
+               private Position fReplacePosition;
+
+               private int fReplaceDeltaOffset;
+
+               private int fReplaceLength;
+
+               private String fReplaceText;
+
+               public Replace(Position position, int deltaOffset, int length,
+                               String text) {
+                       fReplacePosition = position;
+                       fReplaceDeltaOffset = deltaOffset;
+                       fReplaceLength = length;
+                       fReplaceText = text;
+               }
+
+               public void perform(IDocument document, IDocumentListener owner) {
+                       document.removeDocumentListener(owner);
+                       try {
+                               document.replace(fReplacePosition.getOffset()
+                                               + fReplaceDeltaOffset, fReplaceLength, fReplaceText);
+                       } catch (BadLocationException e) {
+                               WebUI.log(e);
+                               // TBD
+                       }
+                       document.addDocumentListener(owner);
+               }
+       }
+
+       private static class PositionComparator implements Comparator {
+               /*
+                * @see Comparator#compare(Object, Object)
+                */
+               public int compare(Object object0, Object object1) {
+                       Position position0 = (Position) object0;
+                       Position position1 = (Position) object1;
+
+                       return position0.getOffset() - position1.getOffset();
+               }
+       }
+
+       private static final String LINKED_POSITION_PREFIX = "LinkedPositionManager.linked.position"; //$NON-NLS-1$
+
+       private static final Comparator fgPositionComparator = new PositionComparator();
+
+       private static final Map fgActiveManagers = new HashMap();
+
+       private static int fgCounter = 0;
+
+       private IDocument fDocument;
+
+       private ILinkedPositionListener fListener;
+
+       private String fPositionCategoryName;
+
+       private boolean fMustLeave;
+
+       /**
+        * Flag that records the state of this manager. As there are many different
+        * entities that may call leave or exit, these cannot always be sure whether
+        * the linked position infrastructure is still active. This is especially
+        * true for multithreaded situations.
+        */
+       private boolean fIsActive = false;
+
+       /**
+        * Creates a <code>LinkedPositionManager</code> for a
+        * <code>IDocument</code>.
+        * 
+        * @param document
+        *            the document to use with linked positions.
+        * @param canCoexist
+        *            <code>true</code> if this manager can coexist with an
+        *            already existing one
+        */
+       public LinkedPositionManager(IDocument document, boolean canCoexist) {
+               Assert.isNotNull(document);
+               fDocument = document;
+               fPositionCategoryName = LINKED_POSITION_PREFIX + (fgCounter++);
+               install(canCoexist);
+       }
+
+       /**
+        * Creates a <code>LinkedPositionManager</code> for a
+        * <code>IDocument</code>.
+        * 
+        * @param document
+        *            the document to use with linked positions.
+        */
+       public LinkedPositionManager(IDocument document) {
+               this(document, false);
+       }
+
+       /**
+        * Sets a listener to notify changes of current linked position.
+        */
+       public void setLinkedPositionListener(ILinkedPositionListener listener) {
+               fListener = listener;
+       }
+
+       /**
+        * Adds a linked position to the manager with the type being the content of
+        * the document at the specified range. There are the following constraints
+        * for linked positions:
+        * 
+        * <ul>
+        * <li>Any two positions have spacing of at least one character. This
+        * implies that two positions must not overlap.</li>
+        * 
+        * <li>The string at any position must not contain line delimiters.</li>
+        * </ul>
+        * 
+        * @param offset
+        *            the offset of the position.
+        * @param length
+        *            the length of the position.
+        */
+       public void addPosition(int offset, int length) throws BadLocationException {
+               String type = fDocument.get(offset, length);
+               addPosition(offset, length, type);
+       }
+
+       /**
+        * Adds a linked position of the specified position type to the manager.
+        * There are the following constraints for linked positions:
+        * 
+        * <ul>
+        * <li>Any two positions have spacing of at least one character. This
+        * implies that two positions must not overlap.</li>
+        * 
+        * <li>The string at any position must not contain line delimiters.</li>
+        * </ul>
+        * 
+        * @param offset
+        *            the offset of the position.
+        * @param length
+        *            the length of the position.
+        * @param type
+        *            the position type name - any positions with the same type are
+        *            linked.
+        */
+       public void addPosition(int offset, int length, String type)
+                       throws BadLocationException {
+               Position[] positions = getPositions(fDocument);
+
+               if (positions != null) {
+                       for (int i = 0; i < positions.length; i++)
+                               if (collides(positions[i], offset, length))
+                                       throw new BadLocationException(
+                                                       LinkedPositionMessages
+                                                                       .getString(("LinkedPositionManager.error.position.collision"))); //$NON-NLS-1$
+               }
+
+               String content = fDocument.get(offset, length);
+
+               if (containsLineDelimiters(content))
+                       throw new BadLocationException(
+                                       LinkedPositionMessages
+                                                       .getString(("LinkedPositionManager.error.contains.line.delimiters"))); //$NON-NLS-1$
+
+               try {
+                       fDocument.addPosition(fPositionCategoryName, new TypedPosition(
+                                       offset, length, type));
+               } catch (BadPositionCategoryException e) {
+                       WebUI.log(e);
+                       Assert.isTrue(false);
+               }
+       }
+
+       /**
+        * Adds a linked position to the manager. The current document content at
+        * the specified range is taken as the position type.
+        * <p>
+        * There are the following constraints for linked positions:
+        * 
+        * <ul>
+        * <li>Any two positions have spacing of at least one character. This
+        * implies that two positions must not overlap.</li>
+        * 
+        * <li>The string at any position must not contain line delimiters.</li>
+        * </ul>
+        * 
+        * It is usually best to set the first item in
+        * <code>additionalChoices</code> to be equal with the text inserted at
+        * the current position.
+        * </p>
+        * 
+        * @param offset
+        *            the offset of the position.
+        * @param length
+        *            the length of the position.
+        * @param additionalChoices
+        *            a number of additional choices to be displayed when selecting
+        *            a position of this <code>type</code>.
+        */
+       public void addPosition(int offset, int length,
+                       ICompletionProposal[] additionalChoices)
+                       throws BadLocationException {
+               String type = fDocument.get(offset, length);
+               addPosition(offset, length, type, additionalChoices);
+       }
+
+       /**
+        * Adds a linked position of the specified position type to the manager.
+        * There are the following constraints for linked positions:
+        * 
+        * <ul>
+        * <li>Any two positions have spacing of at least one character. This
+        * implies that two positions must not overlap.</li>
+        * 
+        * <li>The string at any position must not contain line delimiters.</li>
+        * </ul>
+        * 
+        * It is usually best to set the first item in
+        * <code>additionalChoices</code> to be equal with the text inserted at
+        * the current position.
+        * 
+        * @param offset
+        *            the offset of the position.
+        * @param length
+        *            the length of the position.
+        * @param type
+        *            the position type name - any positions with the same type are
+        *            linked.
+        * @param additionalChoices
+        *            a number of additional choices to be displayed when selecting
+        *            a position of this <code>type</code>.
+        */
+       public void addPosition(int offset, int length, String type,
+                       ICompletionProposal[] additionalChoices)
+                       throws BadLocationException {
+               Position[] positions = getPositions(fDocument);
+
+               if (positions != null) {
+                       for (int i = 0; i < positions.length; i++)
+                               if (collides(positions[i], offset, length))
+                                       throw new BadLocationException(
+                                                       LinkedPositionMessages
+                                                                       .getString(("LinkedPositionManager.error.position.collision"))); //$NON-NLS-1$
+               }
+
+               String content = fDocument.get(offset, length);
+
+               if (containsLineDelimiters(content))
+                       throw new BadLocationException(
+                                       LinkedPositionMessages
+                                                       .getString(("LinkedPositionManager.error.contains.line.delimiters"))); //$NON-NLS-1$
+
+               try {
+                       fDocument.addPosition(fPositionCategoryName, new ProposalPosition(
+                                       offset, length, type, additionalChoices));
+               } catch (BadPositionCategoryException e) {
+                       WebUI.log(e);
+                       Assert.isTrue(false);
+               }
+       }
+
+       /**
+        * Tests if a manager is already active for a document.
+        */
+       public static boolean hasActiveManager(IDocument document) {
+               return fgActiveManagers.get(document) != null;
+       }
+
+       private void install(boolean canCoexist) {
+
+               if (fIsActive)
+                       ;// JavaPlugin.log(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionManager
+                               // is already active: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+               else {
+                       fIsActive = true;
+                       // JavaPlugin.log(new Status(IStatus.INFO, JavaPlugin.getPluginId(),
+                       // IStatus.OK, "LinkedPositionManager activated:
+                       // "+fPositionCategoryName, new Exception())); //$NON-NLS-1$
+               }
+
+               if (!canCoexist) {
+                       LinkedPositionManager manager = (LinkedPositionManager) fgActiveManagers
+                                       .get(fDocument);
+                       if (manager != null)
+                               manager.leave(true);
+               }
+
+               fgActiveManagers.put(fDocument, this);
+               fDocument.addPositionCategory(fPositionCategoryName);
+               fDocument.addPositionUpdater(this);
+               fDocument.addDocumentListener(this);
+
+               fMustLeave = false;
+       }
+
+       /**
+        * Leaves the linked mode. If unsuccessful, the linked positions are
+        * restored to the values at the time they were added.
+        */
+       public void uninstall(boolean success) {
+
+               if (!fIsActive)
+                       // we migth also just return
+                       ;// JavaPlugin(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionManager
+                               // activated: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+               else {
+                       fDocument.removeDocumentListener(this);
+
+                       try {
+                               Position[] positions = getPositions(fDocument);
+                               if ((!success) && (positions != null)) {
+                                       // restore
+                                       for (int i = 0; i != positions.length; i++) {
+                                               TypedPosition position = (TypedPosition) positions[i];
+                                               fDocument.replace(position.getOffset(), position
+                                                               .getLength(), position.getType());
+                                       }
+                               }
+
+                               fDocument.removePositionCategory(fPositionCategoryName);
+
+                               fIsActive = false;
+                               // JavaPlugin.log(new Status(IStatus.INFO,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionManager
+                               // deactivated: "+fPositionCategoryName, new Exception()));
+                               // //$NON-NLS-1$
+
+                       } catch (BadLocationException e) {
+                               WebUI.log(e);
+                               Assert.isTrue(false);
+
+                       } catch (BadPositionCategoryException e) {
+                               WebUI.log(e);
+                               Assert.isTrue(false);
+
+                       } finally {
+                               fDocument.removePositionUpdater(this);
+                               fgActiveManagers.remove(fDocument);
+                       }
+               }
+
+       }
+
+       /**
+        * Returns the position at the given offset, <code>null</code> if there is
+        * no position.
+        * 
+        * @since 2.1
+        */
+       public Position getPosition(int offset) {
+               Position[] positions = getPositions(fDocument);
+               if (positions == null)
+                       return null;
+
+               for (int i = positions.length - 1; i >= 0; i--) {
+                       Position position = positions[i];
+                       if (offset >= position.getOffset()
+                                       && offset <= position.getOffset() + position.getLength())
+                               return positions[i];
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns the first linked position.
+        * 
+        * @return returns <code>null</code> if no linked position exist.
+        */
+       public Position getFirstPosition() {
+               return getNextPosition(-1);
+       }
+
+       public Position getLastPosition() {
+               Position[] positions = getPositions(fDocument);
+               for (int i = positions.length - 1; i >= 0; i--) {
+                       String type = ((TypedPosition) positions[i]).getType();
+                       int j;
+                       for (j = 0; j != i; j++)
+                               if (((TypedPosition) positions[j]).getType().equals(type))
+                                       break;
+
+                       if (j == i)
+                               return positions[i];
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns the next linked position with an offset greater than
+        * <code>offset</code>. If another position with the same type and offset
+        * lower than <code>offset</code> exists, the position is skipped.
+        * 
+        * @return returns <code>null</code> if no linked position exist.
+        */
+       public Position getNextPosition(int offset) {
+               Position[] positions = getPositions(fDocument);
+               return findNextPosition(positions, offset);
+       }
+
+       private static Position findNextPosition(Position[] positions, int offset) {
+               // skip already visited types
+               for (int i = 0; i != positions.length; i++) {
+                       if (positions[i].getOffset() > offset) {
+                               String type = ((TypedPosition) positions[i]).getType();
+                               int j;
+                               for (j = 0; j != i; j++)
+                                       if (((TypedPosition) positions[j]).getType().equals(type))
+                                               break;
+
+                               if (j == i)
+                                       return positions[i];
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns the position with the greatest offset smaller than
+        * <code>offset</code>.
+        * 
+        * @return returns <code>null</code> if no linked position exist.
+        */
+       public Position getPreviousPosition(int offset) {
+               Position[] positions = getPositions(fDocument);
+               if (positions == null)
+                       return null;
+
+               TypedPosition currentPosition = (TypedPosition) findCurrentPosition(
+                               positions, offset);
+               String currentType = currentPosition == null ? null : currentPosition
+                               .getType();
+
+               Position lastPosition = null;
+               Position position = getFirstPosition();
+
+               while (position != null && position.getOffset() < offset) {
+                       if (!((TypedPosition) position).getType().equals(currentType))
+                               lastPosition = position;
+                       position = findNextPosition(positions, position.getOffset());
+               }
+
+               return lastPosition;
+       }
+
+       private Position[] getPositions(IDocument document) {
+
+               if (!fIsActive)
+                       // we migth also just return an empty array
+                       ;// JavaPlugin(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionManager
+                               // is not active: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+
+               try {
+                       Position[] positions = document.getPositions(fPositionCategoryName);
+                       Arrays.sort(positions, fgPositionComparator);
+                       return positions;
+
+               } catch (BadPositionCategoryException e) {
+                       WebUI.log(e);
+                       Assert.isTrue(false);
+               }
+
+               return null;
+       }
+
+       public static boolean includes(Position position, int offset, int length) {
+               return (offset >= position.getOffset())
+                               && (offset + length <= position.getOffset()
+                                               + position.getLength());
+       }
+
+       public static boolean excludes(Position position, int offset, int length) {
+               return (offset + length <= position.getOffset())
+                               || (position.getOffset() + position.getLength() <= offset);
+       }
+
+       /*
+        * Collides if spacing if positions intersect each other or are adjacent.
+        */
+       private static boolean collides(Position position, int offset, int length) {
+               return (offset <= position.getOffset() + position.getLength())
+                               && (position.getOffset() <= offset + length);
+       }
+
+       private void leave(boolean success) {
+               try {
+                       uninstall(success);
+
+                       if (fListener != null)
+                               fListener.exit((success ? LinkedPositionUI.COMMIT : 0)
+                                               | LinkedPositionUI.UPDATE_CARET);
+               } finally {
+                       fMustLeave = false;
+               }
+       }
+
+       private void abort() {
+               uninstall(true); // don't revert anything
+
+               if (fListener != null)
+                       fListener.exit(LinkedPositionUI.COMMIT); // don't let the UI
+                                                                                                               // restore anything
+
+               // don't set fMustLeave, as we will get re-registered by a document
+               // event
+       }
+
+       /*
+        * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+        */
+       public void documentAboutToBeChanged(DocumentEvent event) {
+
+               if (fMustLeave) {
+                       event.getDocument().removeDocumentListener(this);
+                       return;
+               }
+
+               IDocument document = event.getDocument();
+
+               Position[] positions = getPositions(document);
+               Position position = findCurrentPosition(positions, event.getOffset());
+
+               // modification outside editable position
+               if (position == null) {
+                       // check for destruction of constraints (spacing of at least 1)
+                       if ((event.getText() == null || event.getText().length() == 0)
+                                       && (findCurrentPosition(positions, event.getOffset()) != null)
+                                       && // will never become true, see condition above
+                                       (findCurrentPosition(positions, event.getOffset()
+                                                       + event.getLength()) != null)) {
+                               leave(true);
+                       }
+
+                       // modification intersects editable position
+               } else {
+                       // modificaction inside editable position
+                       if (includes(position, event.getOffset(), event.getLength())) {
+                               if (containsLineDelimiters(event.getText()))
+                                       leave(true);
+
+                               // modificaction exceeds editable position
+                       } else {
+                               leave(true);
+                       }
+               }
+       }
+
+       /*
+        * @see IDocumentListener#documentChanged(DocumentEvent)
+        */
+       public void documentChanged(DocumentEvent event) {
+
+               // have to handle code assist, so can't just leave the linked mode
+               // leave(true);
+
+               IDocument document = event.getDocument();
+
+               Position[] positions = getPositions(document);
+               TypedPosition currentPosition = (TypedPosition) findCurrentPosition(
+                               positions, event.getOffset());
+
+               // ignore document changes (assume it won't invalidate constraints)
+               if (currentPosition == null)
+                       return;
+
+               int deltaOffset = event.getOffset() - currentPosition.getOffset();
+
+               if (fListener != null) {
+                       int length = event.getText() == null ? 0 : event.getText().length();
+                       fListener.setCurrentPosition(currentPosition, deltaOffset + length);
+               }
+
+               for (int i = 0; i != positions.length; i++) {
+                       TypedPosition p = (TypedPosition) positions[i];
+
+                       if (p.getType().equals(currentPosition.getType())
+                                       && !p.equals(currentPosition)) {
+                               Replace replace = new Replace(p, deltaOffset,
+                                               event.getLength(), event.getText());
+                               ((IDocumentExtension) document)
+                                               .registerPostNotificationReplace(this, replace);
+                       }
+               }
+       }
+
+       /*
+        * @see IPositionUpdater#update(DocumentEvent)
+        */
+       public void update(DocumentEvent event) {
+
+               int eventOffset = event.getOffset();
+               int eventOldLength = event.getLength();
+               int eventNewLength = event.getText() == null ? 0 : event.getText()
+                               .length();
+               int deltaLength = eventNewLength - eventOldLength;
+
+               Position[] positions = getPositions(event.getDocument());
+
+               for (int i = 0; i != positions.length; i++) {
+
+                       Position position = positions[i];
+
+                       if (position.isDeleted())
+                               continue;
+
+                       int offset = position.getOffset();
+                       int length = position.getLength();
+                       int end = offset + length;
+
+                       if (offset > eventOffset + eventOldLength) // position comes way
+                                                                                                               // after change - shift
+                               position.setOffset(offset + deltaLength);
+                       else if (end < eventOffset) // position comes way before change -
+                                                                               // leave alone
+                               ;
+                       else if (offset <= eventOffset
+                                       && end >= eventOffset + eventOldLength) {
+                               // event completely internal to the position - adjust length
+                               position.setLength(length + deltaLength);
+                       } else if (offset < eventOffset) {
+                               // event extends over end of position - adjust length
+                               int newEnd = eventOffset + eventNewLength;
+                               position.setLength(newEnd - offset);
+                       } else if (end > eventOffset + eventOldLength) {
+                               // event extends from before position into it - adjust offset
+                               // and length
+                               // offset becomes end of event, length ajusted acordingly
+                               // we want to recycle the overlapping part
+                               int newOffset = eventOffset + eventNewLength;
+                               position.setOffset(newOffset);
+                               position.setLength(length + deltaLength);
+                       } else {
+                               // event consumes the position - delete it
+                               position.delete();
+                               // JavaPlugin.log(new Status(IStatus.INFO,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "linked position
+                               // deleted -> must leave: "+fPositionCategoryName, null));
+                               // //$NON-NLS-1$
+                               fMustLeave = true;
+                       }
+               }
+
+               if (fMustLeave)
+                       abort();
+       }
+
+       private static Position findCurrentPosition(Position[] positions, int offset) {
+               for (int i = 0; i != positions.length; i++)
+                       if (includes(positions[i], offset, 0))
+                               return positions[i];
+
+               return null;
+       }
+
+       private boolean containsLineDelimiters(String string) {
+
+               if (string == null)
+                       return false;
+
+               String[] delimiters = fDocument.getLegalLineDelimiters();
+
+               for (int i = 0; i != delimiters.length; i++)
+                       if (string.indexOf(delimiters[i]) != -1)
+                               return true;
+
+               return false;
+       }
+
+       /**
+        * Test if ok to modify through UI.
+        */
+       public boolean anyPositionIncludes(int offset, int length) {
+               Position[] positions = getPositions(fDocument);
+
+               Position position = findCurrentPosition(positions, offset);
+               if (position == null)
+                       return false;
+
+               return includes(position, offset, length);
+       }
+
+       /**
+        * Returns the position that includes the given range.
+        * 
+        * @param offset
+        * @param length
+        * @return position that includes the given range
+        */
+       public Position getEmbracingPosition(int offset, int length) {
+               Position[] positions = getPositions(fDocument);
+
+               Position position = findCurrentPosition(positions, offset);
+               if (position != null && includes(position, offset, length))
+                       return position;
+
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IAutoIndentStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument,
+        *      org.eclipse.jface.text.DocumentCommand)
+        */
+       public void customizeDocumentCommand(IDocument document,
+                       DocumentCommand command) {
+
+               if (fMustLeave) {
+                       leave(true);
+                       return;
+               }
+
+               // don't interfere with preceding auto edit strategies
+               if (command.getCommandCount() != 1) {
+                       leave(true);
+                       return;
+               }
+
+               Position[] positions = getPositions(document);
+               TypedPosition currentPosition = (TypedPosition) findCurrentPosition(
+                               positions, command.offset);
+
+               // handle edits outside of a position
+               if (currentPosition == null) {
+                       leave(true);
+                       return;
+               }
+
+               if (!command.doit)
+                       return;
+
+               command.doit = false;
+               command.owner = this;
+               command.caretOffset = command.offset + command.length;
+
+               int deltaOffset = command.offset - currentPosition.getOffset();
+
+               if (fListener != null)
+                       fListener.setCurrentPosition(currentPosition, deltaOffset
+                                       + command.text.length());
+
+               for (int i = 0; i != positions.length; i++) {
+                       TypedPosition position = (TypedPosition) positions[i];
+
+                       try {
+                               if (position.getType().equals(currentPosition.getType())
+                                               && !position.equals(currentPosition))
+                                       command.addCommand(position.getOffset() + deltaOffset,
+                                                       command.length, command.text, this);
+                       } catch (BadLocationException e) {
+                               WebUI.log(e);
+                       }
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionMessages.java
new file mode 100644 (file)
index 0000000..decf492
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.link;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class LinkedPositionMessages {
+
+       private static final String RESOURCE_BUNDLE = LinkedPositionMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private LinkedPositionMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionMessages.properties
new file mode 100644 (file)
index 0000000..267939d
--- /dev/null
@@ -0,0 +1,9 @@
+#########################################
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+#########################################
+
+LinkedPositionUI.error.title=Error in LinkedPositionError
+
+LinkedPositionManager.error.contains.line.delimiters=String contains line delimiters.
+LinkedPositionManager.error.position.collision=Linked position collides with another linked position.
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionUI.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionUI.java
new file mode 100644 (file)
index 0000000..04d120f
--- /dev/null
@@ -0,0 +1,972 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.link;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IPositionUpdater;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.IRewriteTarget;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextEvent;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.events.ShellListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A user interface for <code>LinkedPositionManager</code>, using
+ * <code>ITextViewer</code>.
+ */
+public class LinkedPositionUI implements ILinkedPositionListener,
+               ITextInputListener, ITextListener, ModifyListener, VerifyListener,
+               VerifyKeyListener, PaintListener, IPropertyChangeListener,
+               ShellListener {
+
+       /**
+        * A listener for notification when the user cancelled the edit operation.
+        */
+       public interface ExitListener {
+               void exit(boolean accept);
+       }
+
+       public static class ExitFlags {
+               public int flags;
+
+               public boolean doit;
+
+               public ExitFlags(int flags, boolean doit) {
+                       this.flags = flags;
+                       this.doit = doit;
+               }
+       }
+
+       public interface ExitPolicy {
+               ExitFlags doExit(LinkedPositionManager manager, VerifyEvent event,
+                               int offset, int length);
+       }
+
+       // leave flags
+       private static final int UNINSTALL = 1; // uninstall linked position manager
+
+       public static final int COMMIT = 2; // commit changes
+
+       private static final int DOCUMENT_CHANGED = 4; // document has changed
+
+       public static final int UPDATE_CARET = 8; // update caret
+
+       private static final IPreferenceStore fgStore = WebUI
+                       .getDefault().getPreferenceStore();
+
+       private static final String CARET_POSITION_PREFIX = "LinkedPositionUI.caret.position"; //$NON-NLS-1$
+
+       private static int fgCounter = 0;
+
+       private final ITextViewer fViewer;
+
+       private final LinkedPositionManager fManager;
+
+       private final IPositionUpdater fUpdater;
+
+       private final String fPositionCategoryName;
+
+       private Color fFrameColor;
+
+       private int fFinalCaretOffset = -1; // no final caret offset
+
+       private Position fFinalCaretPosition;
+
+       private Position fFramePosition;
+
+       private int fInitialOffset = -1;
+
+       private int fCaretOffset;
+
+       private ExitPolicy fExitPolicy;
+
+       private ExitListener fExitListener;
+
+       private boolean fNeedRedraw;
+
+       private String fContentType;
+
+       private Position fPreviousPosition;
+
+       // private ContentAssistant2 fAssistant;
+
+       /**
+        * Flag that records the state of this ui object. As there are many
+        * different entities that may call leave or exit, these cannot always be
+        * sure whether the linked position infrastructure is still active. This is
+        * especially true for multithreaded situations.
+        */
+       private boolean fIsActive = false;
+
+       /**
+        * Creates a user interface for <code>LinkedPositionManager</code>.
+        * 
+        * @param viewer
+        *            the text viewer.
+        * @param manager
+        *            the <code>LinkedPositionManager</code> managing a
+        *            <code>IDocument</code> of the <code>ITextViewer</code>.
+        */
+       public LinkedPositionUI(ITextViewer viewer, LinkedPositionManager manager) {
+               Assert.isNotNull(viewer);
+               Assert.isNotNull(manager);
+
+               fViewer = viewer;
+               fManager = manager;
+
+               fPositionCategoryName = CARET_POSITION_PREFIX + (fgCounter++);
+               fUpdater = new DefaultPositionUpdater(fPositionCategoryName);
+
+               fManager.setLinkedPositionListener(this);
+
+               initializeHighlightColor(viewer);
+       }
+
+       /*
+        * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+        */
+       public void propertyChange(PropertyChangeEvent event) {
+               if (event.getProperty().equals(
+                               PreferenceConstants.EDITOR_LINKED_POSITION_COLOR)) {
+                       initializeHighlightColor(fViewer);
+                       redrawRegion();
+               }
+       }
+
+       private void initializeHighlightColor(ITextViewer viewer) {
+
+               if (fFrameColor != null)
+                       fFrameColor.dispose();
+
+               StyledText text = viewer.getTextWidget();
+               if (text != null) {
+                       Display display = text.getDisplay();
+                       fFrameColor = createColor(fgStore,
+                                       PreferenceConstants.EDITOR_LINKED_POSITION_COLOR, display);
+               }
+       }
+
+       /**
+        * Creates a color from the information stored in the given preference
+        * store. Returns <code>null</code> if there is no such information
+        * available.
+        */
+       private Color createColor(IPreferenceStore store, String key,
+                       Display display) {
+
+               RGB rgb = null;
+
+               if (store.contains(key)) {
+
+                       if (store.isDefault(key))
+                               rgb = PreferenceConverter.getDefaultColor(store, key);
+                       else
+                               rgb = PreferenceConverter.getColor(store, key);
+
+                       if (rgb != null)
+                               return new Color(display, rgb);
+               }
+
+               return null;
+       }
+
+       /**
+        * Sets the initial offset.
+        * 
+        * @param offset
+        */
+       public void setInitialOffset(int offset) {
+               fInitialOffset = offset;
+       }
+
+       /**
+        * Sets the final position of the caret when the linked mode is exited
+        * successfully by leaving the last linked position using TAB. The set
+        * position will be a TAB stop as well as the positions configured in the
+        * <code>LinkedPositionManager</code>.
+        */
+       public void setFinalCaretOffset(int offset) {
+               fFinalCaretOffset = offset;
+       }
+
+       /**
+        * Sets a <code>CancelListener</code> which is notified if the linked mode
+        * is exited unsuccessfully by hitting ESC.
+        */
+       public void setCancelListener(ExitListener listener) {
+               fExitListener = listener;
+       }
+
+       /**
+        * Sets an <code>ExitPolicy</code> which decides when and how the linked
+        * mode is exited.
+        */
+       public void setExitPolicy(ExitPolicy policy) {
+               fExitPolicy = policy;
+       }
+
+       /*
+        * @see LinkedPositionManager.LinkedPositionListener#setCurrentPositions(Position,
+        *      int)
+        */
+       public void setCurrentPosition(Position position, int caretOffset) {
+               if (!fIsActive)
+                       ;// JavaPlugin.log(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionUI is
+                               // not active: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+
+               if (!fFramePosition.equals(position)) {
+                       fNeedRedraw = true;
+                       fFramePosition = position;
+               }
+
+               fCaretOffset = caretOffset;
+       }
+
+       /**
+        * Enters the linked mode. The linked mode can be left by calling
+        * <code>exit</code>.
+        * 
+        * @see #exit(boolean)
+        */
+       public void enter() {
+               if (fIsActive)
+                       ;// JavaPlugin.log(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionUI is
+                               // already active: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+               else {
+                       fIsActive = true;
+                       // JavaPlugin.log(new Status(IStatus.INFO, JavaPlugin.getPluginId(),
+                       // IStatus.OK, "LinkedPositionUI activated: "+fPositionCategoryName,
+                       // new Exception())); //$NON-NLS-1$
+               }
+
+               // track final caret
+               IDocument document = fViewer.getDocument();
+               document.addPositionCategory(fPositionCategoryName);
+               document.addPositionUpdater(fUpdater);
+
+               try {
+                       if (fFinalCaretOffset != -1) {
+                               fFinalCaretPosition = new Position(fFinalCaretOffset);
+                               document
+                                               .addPosition(fPositionCategoryName, fFinalCaretPosition);
+                       }
+               } catch (BadLocationException e) {
+                       handleException(fViewer.getTextWidget().getShell(), e);
+
+               } catch (BadPositionCategoryException e) {
+                       WebUI.log(e);
+                       Assert.isTrue(false);
+               }
+
+               fViewer.addTextInputListener(this);
+               fViewer.addTextListener(this);
+
+               ITextViewerExtension extension = (ITextViewerExtension) fViewer;
+               extension.prependVerifyKeyListener(this);
+
+               StyledText text = fViewer.getTextWidget();
+               text.addVerifyListener(this);
+               text.addModifyListener(this);
+               text.addPaintListener(this);
+               text.showSelection();
+
+               Shell shell = text.getShell();
+               shell.addShellListener(this);
+
+               fFramePosition = (fInitialOffset == -1) ? fManager.getFirstPosition()
+                               : fManager.getPosition(fInitialOffset);
+               if (fFramePosition == null) {
+                       leave(UNINSTALL | COMMIT | UPDATE_CARET);
+                       return;
+               }
+
+               fgStore.addPropertyChangeListener(this);
+
+               // try {
+               // fContentType= TextUtilities.getContentType(document,
+               // IJavaPartitions.JAVA_PARTITIONING, fFramePosition.offset);
+               // if (fViewer instanceof ITextViewerExtension2) {
+               // ((ITextViewerExtension2) fViewer).prependAutoEditStrategy(fManager,
+               // fContentType);
+               // } else {
+               // Assert.isTrue(false);
+               // }
+               //
+               // } catch (BadLocationException e) {
+               // handleException(fViewer.getTextWidget().getShell(), e);
+               // }
+               try {
+                       fContentType = document.getContentType(fFramePosition.offset);
+                       if (fViewer instanceof ITextViewerExtension2) {
+                               ((ITextViewerExtension2) fViewer).prependAutoEditStrategy(
+                                               fManager, fContentType);
+                       } else {
+                               Assert.isTrue(false);
+                       }
+
+               } catch (BadLocationException e) {
+                       handleException(fViewer.getTextWidget().getShell(), e);
+               }
+               selectRegion();
+               // triggerContentAssist();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.link.ILinkedPositionListener#exit(boolean)
+        */
+       public void exit(int flags) {
+               leave(flags);
+       }
+
+       /**
+        * Returns the cursor selection, after having entered the linked mode.
+        * <code>enter()</code> must be called prior to a call to this method.
+        */
+       public IRegion getSelectedRegion() {
+               if (!fIsActive)
+                       ;// JavaPlugin.log(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionUI is
+                               // not active: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+
+               if (fFramePosition == null)
+                       return new Region(fFinalCaretOffset, 0);
+               else
+                       return new Region(fFramePosition.getOffset(), fFramePosition
+                                       .getLength());
+       }
+
+       private void leave(int flags) {
+               if (!fIsActive)
+                       ;// JavaPlugin.log(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionUI is
+                               // not active: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+               else {
+                       fIsActive = false;
+                       // JavaPlugin.log(new Status(IStatus.INFO, JavaPlugin.getPluginId(),
+                       // IStatus.OK, "LinkedPositionUI deactivated:
+                       // "+fPositionCategoryName, new Exception())); //$NON-NLS-1$
+               }
+
+               fInitialOffset = -1;
+
+               if ((flags & UNINSTALL) != 0)
+                       fManager.uninstall((flags & COMMIT) != 0);
+
+               fgStore.removePropertyChangeListener(this);
+
+               if (fFrameColor != null) {
+                       fFrameColor.dispose();
+                       fFrameColor = null;
+               }
+
+               StyledText text = fViewer.getTextWidget();
+               // bail out if the styled text is null, meaning the viewer has been
+               // disposed (-> document is null as well)
+               // see pr https://bugs.eclipse.org/bugs/show_bug.cgi?id=46821
+               if (text == null)
+                       return;
+
+               text.removePaintListener(this);
+               text.removeModifyListener(this);
+               text.removeVerifyListener(this);
+
+               Shell shell = text.getShell();
+               shell.removeShellListener(this);
+
+               // if (fAssistant != null) {
+               // Display display= text.getDisplay();
+               // if (display != null && !display.isDisposed()) {
+               // display.asyncExec(new Runnable() {
+               // public void run() {
+               // if (fAssistant != null) {
+               // fAssistant.uninstall();
+               // fAssistant= null;
+               // }
+               // }
+               // });
+               // }
+               // }
+
+               ITextViewerExtension extension = (ITextViewerExtension) fViewer;
+               extension.removeVerifyKeyListener(this);
+
+               IRewriteTarget target = extension.getRewriteTarget();
+               target.endCompoundChange();
+
+               if (fViewer instanceof ITextViewerExtension2 && fContentType != null)
+                       ((ITextViewerExtension2) fViewer).removeAutoEditStrategy(fManager,
+                                       fContentType);
+               fContentType = null;
+
+               fViewer.removeTextListener(this);
+               fViewer.removeTextInputListener(this);
+
+               try {
+                       IDocument document = fViewer.getDocument();
+
+                       if (((flags & COMMIT) != 0) && ((flags & DOCUMENT_CHANGED) == 0)
+                                       && ((flags & UPDATE_CARET) != 0)) {
+                               Position[] positions = document
+                                               .getPositions(fPositionCategoryName);
+                               if ((positions != null) && (positions.length != 0)) {
+
+                                       if (fViewer instanceof ITextViewerExtension5) {
+                                               ITextViewerExtension5 extension3 = (ITextViewerExtension5) fViewer;
+                                               int widgetOffset = extension3
+                                                               .modelOffset2WidgetOffset(positions[0]
+                                                                               .getOffset());
+                                               if (widgetOffset >= 0)
+                                                       text.setSelection(widgetOffset, widgetOffset);
+
+                                       } else {
+                                               IRegion region = fViewer.getVisibleRegion();
+                                               int offset = positions[0].getOffset()
+                                                               - region.getOffset();
+                                               if ((offset >= 0) && (offset <= region.getLength()))
+                                                       text.setSelection(offset, offset);
+                                       }
+                               }
+                       }
+
+                       document.removePositionUpdater(fUpdater);
+                       document.removePositionCategory(fPositionCategoryName);
+
+                       if (fExitListener != null)
+                               fExitListener.exit(((flags & COMMIT) != 0)
+                                               || ((flags & DOCUMENT_CHANGED) != 0));
+
+               } catch (BadPositionCategoryException e) {
+                       WebUI.log(e);
+                       Assert.isTrue(false);
+               }
+
+               if ((flags & DOCUMENT_CHANGED) == 0)
+                       text.redraw();
+       }
+
+       private void next() {
+               if (!fIsActive)
+                       ;// JavaPlugin.log(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionUI is
+                               // not active: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+
+               redrawRegion();
+
+               if (fFramePosition == fFinalCaretPosition)
+                       fFramePosition = fManager.getFirstPosition();
+               else
+                       fFramePosition = fManager.getNextPosition(fFramePosition
+                                       .getOffset());
+               if (fFramePosition == null) {
+                       if (fFinalCaretPosition != null)
+                               fFramePosition = fFinalCaretPosition;
+                       else
+                               fFramePosition = fManager.getFirstPosition();
+               }
+               if (fFramePosition == null) {
+                       leave(UNINSTALL | COMMIT | UPDATE_CARET);
+               } else {
+                       selectRegion();
+                       // triggerContentAssist();
+                       redrawRegion();
+               }
+       }
+
+       private void previous() {
+               if (!fIsActive)
+                       ;// JavaPlugin.log(new Status(IStatus.WARNING,
+                               // JavaPlugin.getPluginId(), IStatus.OK, "LinkedPositionUI is
+                               // not active: "+fPositionCategoryName, new
+                               // IllegalStateException())); //$NON-NLS-1$
+
+               redrawRegion();
+
+               fFramePosition = fManager.getPreviousPosition(fFramePosition
+                               .getOffset());
+               if (fFramePosition == null) {
+                       if (fFinalCaretPosition != null)
+                               fFramePosition = fFinalCaretPosition;
+                       else
+                               fFramePosition = fManager.getLastPosition();
+               }
+               if (fFramePosition == null) {
+                       leave(UNINSTALL | COMMIT | UPDATE_CARET);
+               } else {
+                       selectRegion();
+                       // triggerContentAssist();
+                       redrawRegion();
+               }
+       }
+
+       /** Trigger content assist on choice positions */
+       // private void triggerContentAssist() {
+       // if (fFramePosition instanceof ProposalPosition) {
+       //
+       // ProposalPosition pp= (ProposalPosition) fFramePosition;
+       // initializeContentAssistant();
+       // if (fAssistant == null)
+       // return;
+       // fAssistant.setCompletions(pp.getChoices());
+       // fAssistant.showPossibleCompletions();
+       // } else {
+       // if (fAssistant != null)
+       // fAssistant.setCompletions(new ICompletionProposal[0]);
+       // }
+       // }
+       /** Lazy initialize content assistant for this linked ui */
+       // private void initializeContentAssistant() {
+       // if (fAssistant != null)
+       // return;
+       // fAssistant= new ContentAssistant2();
+       // fAssistant.setDocumentPartitioning(IJavaPartitions.JAVA_PARTITIONING);
+       // fAssistant.install(fViewer);
+       // }
+       /*
+        * @see VerifyKeyListener#verifyKey(VerifyEvent)
+        */
+       public void verifyKey(VerifyEvent event) {
+
+               if (!event.doit || !fIsActive)
+                       return;
+
+               Point selection = fViewer.getSelectedRange();
+               int offset = selection.x;
+               int length = selection.y;
+
+               ExitFlags exitFlags = fExitPolicy == null ? null : fExitPolicy.doExit(
+                               fManager, event, offset, length);
+               if (exitFlags != null) {
+                       leave(UNINSTALL | exitFlags.flags);
+                       event.doit = exitFlags.doit;
+                       return;
+               }
+
+               switch (event.character) {
+               // [SHIFT-]TAB = hop between edit boxes
+               case 0x09: {
+                       // if tab was treated as a document change, would it exceed variable
+                       // range?
+                       if (!LinkedPositionManager.includes(fFramePosition, offset, length)) {
+                               leave(UNINSTALL | COMMIT);
+                               return;
+                       }
+               }
+
+                       if (event.stateMask == SWT.SHIFT)
+                               previous();
+                       else
+                               next();
+
+                       event.doit = false;
+                       break;
+
+               // ENTER
+               case 0x0A: // Ctrl+Enter
+               case 0x0D: {
+                       // if (fAssistant != null && fAssistant.wasProposalChosen()) {
+                       // next();
+                       // event.doit= false;
+                       // break;
+                       // }
+
+                       // if enter was treated as a document change, would it exceed
+                       // variable range?
+                       if (!LinkedPositionManager.includes(fFramePosition, offset, length)
+                                       || (fFramePosition == fFinalCaretPosition)) {
+                               leave(UNINSTALL | COMMIT);
+                               return;
+                       }
+               }
+
+                       leave(UNINSTALL | COMMIT | UPDATE_CARET);
+                       event.doit = false;
+                       break;
+
+               // ESC
+               case 0x1B:
+                       leave(UNINSTALL | COMMIT);
+                       event.doit = false;
+                       break;
+
+               case ';':
+                       leave(UNINSTALL | COMMIT);
+                       event.doit = true;
+                       break;
+
+               default:
+                       if (event.character != 0) {
+                               if (!controlUndoBehavior(offset, length)
+                                               || fFramePosition == fFinalCaretPosition) {
+                                       leave(UNINSTALL | COMMIT);
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       private boolean controlUndoBehavior(int offset, int length) {
+
+               Position position = fManager.getEmbracingPosition(offset, length);
+               if (position != null) {
+
+                       ITextViewerExtension extension = (ITextViewerExtension) fViewer;
+                       IRewriteTarget target = extension.getRewriteTarget();
+
+                       if (fPreviousPosition != null
+                                       && !fPreviousPosition.equals(position))
+                               target.endCompoundChange();
+                       target.beginCompoundChange();
+               }
+
+               fPreviousPosition = position;
+               return fPreviousPosition != null;
+       }
+
+       /*
+        * @see VerifyListener#verifyText(VerifyEvent)
+        */
+       public void verifyText(VerifyEvent event) {
+               if (!event.doit)
+                       return;
+
+               int offset = 0;
+               int length = 0;
+
+               if (fViewer instanceof ITextViewerExtension5) {
+                       ITextViewerExtension5 extension = (ITextViewerExtension5) fViewer;
+                       IRegion modelRange = extension.widgetRange2ModelRange(new Region(
+                                       event.start, event.end - event.start));
+                       if (modelRange == null)
+                               return;
+
+                       offset = modelRange.getOffset();
+                       length = modelRange.getLength();
+
+               } else {
+                       IRegion visibleRegion = fViewer.getVisibleRegion();
+                       offset = event.start + visibleRegion.getOffset();
+                       length = event.end - event.start;
+               }
+
+               // allow changes only within linked positions when coming through UI
+               if (!fManager.anyPositionIncludes(offset, length))
+                       leave(UNINSTALL | COMMIT);
+       }
+
+       /*
+        * @see PaintListener#paintControl(PaintEvent)
+        */
+       public void paintControl(PaintEvent event) {
+               if (fFramePosition == null)
+                       return;
+
+               IRegion widgetRange = asWidgetRange(fFramePosition);
+               if (widgetRange == null) {
+                       leave(UNINSTALL | COMMIT | DOCUMENT_CHANGED);
+                       return;
+               }
+
+               int offset = widgetRange.getOffset();
+               int length = widgetRange.getLength();
+
+               StyledText text = fViewer.getTextWidget();
+
+               // support for bidi
+               Point minLocation = getMinimumLocation(text, offset, length);
+               Point maxLocation = getMaximumLocation(text, offset, length);
+
+               int x1 = minLocation.x;
+               int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
+               int y = minLocation.y + text.getLineHeight() - 1;
+
+               GC gc = event.gc;
+               gc.setForeground(fFrameColor);
+               gc.drawLine(x1, y, x2, y);
+       }
+
+       protected IRegion asWidgetRange(Position position) {
+               if (fViewer instanceof ITextViewerExtension5) {
+
+                       ITextViewerExtension5 extension = (ITextViewerExtension5) fViewer;
+                       return extension.modelRange2WidgetRange(new Region(position
+                                       .getOffset(), position.getLength()));
+
+               } else {
+
+                       IRegion region = fViewer.getVisibleRegion();
+                       if (includes(region, position))
+                               return new Region(position.getOffset() - region.getOffset(),
+                                               position.getLength());
+               }
+
+               return null;
+       }
+
+       private static Point getMinimumLocation(StyledText text, int offset,
+                       int length) {
+               Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+               for (int i = 0; i <= length; i++) {
+                       Point location = text.getLocationAtOffset(offset + i);
+
+                       if (location.x < minLocation.x)
+                               minLocation.x = location.x;
+                       if (location.y < minLocation.y)
+                               minLocation.y = location.y;
+               }
+
+               return minLocation;
+       }
+
+       private static Point getMaximumLocation(StyledText text, int offset,
+                       int length) {
+               Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
+
+               for (int i = 0; i <= length; i++) {
+                       Point location = text.getLocationAtOffset(offset + i);
+
+                       if (location.x > maxLocation.x)
+                               maxLocation.x = location.x;
+                       if (location.y > maxLocation.y)
+                               maxLocation.y = location.y;
+               }
+
+               return maxLocation;
+       }
+
+       private void redrawRegion() {
+               IRegion widgetRange = asWidgetRange(fFramePosition);
+               if (widgetRange == null) {
+                       leave(UNINSTALL | COMMIT | DOCUMENT_CHANGED);
+                       return;
+               }
+
+               StyledText text = fViewer.getTextWidget();
+               if (text != null && !text.isDisposed())
+                       text.redrawRange(widgetRange.getOffset(), widgetRange.getLength(),
+                                       true);
+       }
+
+       private void selectRegion() {
+
+               IRegion widgetRange = asWidgetRange(fFramePosition);
+               if (widgetRange == null) {
+                       leave(UNINSTALL | COMMIT | DOCUMENT_CHANGED);
+                       return;
+               }
+
+               StyledText text = fViewer.getTextWidget();
+               if (text != null && !text.isDisposed()) {
+                       int start = widgetRange.getOffset();
+                       int end = widgetRange.getLength() + start;
+                       text.setSelection(start, end);
+               }
+       }
+
+       private void updateCaret() {
+
+               IRegion widgetRange = asWidgetRange(fFramePosition);
+               if (widgetRange == null) {
+                       leave(UNINSTALL | COMMIT | DOCUMENT_CHANGED);
+                       return;
+               }
+
+               int offset = widgetRange.getOffset() + fCaretOffset;
+               StyledText text = fViewer.getTextWidget();
+               if (text != null && !text.isDisposed())
+                       text.setCaretOffset(offset);
+       }
+
+       /*
+        * @see ModifyListener#modifyText(ModifyEvent)
+        */
+       public void modifyText(ModifyEvent e) {
+               // reposition caret after StyledText
+               redrawRegion();
+               updateCaret();
+       }
+
+       private static void handleException(Shell shell, Exception e) {
+               String title = LinkedPositionMessages
+                               .getString("LinkedPositionUI.error.title"); //$NON-NLS-1$
+               if (e instanceof CoreException)
+                       ExceptionHandler.handle((CoreException) e, shell, title, null);
+               else if (e instanceof InvocationTargetException)
+                       ExceptionHandler.handle((InvocationTargetException) e, shell,
+                                       title, null);
+               else {
+                       MessageDialog.openError(shell, title, e.getMessage());
+                       WebUI.log(e);
+               }
+       }
+
+       /*
+        * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument,
+        *      IDocument)
+        */
+       public void inputDocumentAboutToBeChanged(IDocument oldInput,
+                       IDocument newInput) {
+               // 5326: leave linked mode on document change
+               int flags = UNINSTALL | COMMIT
+                               | (oldInput.equals(newInput) ? 0 : DOCUMENT_CHANGED);
+               leave(flags);
+       }
+
+       /*
+        * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
+        */
+       public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+       }
+
+       private static boolean includes(IRegion region, Position position) {
+               return position.getOffset() >= region.getOffset()
+                               && position.getOffset() + position.getLength() <= region
+                                               .getOffset()
+                                               + region.getLength();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.ITextListener#textChanged(TextEvent)
+        */
+       public void textChanged(TextEvent event) {
+               if (!fNeedRedraw)
+                       return;
+
+               redrawRegion();
+               fNeedRedraw = false;
+       }
+
+       /*
+        * @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent)
+        */
+       public void shellActivated(ShellEvent event) {
+       }
+
+       /*
+        * @see org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events.ShellEvent)
+        */
+       public void shellClosed(ShellEvent event) {
+               leave(UNINSTALL | COMMIT | DOCUMENT_CHANGED);
+       }
+
+       /*
+        * @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
+        */
+       public void shellDeactivated(ShellEvent event) {
+               // don't deactivate on focus lost, since the proposal popups may take
+               // focus
+               // plus: it doesn't hurt if you can check with another window without
+               // losing linked mode
+               // since there is no intrusive popup sticking out.
+
+               // need to check first what happens on reentering based on an open
+               // action
+               // Seems to be no problem
+
+               // TODO check whether we can leave it or uncomment it after debugging
+               // PS: why DOCUMENT_CHANGED? We want to trigger a redraw! (Shell
+               // deactivated does not mean
+               // it is not visible any longer.
+               // leave(UNINSTALL | COMMIT | DOCUMENT_CHANGED);
+
+               // Better:
+               // Check with content assistant and only leave if its not the proposal
+               // shell that took the
+               // focus away.
+
+               StyledText text;
+               Display display;
+
+               // if (fAssistant == null || fViewer == null || (text=
+               // fViewer.getTextWidget()) == null
+               // || (display= text.getDisplay()) == null || display.isDisposed()) {
+               if (fViewer == null || (text = fViewer.getTextWidget()) == null
+                               || (display = text.getDisplay()) == null
+                               || display.isDisposed()) {
+                       leave(UNINSTALL | COMMIT);
+               } else {
+                       // Post in UI thread since the assistant popup will only get the
+                       // focus after we lose it.
+                       display.asyncExec(new Runnable() {
+                               public void run() {
+                                       // TODO add isDisposed / isUninstalled / hasLeft check? for
+                                       // now: check for content type,
+                                       // since it gets nullified in leave()
+                                       if (fIsActive) {// && (fAssistant == null ||
+                                                                       // !fAssistant.hasFocus())) {
+                                               leave(UNINSTALL | COMMIT);
+                                       }
+                               }
+                       });
+               }
+       }
+
+       /*
+        * @see org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt.events.ShellEvent)
+        */
+       public void shellDeiconified(ShellEvent event) {
+       }
+
+       /*
+        * @see org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events.ShellEvent)
+        */
+       public void shellIconified(ShellEvent event) {
+               leave(UNINSTALL | COMMIT | DOCUMENT_CHANGED);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/ProposalPosition.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/link/ProposalPosition.java
new file mode 100644 (file)
index 0000000..4996443
--- /dev/null
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.link;
+
+import java.util.Arrays;
+
+import org.eclipse.jface.text.TypedPosition;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+
+/**
+ * 
+ */
+public class ProposalPosition extends TypedPosition {
+
+       /**
+        * The choices available for this position, fChoices[0] is the original
+        * type.
+        */
+       private final ICompletionProposal[] fChoices;
+
+       /*
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object o) {
+               if (o instanceof ProposalPosition) {
+                       if (super.equals(o)) {
+                               return Arrays.equals(fChoices, ((ProposalPosition) o).fChoices);
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * @param offset
+        * @param length
+        * @param type
+        */
+       public ProposalPosition(int offset, int length, String type,
+                       ICompletionProposal[] choices) {
+               super(offset, length, type);
+               fChoices = new ICompletionProposal[choices.length];
+               System.arraycopy(choices, 0, fChoices, 0, choices.length);
+       }
+
+       /**
+        * 
+        * @return an array of choices, including the initial one. Clients must not
+        *         modify it.
+        */
+       public ICompletionProposal[] getChoices() {
+               updateChoicePositions();
+               return fChoices;
+       }
+
+       /**
+        * 
+        */
+       private void updateChoicePositions() {
+               for (int i = 0; i < fChoices.length; i++) {
+                       // if (fChoices[i] instanceof JavaCompletionProposal)
+                       // ((JavaCompletionProposal)fChoices[i]).setReplacementOffset(offset);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/IHtmlTagConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/IHtmlTagConstants.java
new file mode 100644 (file)
index 0000000..859d9b3
--- /dev/null
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *****************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.phpdoc;
+
+/**
+ * Html tag constants.
+ * 
+ * @since 3.0
+ */
+public interface IHtmlTagConstants {
+
+       /** Html tag close prefix */
+       public static final String HTML_CLOSE_PREFIX = "</"; //$NON-NLS-1$
+
+       /** Html entity characters */
+       public static final char[] HTML_ENTITY_CHARACTERS = new char[] { '<', '>',
+                       ' ', '&', '^', '~', '\"' };
+
+       /** Html entity codes */
+       public static final String[] HTML_ENTITY_CODES = new String[] {
+                       "&lt;", "&gt;", "&nbsp;", "&amp;", "&circ;", "&tilde;", "&quot;" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+
+       /** Html general tags */
+       public static final String[] HTML_GENERAL_TAGS = new String[] {
+                       "b", "blockquote", "br", "code", "dd", "dl", "dt", "em", "hr", "h1", "h2", "h3", "h4", "h5", "h6", "i", "li", "nl", "ol", "p", "pre", "q", "td", "th", "tr", "tt", "ul" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$ //$NON-NLS-17$ //$NON-NLS-18$ //$NON-NLS-19$ //$NON-NLS-20$ //$NON-NLS-21$ //$NON-NLS-22$ //$NON-NLS-23$ //$NON-NLS-24$ //$NON-NLS-25$ //$NON-NLS-26$ //$NON-NLS-27$
+
+       /** Html tag postfix */
+       public static final char HTML_TAG_POSTFIX = '>';
+
+       /** Html tag prefix */
+       public static final char HTML_TAG_PREFIX = '<';
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/IJavaDocTagConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/IJavaDocTagConstants.java
new file mode 100644 (file)
index 0000000..c815382
--- /dev/null
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *****************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.phpdoc;
+
+/**
+ * Javadoc tag constants.
+ * 
+ * @since 3.0
+ */
+public interface IJavaDocTagConstants {
+
+       /** Javadoc break tags */
+       public static final String[] JAVADOC_BREAK_TAGS = new String[] {
+                       "dd", "dt", "li", "td", "th", "tr", "h1", "h2", "h3", "h4", "h5", "h6", "q" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$
+
+       /** Javadoc single break tag */
+       public static final String[] JAVADOC_SINGLE_BREAK_TAG = new String[] { "br" }; //$NON-NLS-1$
+
+       /** Javadoc code tags */
+       public static final String[] JAVADOC_CODE_TAGS = new String[] { "pre" }; //$NON-NLS-1$
+
+       /** Javadoc general tags */
+       public static final String[] JAVADOC_GENERAL_TAGS = new String[] {
+                       "@author", "@deprecated", "@exception", "@link", "@param", "@return", "@see", "@since", "@throws", "@value", "@version", "@license", "@abstract", "@access", "@category",
+                       "@copyright", "@example", "@final", "@filesource", "@global", "@ignore", "@internal", "@link", "@method", "@name", "@package", "@param", "@property", "@static",
+                       "@staticvar", "@subpackage", "@todo", "@tutorial", "@uses", "@var","@id", "inheritdoc", "@property-read", "@property-write", "@source"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$ //$NON-NLS-17$ //$NON-NLS-18$
+
+       /** Javadoc immutable tags */
+       public static final String[] JAVADOC_IMMUTABLE_TAGS = new String[] {
+                       "code", "em", "pre", "q", "tt" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       /** Javadoc link tags */
+       public static final String[] JAVADOC_LINK_TAGS = new String[] {
+                       "@docRoot", "@inheritDoc", "@link", "@linkplain" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       /** Javadoc new line tags */
+       public static final String[] JAVADOC_NEWLINE_TAGS = new String[] {
+                       "dd", "dt", "li", "td", "th", "tr", "h1", "h2", "h3", "h4", "h5", "h6", "q" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$
+
+       /** Javadoc parameter tags */
+       public static final String[] JAVADOC_PARAM_TAGS = new String[] {
+                       "@exception", "@param", "@serialField", "@throws" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       /** Javadoc reference tags */
+       public static final String[] JAVADOC_REFERENCE_TAGS = new String[] { "@see" }; //$NON-NLS-1$
+
+       /** Javadoc root tags */
+       public static final String[] JAVADOC_ROOT_TAGS = new String[] {
+                       "@author", "@deprecated", "@return", "@see", "@serial", "@serialData", "@since", "@version", "@inheritDoc" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
+
+       /** Javadoc separator tags */
+       public static final String[] JAVADOC_SEPARATOR_TAGS = new String[] {
+                       "dl", "hr", "nl", "p", "pre", "ul", "ol" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+
+       /** Javadoc tag prefix */
+       public static final char JAVADOC_TAG_PREFIX = '@';
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/JavaDocAutoIndentStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/JavaDocAutoIndentStrategy.java
new file mode 100644 (file)
index 0000000..708a7b6
--- /dev/null
@@ -0,0 +1,938 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.phpdoc;
+
+import java.text.BreakIterator;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.internal.corext.util.Strings;
+import net.sourceforge.phpdt.ui.CodeGeneration;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.ui.texteditor.ITextEditorExtension3;
+
+/**
+ * Auto indent strategy for java doc comments
+ */
+public class JavaDocAutoIndentStrategy extends
+               DefaultIndentLineAutoEditStrategy {
+
+       private String fPartitioning;
+
+       /**
+        * Creates a new Javadoc auto indent strategy for the given document
+        * partitioning.
+        * 
+        * @param partitioning
+        *            the document partitioning
+        */
+       public JavaDocAutoIndentStrategy(String partitioning) {
+               fPartitioning = partitioning;
+       }
+
+       private static String getLineDelimiter(IDocument document) {
+               try {
+                       if (document.getNumberOfLines() > 1)
+                               return document.getLineDelimiter(0);
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+               }
+
+               return System.getProperty("line.separator"); //$NON-NLS-1$
+       }
+
+       /**
+        * Copies the indentation of the previous line and add a star. If the
+        * javadoc just started on this line add standard method tags and close the
+        * javadoc.
+        * 
+        * @param d
+        *            the document to work on
+        * @param c
+        *            the command to deal with
+        */
+       private void jdocIndentAfterNewLine(IDocument d, DocumentCommand c) {
+
+               if (c.offset == -1 || d.getLength() == 0)
+                       return;
+
+               try {
+                       // find start of line
+                       int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
+                       IRegion info = d.getLineInformationOfOffset(p);
+                       int start = info.getOffset();
+
+                       // find white spaces
+                       int end = findEndOfWhiteSpace(d, start, c.offset);
+
+                       StringBuffer buf = new StringBuffer(c.text);
+                       if (end >= start) { // 1GEYL1R: ITPJUI:ALL - java doc edit smartness
+                                                               // not work for class comments
+                               // append to input
+                               String indentation = jdocExtractLinePrefix(d, d
+                                               .getLineOfOffset(c.offset));
+                               buf.append(indentation);
+                               if (end < c.offset) {
+                                       if (d.getChar(end) == '/') {
+                                               // javadoc started on this line
+                                               buf.append(" * "); //$NON-NLS-1$
+
+                                               if (WebUI
+                                                               .getDefault()
+                                                               .getPreferenceStore()
+                                                               .getBoolean(
+                                                                               PreferenceConstants.EDITOR_CLOSE_JAVADOCS)
+                                                               && isNewComment(d, c.offset, fPartitioning)) {
+                                                       String lineDelimiter = getLineDelimiter(d);
+
+                                                       String endTag = lineDelimiter + indentation + " */"; //$NON-NLS-1$
+                                                       d.replace(c.offset, 0, endTag); //$NON-NLS-1$
+                                                       // evaluate method signature
+                                                       ICompilationUnit unit = getCompilationUnit();
+
+                                                       // if
+                                                       // (PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS)
+                                                       // &&
+                                                       // unit != null)
+                                                       // {
+                                                       // try {
+                                                       // JavaModelUtil.reconcile(unit);
+                                                       // String string= createJavaDocTags(d, c,
+                                                       // indentation, lineDelimiter, unit);
+                                                       // if (string != null) {
+                                                       // d.replace(c.offset, 0, string);
+                                                       // }
+                                                       // } catch (CoreException e) {
+                                                       // // ignore
+                                                       // }
+                                                       // }
+                                               }
+
+                                       }
+                               }
+                       }
+
+                       c.text = buf.toString();
+
+               } catch (BadLocationException excp) {
+                       // stop work
+               }
+       }
+
+       private String createJavaDocTags(IDocument document,
+                       DocumentCommand command, String indentation, String lineDelimiter,
+                       ICompilationUnit unit) throws CoreException, BadLocationException {
+               IJavaElement element = unit.getElementAt(command.offset);
+               if (element == null)
+                       return null;
+
+               switch (element.getElementType()) {
+               case IJavaElement.TYPE:
+                       return createTypeTags(document, command, indentation,
+                                       lineDelimiter, (IType) element);
+
+               case IJavaElement.METHOD:
+                       return createMethodTags(document, command, indentation,
+                                       lineDelimiter, (IMethod) element);
+
+               default:
+                       return null;
+               }
+       }
+
+       /*
+        * Removes start and end of a comment and corrects indentation and line
+        * delimiters.
+        */
+       private String prepareTemplateComment(String comment, String indentation,
+                       String lineDelimiter) {
+               // trim comment start and end if any
+               if (comment.endsWith("*/")) //$NON-NLS-1$
+                       comment = comment.substring(0, comment.length() - 2);
+               comment = comment.trim();
+               if (comment.startsWith("/*")) { //$NON-NLS-1$
+                       if (comment.length() > 2 && comment.charAt(2) == '*') {
+                               comment = comment.substring(3); // remove '/**'
+                       } else {
+                               comment = comment.substring(2); // remove '/*'
+                       }
+               }
+               // return Strings.changeIndent(comment, 0,
+               // CodeFormatterUtil.getTabWidth(), indentation, lineDelimiter);
+               return Strings.changeIndent(comment, 0, getTabWidth(), indentation,
+                               lineDelimiter);
+       }
+
+       public static int getTabWidth() {
+               Preferences preferences = WebUI.getDefault()
+                               .getPluginPreferences();
+               return preferences
+                               .getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+       }
+
+       private String createTypeTags(IDocument document, DocumentCommand command,
+                       String indentation, String lineDelimiter, IType type)
+                       throws CoreException {
+               String comment = CodeGeneration.getTypeComment(type
+                               .getCompilationUnit(), type.getTypeQualifiedName('.'),
+                               lineDelimiter);
+               if (comment != null) {
+                       return prepareTemplateComment(comment.trim(), indentation,
+                                       lineDelimiter);
+               }
+               return null;
+       }
+
+       private String createMethodTags(IDocument document,
+                       DocumentCommand command, String indentation, String lineDelimiter,
+                       IMethod method) throws CoreException, BadLocationException {
+               IRegion partition = TextUtilities.getPartition(document, fPartitioning,
+                               command.offset, false);
+               ISourceRange sourceRange = method.getSourceRange();
+               if (sourceRange == null
+                               || sourceRange.getOffset() != partition.getOffset())
+                       return null;
+
+               // IMethod inheritedMethod= getInheritedMethod(method);
+               // String comment= CodeGeneration.getMethodComment(method,
+               // inheritedMethod, lineDelimiter);
+               // if (comment != null) {
+               // comment= comment.trim();
+               // boolean javadocComment= comment.startsWith("/**"); //$NON-NLS-1$
+               // boolean isJavaDoc= partition.getLength() >= 3 &&
+               // document.get(partition.getOffset(), 3).equals("/**"); //$NON-NLS-1$
+               // if (javadocComment == isJavaDoc) {
+               // return prepareTemplateComment(comment, indentation, lineDelimiter);
+               // }
+               // }
+               return null;
+       }
+
+       /**
+        * Returns the method inherited from, <code>null</code> if method is newly
+        * defined.
+        */
+       // private static IMethod getInheritedMethod(IMethod method) throws
+       // JavaModelException {
+       // IType declaringType= method.getDeclaringType();
+       // ITypeHierarchy typeHierarchy=
+       // SuperTypeHierarchyCache.getTypeHierarchy(declaringType);
+       // return JavaModelUtil.findMethodDeclarationInHierarchy(typeHierarchy,
+       // declaringType,
+       // method.getElementName(), method.getParameterTypes(),
+       // method.isConstructor());
+       // }
+       protected void jdocIndentForCommentEnd(IDocument d, DocumentCommand c) {
+               if (c.offset < 2 || d.getLength() == 0) {
+                       return;
+               }
+               try {
+                       if ("* ".equals(d.get(c.offset - 2, 2))) { //$NON-NLS-1$
+                               // modify document command
+                               c.length++;
+                               c.offset--;
+                       }
+               } catch (BadLocationException excp) {
+                       // stop work
+               }
+       }
+
+       /**
+        * Guesses if the command operates within a newly created javadoc comment or
+        * not. If in doubt, it will assume that the javadoc is new.
+        */
+       private static boolean isNewComment(IDocument document, int commandOffset,
+                       String partitioning) {
+
+               try {
+                       int lineIndex = document.getLineOfOffset(commandOffset) + 1;
+                       if (lineIndex >= document.getNumberOfLines())
+                               return true;
+
+                       IRegion line = document.getLineInformation(lineIndex);
+                       ITypedRegion partition = TextUtilities.getPartition(document,
+                                       partitioning, commandOffset, false);
+                       int partitionEnd = partition.getOffset() + partition.getLength();
+                       if (line.getOffset() >= partitionEnd)
+                               return false;
+
+                       if (document.getLength() == partitionEnd)
+                               return true; // partition goes to end of document - probably
+                                                               // a new comment
+
+                       String comment = document.get(partition.getOffset(), partition
+                                       .getLength());
+                       if (comment.indexOf("/*", 2) != -1) //$NON-NLS-1$
+                               return true; // enclosed another comment -> probably a new
+                                                               // comment
+
+                       return false;
+
+               } catch (BadLocationException e) {
+                       return false;
+               }
+       }
+
+       private boolean isSmartMode() {
+               IWorkbenchPage page = WebUI.getActivePage();
+               if (page != null) {
+                       IEditorPart part = page.getActiveEditor();
+                       if (part instanceof ITextEditorExtension3) {
+                               ITextEditorExtension3 extension = (ITextEditorExtension3) part;
+                               return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
+                       }
+               }
+               return false;
+       }
+
+       /*
+        * @see IAutoIndentStrategy#customizeDocumentCommand
+        */
+       public void customizeDocumentCommand(IDocument document,
+                       DocumentCommand command) {
+
+               if (!isSmartMode())
+                       return;
+
+               try {
+
+                       if (command.text != null && command.length == 0) {
+                               String[] lineDelimiters = document.getLegalLineDelimiters();
+                               int index = TextUtilities
+                                               .endsWith(lineDelimiters, command.text);
+                               if (index > -1) {
+                                       // ends with line delimiter
+                                       if (lineDelimiters[index].equals(command.text))
+                                               // just the line delimiter
+                                               jdocIndentAfterNewLine(document, command);
+                                       return;
+                               }
+                       }
+
+                       if (command.text != null && command.text.equals("/")) { //$NON-NLS-1$
+                               jdocIndentForCommentEnd(document, command);
+                               return;
+                       }
+
+                       ITypedRegion partition = TextUtilities.getPartition(document,
+                                       fPartitioning, command.offset, true);
+                       int partitionStart = partition.getOffset();
+                       int partitionEnd = partition.getLength() + partitionStart;
+
+                       String text = command.text;
+                       int offset = command.offset;
+                       int length = command.length;
+
+                       // partition change
+                       final int PREFIX_LENGTH = "/*".length(); //$NON-NLS-1$
+                       final int POSTFIX_LENGTH = "*/".length(); //$NON-NLS-1$
+                       if ((offset < partitionStart + PREFIX_LENGTH || offset + length > partitionEnd
+                                       - POSTFIX_LENGTH)
+                                       || text != null
+                                       && text.length() >= 2
+                                       && ((text.indexOf("*/") != -1) || (document.getChar(offset) == '*' && text.startsWith("/")))) //$NON-NLS-1$ //$NON-NLS-2$
+                               return;
+
+                       if (command.text == null || command.text.length() == 0)
+                               jdocHandleBackspaceDelete(document, command);
+
+                       else if (command.text != null && command.length == 0
+                                       && command.text.length() > 0)
+                               jdocWrapParagraphOnInsert(document, command);
+
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+               }
+       }
+
+       private void flushCommand(IDocument document, DocumentCommand command)
+                       throws BadLocationException {
+
+               if (!command.doit)
+                       return;
+
+               document.replace(command.offset, command.length, command.text);
+
+               command.doit = false;
+               if (command.text != null)
+                       command.offset += command.text.length();
+               command.length = 0;
+               command.text = null;
+       }
+
+       protected void jdocWrapParagraphOnInsert(IDocument document,
+                       DocumentCommand command) throws BadLocationException {
+
+               // Assert.isTrue(command.length == 0);
+               // Assert.isTrue(command.text != null && command.text.length() == 1);
+
+               if (!getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_FORMAT_JAVADOCS))
+                       return;
+
+               int line = document.getLineOfOffset(command.offset);
+               IRegion region = document.getLineInformation(line);
+               int lineOffset = region.getOffset();
+               int lineLength = region.getLength();
+
+               String lineContents = document.get(lineOffset, lineLength);
+               StringBuffer buffer = new StringBuffer(lineContents);
+               int start = command.offset - lineOffset;
+               int end = command.length + start;
+               buffer.replace(start, end, command.text);
+
+               // handle whitespace
+               if (command.text != null && command.text.length() != 0
+                               && command.text.trim().length() == 0) {
+
+                       String endOfLine = document.get(command.offset, lineOffset
+                                       + lineLength - command.offset);
+
+                       // end of line
+                       if (endOfLine.length() == 0) {
+                               // move caret to next line
+                               flushCommand(document, command);
+
+                               if (isLineTooShort(document, line)) {
+                                       int[] caretOffset = { command.offset };
+                                       jdocWrapParagraphFromLine(document, line, caretOffset,
+                                                       false);
+                                       command.offset = caretOffset[0];
+                                       return;
+                               }
+
+                               // move caret to next line if possible
+                               if (line < document.getNumberOfLines() - 1
+                                               && isJavaDocLine(document, line + 1)) {
+                                       String lineDelimiter = document.getLineDelimiter(line);
+                                       String nextLinePrefix = jdocExtractLinePrefix(document,
+                                                       line + 1);
+                                       command.offset += lineDelimiter.length()
+                                                       + nextLinePrefix.length();
+                               }
+                               return;
+
+                               // inside whitespace at end of line
+                       } else if (endOfLine.trim().length() == 0) {
+                               // simply insert space
+                               return;
+                       }
+               }
+
+               // change in prefix region
+               String prefix = jdocExtractLinePrefix(document, line);
+               boolean wrapAlways = command.offset >= lineOffset
+                               && command.offset <= lineOffset + prefix.length();
+
+               // must insert the text now because it may include whitepace
+               flushCommand(document, command);
+
+               if (wrapAlways
+                               || calculateDisplayedWidth(buffer.toString()) > getMargin()
+                               || isLineTooShort(document, line)) {
+                       int[] caretOffset = { command.offset };
+                       jdocWrapParagraphFromLine(document, line, caretOffset, wrapAlways);
+
+                       if (!wrapAlways)
+                               command.offset = caretOffset[0];
+               }
+       }
+
+       /**
+        * Method jdocWrapParagraphFromLine.
+        * 
+        * @param document
+        * @param line
+        * @param always
+        */
+       private void jdocWrapParagraphFromLine(IDocument document, int line,
+                       int[] caretOffset, boolean always) throws BadLocationException {
+
+               String indent = jdocExtractLinePrefix(document, line);
+               if (!always) {
+                       if (!indent.trim().startsWith("*")) //$NON-NLS-1$
+                               return;
+
+                       if (indent.trim().startsWith("*/")) //$NON-NLS-1$
+                               return;
+
+                       if (!isLineTooLong(document, line)
+                                       && !isLineTooShort(document, line))
+                               return;
+               }
+
+               boolean caretRelativeToParagraphOffset = false;
+               int caret = caretOffset[0];
+
+               int caretLine = document.getLineOfOffset(caret);
+               int lineOffset = document.getLineOffset(line);
+               int paragraphOffset = lineOffset + indent.length();
+               if (paragraphOffset < caret) {
+                       caret -= paragraphOffset;
+                       caretRelativeToParagraphOffset = true;
+               } else {
+                       caret -= lineOffset;
+               }
+
+               StringBuffer buffer = new StringBuffer();
+               int currentLine = line;
+               while (line == currentLine || isJavaDocLine(document, currentLine)) {
+
+                       if (buffer.length() != 0
+                                       && !Character.isWhitespace(buffer
+                                                       .charAt(buffer.length() - 1))) {
+                               buffer.append(' ');
+                               if (currentLine <= caretLine) {
+                                       // in this case caretRelativeToParagraphOffset is always
+                                       // true
+                                       ++caret;
+                               }
+                       }
+
+                       String string = getLineContents(document, currentLine);
+                       buffer.append(string);
+                       currentLine++;
+               }
+               String paragraph = buffer.toString();
+
+               if (paragraph.trim().length() == 0)
+                       return;
+
+               caretOffset[0] = caretRelativeToParagraphOffset ? caret : 0;
+               String delimiter = document.getLineDelimiter(0);
+               String wrapped = formatParagraph(paragraph, caretOffset, indent,
+                               delimiter, getMargin());
+
+               int beginning = document.getLineOffset(line);
+               int end = document.getLineOffset(currentLine);
+               document.replace(beginning, end - beginning, wrapped.toString());
+
+               caretOffset[0] = caretRelativeToParagraphOffset ? caretOffset[0]
+                               + beginning : caret + beginning;
+       }
+
+       /**
+        * Line break iterator to handle whitespaces as first class citizens.
+        */
+       private static class LineBreakIterator {
+
+               private final String fString;
+
+               private final BreakIterator fIterator = BreakIterator.getLineInstance();
+
+               private int fStart;
+
+               private int fEnd;
+
+               private int fBufferedEnd;
+
+               public LineBreakIterator(String string) {
+                       fString = string;
+                       fIterator.setText(string);
+               }
+
+               public int first() {
+                       fBufferedEnd = -1;
+                       fStart = fIterator.first();
+                       return fStart;
+               }
+
+               public int next() {
+
+                       if (fBufferedEnd != -1) {
+                               fStart = fEnd;
+                               fEnd = fBufferedEnd;
+                               fBufferedEnd = -1;
+                               return fEnd;
+                       }
+
+                       fStart = fEnd;
+                       fEnd = fIterator.next();
+
+                       if (fEnd == BreakIterator.DONE)
+                               return fEnd;
+
+                       final String string = fString.substring(fStart, fEnd);
+
+                       // whitespace
+                       if (string.trim().length() == 0)
+                               return fEnd;
+
+                       final String word = string.trim();
+                       if (word.length() == string.length())
+                               return fEnd;
+
+                       // suspected whitespace
+                       fBufferedEnd = fEnd;
+                       return fStart + word.length();
+               }
+       }
+
+       /**
+        * Formats a paragraph, using break iterator.
+        * 
+        * @param offset
+        *            an offset within the paragraph, which will be updated with
+        *            respect to formatting.
+        */
+       private static String formatParagraph(String paragraph, int[] offset,
+                       String prefix, String lineDelimiter, int margin) {
+
+               LineBreakIterator iterator = new LineBreakIterator(paragraph);
+
+               StringBuffer paragraphBuffer = new StringBuffer();
+               StringBuffer lineBuffer = new StringBuffer();
+               StringBuffer whiteSpaceBuffer = new StringBuffer();
+
+               int index = offset[0];
+               int indexBuffer = -1;
+
+               // line delimiter could be null
+               if (lineDelimiter == null)
+                       lineDelimiter = ""; //$NON-NLS-1$
+
+               for (int start = iterator.first(), end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator
+                               .next()) {
+
+                       String word = paragraph.substring(start, end);
+
+                       // word is whitespace
+                       if (word.trim().length() == 0) {
+                               whiteSpaceBuffer.append(word);
+
+                               // first word of line is always appended
+                       } else if (lineBuffer.length() == 0) {
+                               lineBuffer.append(prefix);
+                               lineBuffer.append(whiteSpaceBuffer.toString());
+                               lineBuffer.append(word);
+
+                       } else {
+                               String line = lineBuffer.toString()
+                                               + whiteSpaceBuffer.toString() + word.toString();
+
+                               // margin exceeded
+                               if (calculateDisplayedWidth(line) > margin) {
+                                       // flush line buffer and wrap paragraph
+                                       paragraphBuffer.append(lineBuffer.toString());
+                                       paragraphBuffer.append(lineDelimiter);
+                                       lineBuffer.setLength(0);
+                                       lineBuffer.append(prefix);
+                                       lineBuffer.append(word);
+
+                                       // flush index buffer
+                                       if (indexBuffer != -1) {
+                                               offset[0] = indexBuffer;
+                                               // correct for caret in whitespace at the end of line
+                                               if (whiteSpaceBuffer.length() != 0 && index < start
+                                                               && index >= start - whiteSpaceBuffer.length())
+                                                       offset[0] -= (index - (start - whiteSpaceBuffer
+                                                                       .length()));
+                                               indexBuffer = -1;
+                                       }
+
+                                       whiteSpaceBuffer.setLength(0);
+
+                                       // margin not exceeded
+                               } else {
+                                       lineBuffer.append(whiteSpaceBuffer.toString());
+                                       lineBuffer.append(word);
+                                       whiteSpaceBuffer.setLength(0);
+                               }
+                       }
+
+                       if (index >= start && index < end) {
+                               indexBuffer = paragraphBuffer.length() + lineBuffer.length()
+                                               + (index - start);
+                               if (word.trim().length() != 0)
+                                       indexBuffer -= word.length();
+                       }
+               }
+
+               // flush line buffer
+               paragraphBuffer.append(lineBuffer.toString());
+               paragraphBuffer.append(lineDelimiter);
+
+               // flush index buffer
+               if (indexBuffer != -1)
+                       offset[0] = indexBuffer;
+
+               // last position is not returned by break iterator
+               else if (offset[0] == paragraph.length())
+                       offset[0] = paragraphBuffer.length() - lineDelimiter.length();
+
+               return paragraphBuffer.toString();
+       }
+
+       private static IPreferenceStore getPreferenceStore() {
+               return WebUI.getDefault().getPreferenceStore();
+       }
+
+       /**
+        * Returns the displayed width of a string, taking in account the displayed
+        * tab width. The result can be compared against the print margin.
+        */
+       private static int calculateDisplayedWidth(String string) {
+
+               int tabWidth = getPreferenceStore()
+                               .getInt(
+                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+               if (tabWidth <= 0) {
+                       tabWidth = 2;
+               }
+               int column = 0;
+               for (int i = 0; i < string.length(); i++)
+                       if ('\t' == string.charAt(i))
+                               column += tabWidth - (column % tabWidth);
+                       else
+                               column++;
+
+               return column;
+       }
+
+       private String jdocExtractLinePrefix(IDocument d, int line)
+                       throws BadLocationException {
+
+               IRegion region = d.getLineInformation(line);
+               int lineOffset = region.getOffset();
+               int index = findEndOfWhiteSpace(d, lineOffset, lineOffset
+                               + d.getLineLength(line));
+               if (d.getChar(index) == '*') {
+                       index++;
+                       if (index != lineOffset + region.getLength()
+                                       && d.getChar(index) == ' ')
+                               index++;
+               }
+               return d.get(lineOffset, index - lineOffset);
+       }
+
+       private String getLineContents(IDocument d, int line)
+                       throws BadLocationException {
+               int offset = d.getLineOffset(line);
+               int length = d.getLineLength(line);
+               String lineDelimiter = d.getLineDelimiter(line);
+               if (lineDelimiter != null)
+                       length = length - lineDelimiter.length();
+               String lineContents = d.get(offset, length);
+               int trim = jdocExtractLinePrefix(d, line).length();
+               return lineContents.substring(trim);
+       }
+
+       private static String getLine(IDocument document, int line)
+                       throws BadLocationException {
+               IRegion region = document.getLineInformation(line);
+               return document.get(region.getOffset(), region.getLength());
+       }
+
+       /**
+        * Returns <code>true</code> if the javadoc line is too short,
+        * <code>false</code> otherwise.
+        */
+       private boolean isLineTooShort(IDocument document, int line)
+                       throws BadLocationException {
+
+               if (!isJavaDocLine(document, line + 1))
+                       return false;
+
+               String nextLine = getLineContents(document, line + 1);
+               if (nextLine.trim().length() == 0)
+                       return false;
+
+               return true;
+       }
+
+       /**
+        * Returns <code>true</code> if the line is too long, <code>false</code>
+        * otherwise.
+        */
+       private boolean isLineTooLong(IDocument document, int line)
+                       throws BadLocationException {
+               String lineContents = getLine(document, line);
+               return calculateDisplayedWidth(lineContents) > getMargin();
+       }
+
+       private static int getMargin() {
+               return getPreferenceStore()
+                               .getInt(
+                                               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN);
+       }
+
+       private static final String[] fgInlineTags = {
+                       "<b>", "<i>", "<em>", "<strong>", "<code>" //$NON-NLS-1$  //$NON-NLS-2$  //$NON-NLS-3$  //$NON-NLS-4$ //$NON-NLS-5$
+       };
+
+       private boolean isInlineTag(String string) {
+               for (int i = 0; i < fgInlineTags.length; i++)
+                       if (string.startsWith(fgInlineTags[i]))
+                               return true;
+               return false;
+       }
+
+       /**
+        * returns true if the specified line is part of a paragraph and should be
+        * merged with the previous line.
+        */
+       private boolean isJavaDocLine(IDocument document, int line)
+                       throws BadLocationException {
+
+               if (document.getNumberOfLines() < line)
+                       return false;
+
+               int offset = document.getLineOffset(line);
+               int length = document.getLineLength(line);
+               int firstChar = findEndOfWhiteSpace(document, offset, offset + length);
+               length -= firstChar - offset;
+               String lineContents = document.get(firstChar, length);
+
+               String prefix = lineContents.trim();
+               if (!prefix.startsWith("*") || prefix.startsWith("*/")) //$NON-NLS-1$ //$NON-NLS-2$
+                       return false;
+
+               lineContents = lineContents.substring(1).trim().toLowerCase();
+
+               // preserve empty lines
+               if (lineContents.length() == 0)
+                       return false;
+
+               // preserve @TAGS
+               if (lineContents.startsWith("@")) //$NON-NLS-1$
+                       return false;
+
+               // preserve HTML tags which are not inline
+               if (lineContents.startsWith("<") && !isInlineTag(lineContents)) //$NON-NLS-1$
+                       return false;
+
+               return true;
+       }
+
+       protected void jdocHandleBackspaceDelete(IDocument document,
+                       DocumentCommand c) {
+
+               if (!getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_FORMAT_JAVADOCS))
+                       return;
+
+               try {
+                       String text = document.get(c.offset, c.length);
+                       int line = document.getLineOfOffset(c.offset);
+                       int lineOffset = document.getLineOffset(line);
+
+                       // erase line delimiter
+                       String lineDelimiter = document.getLineDelimiter(line);
+                       if (lineDelimiter != null && lineDelimiter.equals(text)) {
+
+                               String prefix = jdocExtractLinePrefix(document, line + 1);
+
+                               // strip prefix if any
+                               if (prefix.length() > 0) {
+                                       int length = document.getLineDelimiter(line).length()
+                                                       + prefix.length();
+                                       document.replace(c.offset, length, null);
+
+                                       c.doit = false;
+                                       c.length = 0;
+                                       return;
+                               }
+
+                               // backspace: beginning of a javadoc line
+                       } else if (document.getChar(c.offset - 1) == '*'
+                                       && jdocExtractLinePrefix(document, line).length() - 1 >= c.offset
+                                                       - lineOffset) {
+
+                               lineDelimiter = document.getLineDelimiter(line - 1);
+                               String prefix = jdocExtractLinePrefix(document, line);
+                               int length = (lineDelimiter != null ? lineDelimiter.length()
+                                               : 0)
+                                               + prefix.length();
+                               document.replace(c.offset - length + 1, length, null);
+
+                               c.doit = false;
+                               c.offset -= length - 1;
+                               c.length = 0;
+                               return;
+
+                       } else {
+                               document.replace(c.offset, c.length, null);
+                               c.doit = false;
+                               c.length = 0;
+                       }
+
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+               }
+
+               try {
+                       int line = document.getLineOfOffset(c.offset);
+                       int lineOffset = document.getLineOffset(line);
+                       String prefix = jdocExtractLinePrefix(document, line);
+                       boolean always = c.offset > lineOffset
+                                       && c.offset <= lineOffset + prefix.length();
+                       int[] caretOffset = { c.offset };
+                       jdocWrapParagraphFromLine(document, document
+                                       .getLineOfOffset(c.offset), caretOffset, always);
+                       c.offset = caretOffset[0];
+
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+               }
+       }
+
+       /**
+        * Returns the compilation unit of the CompilationUnitEditor invoking the
+        * AutoIndentStrategy, might return <code>null</code> on error.
+        */
+       private static ICompilationUnit getCompilationUnit() {
+
+               IWorkbenchWindow window = PlatformUI.getWorkbench()
+                               .getActiveWorkbenchWindow();
+               if (window == null)
+                       return null;
+
+               IWorkbenchPage page = window.getActivePage();
+               if (page == null)
+                       return null;
+
+               IEditorPart editor = page.getActiveEditor();
+               if (editor == null)
+                       return null;
+
+               IWorkingCopyManager manager = WebUI.getDefault()
+                               .getWorkingCopyManager();
+               ICompilationUnit unit = manager.getWorkingCopy(editor.getEditorInput());
+               if (unit == null)
+                       return null;
+
+               return unit;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCodeScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCodeScanner.java
new file mode 100644 (file)
index 0000000..4e10a0c
--- /dev/null
@@ -0,0 +1,179 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.phpdoc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * A rule based PHPDoc scanner.
+ */
+public final class PHPDocCodeScanner extends AbstractJavaScanner {
+
+       /**
+        * A key word detector.
+        */
+       static class JavaDocKeywordDetector implements IWordDetector {
+
+               /**
+                * @see IWordDetector#isWordStart
+                */
+               public boolean isWordStart(char c) {
+                       return (c == '@');
+               }
+
+               /**
+                * @see IWordDetector#isWordPart
+                */
+               public boolean isWordPart(char c) {
+                       return Character.isLetter(c);
+               }
+       };
+
+       /**
+        * Detector for HTML comment delimiters.
+        */
+       static class HTMLCommentDetector implements IWordDetector {
+
+               /**
+                * @see IWordDetector#isWordStart
+                */
+               public boolean isWordStart(char c) {
+                       return (c == '<' || c == '-');
+               }
+
+               /**
+                * @see IWordDetector#isWordPart
+                */
+               public boolean isWordPart(char c) {
+                       return (c == '-' || c == '!' || c == '>');
+               }
+       };
+
+       class TagRule extends SingleLineRule {
+
+               /*
+                * @see SingleLineRule
+                */
+               public TagRule(IToken token) {
+                       super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$
+               }
+
+               /*
+                * @see SingleLineRule
+                */
+               public TagRule(IToken token, char escapeCharacter) {
+                       super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$
+               }
+
+               private IToken checkForWhitespace(ICharacterScanner scanner) {
+
+                       try {
+
+                               char c = getDocument().getChar(getTokenOffset() + 1);
+                               if (!Character.isWhitespace(c))
+                                       return fToken;
+
+                       } catch (BadLocationException x) {
+                       }
+
+                       return Token.UNDEFINED;
+               }
+
+               /*
+                * @see PatternRule#evaluate(ICharacterScanner)
+                */
+               public IToken evaluate(ICharacterScanner scanner) {
+                       IToken result = super.evaluate(scanner);
+                       if (result == fToken)
+                               return checkForWhitespace(scanner);
+                       return result;
+               }
+       };
+
+       private static String[] fgKeywords = {"@author", "@deprecated", "@exception", "@link", "@param", "@return", "@see", "@since", "@throws", "@value", "@version", "@license", "@abstract", "@access", "@category",
+               "@copyright", "@example", "@final", "@filesource", "@global", "@ignore", "@internal", "@link", "@method", "@name", "@package", "@param", "@property", "@static",
+               "@staticvar", "@subpackage", "@todo", "@tutorial", "@uses", "@var","@id", "inheritdoc", "@property-read", "@property-write", "@source" }; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+       private static String[] fgTokenProperties = {
+                       IPreferenceConstants.PHPDOC_KEYWORD,
+                       IPreferenceConstants.PHPDOC_TAG, IPreferenceConstants.PHPDOC_LINK,
+                       IPreferenceConstants.PHPDOC_DEFAULT };
+
+       public PHPDocCodeScanner(IColorManager manager, IPreferenceStore store) {
+               super(manager, store);
+               initialize();
+       }
+
+       public IDocument getDocument() {
+               return fDocument;
+       }
+
+       /*
+        * @see AbstractJavaScanner#getTokenProperties()
+        */
+       protected String[] getTokenProperties() {
+               return fgTokenProperties;
+       }
+
+       /*
+        * @see AbstractJavaScanner#createRules()
+        */
+       protected List createRules() {
+
+               List list = new ArrayList();
+
+               // Add rule for tags.
+               Token token = getToken(IPreferenceConstants.PHPDOC_TAG);
+               list.add(new TagRule(token));
+
+               // Add rule for HTML comments
+               WordRule wordRule = new WordRule(new HTMLCommentDetector(), token);
+               wordRule.addWord("<!--", token); //$NON-NLS-1$
+               wordRule.addWord("--!>", token); //$NON-NLS-1$
+               list.add(wordRule);
+
+               // Add rule for links.
+               token = getToken(IPreferenceConstants.PHPDOC_LINK);
+               list.add(new SingleLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+
+               // Add generic whitespace rule.
+               list.add(new WhitespaceRule(new PHPWhitespaceDetector()));
+
+               // Add word rule for keywords.
+               token = getToken(IPreferenceConstants.PHPDOC_DEFAULT);
+               wordRule = new WordRule(new JavaDocKeywordDetector(), token);
+
+               token = getToken(IPreferenceConstants.PHPDOC_KEYWORD);
+               for (int i = 0; i < fgKeywords.length; i++)
+                       wordRule.addWord(fgKeywords[i], token);
+               list.add(wordRule);
+
+               setDefaultReturnToken(getToken(IPreferenceConstants.PHPDOC_DEFAULT));
+               return list;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCompletionProcessor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCompletionProcessor.java
new file mode 100644 (file)
index 0000000..8053a3a
--- /dev/null
@@ -0,0 +1,209 @@
+package net.sourceforge.phpdt.internal.ui.text.phpdoc;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpdt.internal.ui.text.java.PHPCompletionProposalComparator;
+import net.sourceforge.phpdt.internal.ui.text.template.contentassist.TemplateEngine;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.IDocument;
+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;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Simple PHPDoc completion processor.
+ */
+public class PHPDocCompletionProcessor implements IContentAssistProcessor {
+
+       private static class PHPDocCompletionProposalComparator implements
+                       Comparator {
+               public int compare(Object o1, Object o2) {
+                       ICompletionProposal c1 = (ICompletionProposal) o1;
+                       ICompletionProposal c2 = (ICompletionProposal) o2;
+                       return c1.getDisplayString().compareTo(c2.getDisplayString());
+               }
+       };
+
+       // private IEditorPart fEditor;
+       // private IWorkingCopyManager fManager;
+       private char[] fProposalAutoActivationSet;
+
+       private PHPCompletionProposalComparator fComparator;
+
+       private TemplateEngine fTemplateEngine;
+
+       private boolean fRestrictToMatchingCase;
+
+       private IEditorPart fEditor;
+
+       protected IWorkingCopyManager fManager;
+
+       public PHPDocCompletionProcessor(IEditorPart editor) {
+               fEditor = editor;
+               fManager = WebUI.getDefault().getWorkingCopyManager();
+
+               // fEditor= editor;
+               // fManager= JavaPlugin.getDefault().getWorkingCopyManager();
+               TemplateContextType contextType = WebUI.getDefault()
+                               .getTemplateContextRegistry().getContextType("phpdoc"); //$NON-NLS-1$
+               if (contextType != null)
+                       fTemplateEngine = new TemplateEngine(contextType);
+               fRestrictToMatchingCase = false;
+
+               fComparator = new PHPCompletionProposalComparator();
+       }
+
+       /**
+        * Tells this processor to order the proposals alphabetically.
+        * 
+        * @param order
+        *            <code>true</code> if proposals should be ordered.
+        */
+       public void orderProposalsAlphabetically(boolean order) {
+               fComparator.setOrderAlphabetically(order);
+       }
+
+       /**
+        * Tells this processor to restrict is proposals to those starting with
+        * matching cases.
+        * 
+        * @param restrict
+        *            <code>true</code> if proposals should be restricted
+        */
+       public void restrictProposalsToMatchingCases(boolean restrict) {
+               fRestrictToMatchingCase = restrict;
+       }
+
+       /**
+        * @see IContentAssistProcessor#getErrorMessage()
+        */
+       public String getErrorMessage() {
+               return null;
+       }
+
+       /**
+        * @see IContentAssistProcessor#getContextInformationValidator()
+        */
+       public IContextInformationValidator getContextInformationValidator() {
+               return null;
+       }
+
+       /**
+        * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+        */
+       public char[] getContextInformationAutoActivationCharacters() {
+               return null;
+       }
+
+       /**
+        * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+        */
+       public char[] getCompletionProposalAutoActivationCharacters() {
+               return fProposalAutoActivationSet;
+       }
+
+       /**
+        * Sets this processor's set of characters triggering the activation of the
+        * completion proposal computation.
+        * 
+        * @param activationSet
+        *            the activation set
+        */
+       public void setCompletionProposalAutoActivationCharacters(
+                       char[] activationSet) {
+               fProposalAutoActivationSet = activationSet;
+       }
+
+       /**
+        * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+        */
+       public IContextInformation[] computeContextInformation(ITextViewer viewer,
+                       int offset) {
+               return null;
+       }
+
+       /**
+        * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
+        */
+       public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
+                       int documentOffset) {
+               ICompilationUnit unit = fManager.getWorkingCopy(fEditor
+                               .getEditorInput());
+               IDocument document = viewer.getDocument();
+
+               IPHPCompletionProposal[] results = new IPHPCompletionProposal[0];
+
+               // try {
+               // if (unit != null) {
+               //                              
+               // int offset= documentOffset;
+               // int length= 0;
+               //                              
+               // Point selection= viewer.getSelectedRange();
+               // if (selection.y > 0) {
+               // offset= selection.x;
+               // length= selection.y;
+               // }
+               //                              
+               // JavaDocCompletionEvaluator evaluator= new
+               // JavaDocCompletionEvaluator(unit, document, offset, length);
+               // evaluator.restrictProposalsToMatchingCases(fRestrictToMatchingCase);
+               // results= evaluator.computeProposals();
+               // }
+               // } catch (JavaModelException e) {
+               // JavaPlugin.log(e);
+               // }
+
+               if (fTemplateEngine != null) {
+                       // try {
+                       fTemplateEngine.reset();
+                       fTemplateEngine.complete(viewer, documentOffset, unit);
+                       // } catch (JavaModelException x) {
+                       // }
+
+                       IPHPCompletionProposal[] templateResults = fTemplateEngine
+                                       .getResults();
+                       if (results.length == 0) {
+                               results = templateResults;
+                       } else {
+                               // concatenate arrays
+                               IPHPCompletionProposal[] total = new IPHPCompletionProposal[results.length
+                                               + templateResults.length];
+                               System.arraycopy(templateResults, 0, total, 0,
+                                               templateResults.length);
+                               System.arraycopy(results, 0, total, templateResults.length,
+                                               results.length);
+                               results = total;
+                       }
+               }
+
+               /*
+                * Order here and not in result collector to make sure that the order
+                * applies to all proposals and not just those of the compilation unit.
+                */
+               return order(results);
+       }
+
+       /**
+        * Order the given proposals.
+        */
+       private IPHPCompletionProposal[] order(IPHPCompletionProposal[] proposals) {
+               Arrays.sort(proposals, fComparator);
+               return proposals;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/AddWordProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/AddWordProposal.java
new file mode 100644 (file)
index 0000000..b19a9eb
--- /dev/null
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.text.MessageFormat;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.java.IInvocationContext;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckEngine;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellChecker;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Proposal to add the unknown word to the dictionaries.
+ * 
+ * @since 3.0
+ */
+public class AddWordProposal implements IPHPCompletionProposal {
+
+       /** The invocation context */
+       private final IInvocationContext fContext;
+
+       /** The word to add */
+       private final String fWord;
+
+       /**
+        * Creates a new add word proposal
+        * 
+        * @param word
+        *            The word to add
+        * @param context
+        *            The invocation context
+        */
+       public AddWordProposal(final String word, final IInvocationContext context) {
+               fContext = context;
+               fWord = word;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
+        */
+       public final void apply(final IDocument document) {
+
+               final ISpellCheckEngine engine = SpellCheckEngine.getInstance();
+               final ISpellChecker checker = engine.createSpellChecker(engine
+                               .getLocale(), PreferenceConstants.getPreferenceStore());
+
+               if (checker != null)
+                       checker.addWord(fWord);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               return MessageFormat
+                               .format(
+                                               PHPUIMessages.getString("Spelling.add.info"), new String[] { WordCorrectionProposal.getHtmlRepresentation(fWord) }); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
+        */
+       public final IContextInformation getContextInformation() {
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return MessageFormat.format(PHPUIMessages
+                               .getString("Spelling.add.label"), new String[] { fWord }); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return PHPUiImages.get(PHPUiImages.IMG_CORRECTION_ADD);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.java.IJavaCompletionProposal#getRelevance()
+        */
+       public int getRelevance() {
+               return Integer.MIN_VALUE;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(org.eclipse.jface.text.IDocument)
+        */
+       public final Point getSelection(final IDocument document) {
+               return new Point(fContext.getSelectionOffset(), fContext
+                               .getSelectionLength());
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/ChangeCaseProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/ChangeCaseProposal.java
new file mode 100644 (file)
index 0000000..57fde9b
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.util.Locale;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.text.java.IInvocationContext;
+
+/**
+ * Proposal to change the letter case of a word.
+ * 
+ * @since 3.0
+ */
+public class ChangeCaseProposal extends WordCorrectionProposal {
+
+       /**
+        * Creates a new change case proposal.
+        * 
+        * @param arguments
+        *            The problem arguments associated with the spelling problem
+        * @param offset
+        *            The offset in the document where to apply the proposal
+        * @param length
+        *            The lenght in the document to apply the proposal
+        * @param context
+        *            The invocation context for this proposal
+        * @param locale
+        *            The locale to use for the case change
+        */
+       public ChangeCaseProposal(final String[] arguments, final int offset,
+                       final int length, final IInvocationContext context,
+                       final Locale locale) {
+               super(Character.isLowerCase(arguments[0].charAt(0)) ? Character
+                               .toUpperCase(arguments[0].charAt(0))
+                               + arguments[0].substring(1) : arguments[0], arguments, offset,
+                               length, context, Integer.MAX_VALUE);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return PHPUIMessages.getString("Spelling.case.label"); //$NON-NLS-1$
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/HtmlTagDictionary.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/HtmlTagDictionary.java
new file mode 100644 (file)
index 0000000..617f537
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.net.URL;
+
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.IHtmlTagConstants;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.AbstractSpellDictionary;
+
+/**
+ * Dictionary for html tags.
+ * 
+ * @since 3.0
+ */
+public class HtmlTagDictionary extends AbstractSpellDictionary implements
+               IHtmlTagConstants {
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.AbstractSpellDictionary#getName()
+        */
+       protected final URL getURL() {
+               return null;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary#isCorrect(java.lang.String)
+        */
+       public boolean isCorrect(final String word) {
+
+               if (word.charAt(0) == HTML_TAG_PREFIX)
+                       return super.isCorrect(word);
+
+               return false;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.AbstractSpellDictionary#load(java.net.URL)
+        */
+       protected boolean load(final URL url) {
+
+               unload();
+
+               for (int index = 0; index < HTML_GENERAL_TAGS.length; index++) {
+
+                       hashWord(HTML_TAG_PREFIX + HTML_GENERAL_TAGS[index]
+                                       + HTML_TAG_POSTFIX);
+                       hashWord(HTML_CLOSE_PREFIX + HTML_GENERAL_TAGS[index]
+                                       + HTML_TAG_POSTFIX);
+               }
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/JavaDocTagDictionary.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/JavaDocTagDictionary.java
new file mode 100644 (file)
index 0000000..94ed16b
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.net.URL;
+
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.IJavaDocTagConstants;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.AbstractSpellDictionary;
+
+/**
+ * Dictionary for Javadoc tags.
+ * 
+ * @since 3.0
+ */
+public class JavaDocTagDictionary extends AbstractSpellDictionary implements
+               IJavaDocTagConstants {
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.AbstractSpellDictionary#getName()
+        */
+       protected final URL getURL() {
+               return null;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary#isCorrect(java.lang.String)
+        */
+       public boolean isCorrect(final String word) {
+
+               if (word.charAt(0) == JAVADOC_TAG_PREFIX)
+                       return super.isCorrect(word);
+
+               return false;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.AbstractSpellDictionary#load(java.net.URL)
+        */
+       protected boolean load(final URL url) {
+
+               unload();
+
+               for (int index = 0; index < JAVADOC_LINK_TAGS.length; index++)
+                       hashWord(JAVADOC_LINK_TAGS[index]);
+
+               for (int index = 0; index < JAVADOC_ROOT_TAGS.length; index++)
+                       hashWord(JAVADOC_ROOT_TAGS[index]);
+
+               for (int index = 0; index < JAVADOC_PARAM_TAGS.length; index++)
+                       hashWord(JAVADOC_PARAM_TAGS[index]);
+
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellCheckEngine.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellCheckEngine.java
new file mode 100644 (file)
index 0000000..0b1f05f
--- /dev/null
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.DefaultSpellChecker;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckEngine;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckPreferenceKeys;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellChecker;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.PersistentSpellDictionary;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * Spell check engine for Java source spell checking.
+ * 
+ * @since 3.0
+ */
+public class SpellCheckEngine implements ISpellCheckEngine,
+               IPropertyChangeListener {
+
+       /** The dictionary location */
+       public static final String DICTIONARY_LOCATION = "dictionaries/"; //$NON-NLS-1$
+
+       /** The singleton spell checker instance */
+       private static ISpellChecker fChecker = null;
+
+       /** The singleton engine instance */
+       private static ISpellCheckEngine fEngine = null;
+
+       /**
+        * Returns the available locales for this spell check engine.
+        * 
+        * @return The available locales for this engine
+        */
+       public static Set getAvailableLocales() {
+
+               URL url = null;
+               Locale locale = null;
+               InputStream stream = null;
+
+               final Set result = new HashSet();
+               try {
+
+                       final URL location = getDictionaryLocation();
+                       final Locale[] locales = Locale.getAvailableLocales();
+
+                       for (int index = 0; index < locales.length; index++) {
+
+                               locale = locales[index];
+                               url = new URL(
+                                               location,
+                                               locale.toString().toLowerCase()
+                                                               + "." + PHPUIMessages.getString("Spelling.dictionary.file.extension")); //$NON-NLS-1$ //$NON-NLS-2$
+
+                               try {
+                                       stream = url.openStream();
+                                       if (stream != null) {
+                                               try {
+                                                       result.add(locale);
+                                               } finally {
+                                                       stream.close();
+                                               }
+                                       }
+                               } catch (IOException exception) {
+                                       // Do nothing
+                               }
+                       }
+               } catch (MalformedURLException exception) {
+                       // Do nothing
+               }
+               result.add(getDefaultLocale());
+
+               return result;
+       }
+
+       /**
+        * Returns the default locale for this engine.
+        * 
+        * @return The default locale
+        */
+       public static Locale getDefaultLocale() {
+               return Locale.US;
+       }
+
+       /**
+        * Returns the dictionary location.
+        * 
+        * @throws MalformedURLException
+        *             if the URL could not be created
+        * @return The dictionary location, or <code>null</code> iff the location
+        *         is not known
+        */
+       public static URL getDictionaryLocation() throws MalformedURLException {
+
+               final WebUI plugin = WebUI.getDefault();
+               if (plugin != null)
+                       return plugin.getBundle().getEntry("/" + DICTIONARY_LOCATION); //$NON-NLS-1$
+
+               return null;
+       }
+
+       /**
+        * Returns the singleton instance of the spell check engine.
+        * 
+        * @return The singleton instance of the spell check engine
+        */
+       public static final synchronized ISpellCheckEngine getInstance() {
+
+               if (fEngine == null)
+                       fEngine = new SpellCheckEngine();
+
+               return fEngine;
+       }
+
+       /** The registered locale insenitive dictionaries */
+       private final Set fGlobalDictionaries = new HashSet();
+
+       /** The current locale */
+       private Locale fLocale = null;
+
+       /** The registered locale sensitive dictionaries */
+       private final Map fLocaleDictionaries = new HashMap();
+
+       /** The preference store where to listen */
+       private IPreferenceStore fPreferences = null;
+
+       /** The user dictionary */
+       private ISpellDictionary fUserDictionary = null;
+
+       /**
+        * Creates a new spell check manager.
+        */
+       private SpellCheckEngine() {
+
+               fGlobalDictionaries.add(new TaskTagDictionary());
+               fGlobalDictionaries.add(new HtmlTagDictionary());
+               fGlobalDictionaries.add(new JavaDocTagDictionary());
+
+               try {
+
+                       Locale locale = null;
+                       final URL location = getDictionaryLocation();
+
+                       for (final Iterator iterator = getAvailableLocales().iterator(); iterator
+                                       .hasNext();) {
+
+                               locale = (Locale) iterator.next();
+                               fLocaleDictionaries.put(locale, new SpellReconcileDictionary(
+                                               locale, location));
+                       }
+
+               } catch (MalformedURLException exception) {
+                       // Do nothing
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#createSpellChecker(java.util.Locale,org.eclipse.jface.preference.IPreferenceStore)
+        */
+       public final synchronized ISpellChecker createSpellChecker(
+                       final Locale locale, final IPreferenceStore store) {
+
+               if (fLocale != null && fLocale.equals(locale))
+                       return fChecker;
+
+               if (fChecker == null) {
+
+                       fChecker = new DefaultSpellChecker(store);
+                       store.addPropertyChangeListener(this);
+
+                       fPreferences = store;
+
+                       ISpellDictionary dictionary = null;
+                       for (Iterator iterator = fGlobalDictionaries.iterator(); iterator
+                                       .hasNext();) {
+
+                               dictionary = (ISpellDictionary) iterator.next();
+                               fChecker.addDictionary(dictionary);
+                       }
+               }
+
+               ISpellDictionary dictionary = null;
+               if (fLocale != null) {
+
+                       dictionary = (ISpellDictionary) fLocaleDictionaries.get(fLocale);
+                       if (dictionary != null) {
+
+                               fChecker.removeDictionary(dictionary);
+                               dictionary.unload();
+                       }
+               }
+               fLocale = locale;
+
+               dictionary = (ISpellDictionary) fLocaleDictionaries.get(locale);
+               if (dictionary == null) {
+
+                       if (!getDefaultLocale().equals(locale)) {
+
+                               if (fPreferences != null)
+                                       fPreferences.removePropertyChangeListener(this);
+
+                               fChecker = null;
+                               fLocale = null;
+                       }
+
+               } else
+                       fChecker.addDictionary(dictionary);
+
+               if (fPreferences != null)
+                       propertyChange(new PropertyChangeEvent(
+                                       this,
+                                       ISpellCheckPreferenceKeys.SPELLING_USER_DICTIONARY,
+                                       null,
+                                       fPreferences
+                                                       .getString(ISpellCheckPreferenceKeys.SPELLING_USER_DICTIONARY)));
+
+               return fChecker;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#getLocale()
+        */
+       public final Locale getLocale() {
+               return fLocale;
+       }
+
+       /*
+        * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+        */
+       public final void propertyChange(final PropertyChangeEvent event) {
+
+               if (fChecker != null
+                               && event.getProperty().equals(
+                                               ISpellCheckPreferenceKeys.SPELLING_USER_DICTIONARY)) {
+
+                       if (fUserDictionary != null) {
+
+                               fChecker.removeDictionary(fUserDictionary);
+                               fUserDictionary = null;
+                       }
+
+                       final String file = (String) event.getNewValue();
+                       if (file.length() > 0) {
+
+                               try {
+
+                                       final URL url = new URL("file", null, file); //$NON-NLS-1$
+                                       InputStream stream = url.openStream();
+                                       if (stream != null) {
+                                               try {
+                                                       fUserDictionary = new PersistentSpellDictionary(url);
+                                                       fChecker.addDictionary(fUserDictionary);
+                                               } finally {
+                                                       stream.close();
+                                               }
+                                       }
+                               } catch (MalformedURLException exception) {
+                                       // Do nothing
+                               } catch (IOException exception) {
+                                       // Do nothing
+                               }
+                       }
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#registerDictionary(net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary)
+        */
+       public synchronized final void registerDictionary(
+                       final ISpellDictionary dictionary) {
+
+               fGlobalDictionaries.add(dictionary);
+
+               if (fChecker != null)
+                       fChecker.addDictionary(dictionary);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#registerDictionary(java.util.Locale,net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary)
+        */
+       public synchronized final void registerDictionary(final Locale locale,
+                       final ISpellDictionary dictionary) {
+
+               fLocaleDictionaries.put(locale, dictionary);
+
+               if (fChecker != null && fLocale != null && fLocale.equals(locale))
+                       fChecker.addDictionary(dictionary);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#unload()
+        */
+       public synchronized final void unload() {
+
+               ISpellDictionary dictionary = null;
+               for (final Iterator iterator = fGlobalDictionaries.iterator(); iterator
+                               .hasNext();) {
+
+                       dictionary = (ISpellDictionary) iterator.next();
+                       dictionary.unload();
+               }
+
+               for (final Iterator iterator = fLocaleDictionaries.values().iterator(); iterator
+                               .hasNext();) {
+
+                       dictionary = (ISpellDictionary) iterator.next();
+                       dictionary.unload();
+               }
+
+               if (fPreferences != null)
+                       fPreferences.removePropertyChangeListener(this);
+
+               fUserDictionary = null;
+               fChecker = null;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#unregisterDictionary(net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary)
+        */
+       public synchronized final void unregisterDictionary(
+                       final ISpellDictionary dictionary) {
+
+               fGlobalDictionaries.remove(dictionary);
+               fLocaleDictionaries.values().remove(dictionary);
+
+               if (fChecker != null)
+                       fChecker.removeDictionary(dictionary);
+
+               dictionary.unload();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellCheckIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellCheckIterator.java
new file mode 100644 (file)
index 0000000..022cabf
--- /dev/null
@@ -0,0 +1,391 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.text.BreakIterator;
+import java.util.LinkedList;
+import java.util.Locale;
+
+import net.sourceforge.phpdt.corext.refactoring.nls.NLSElement;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.IHtmlTagConstants;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.IJavaDocTagConstants;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.DefaultSpellChecker;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckIterator;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextUtilities;
+
+/**
+ * Iterator to spell-check javadoc comment regions.
+ * 
+ * @since 3.0
+ */
+public class SpellCheckIterator implements ISpellCheckIterator,
+               IJavaDocTagConstants, IHtmlTagConstants {
+
+       /** The content of the region */
+       private final String fContent;
+
+       /** The line delimiter */
+       private final String fDelimiter;
+
+       /** The last token */
+       private String fLastToken = null;
+
+       /** The next break */
+       private int fNext = 1;
+
+       /** The offset of the region */
+       private final int fOffset;
+
+       /** The predecessor break */
+       private int fPredecessor;
+
+       /** The previous break */
+       private int fPrevious = 0;
+
+       /** The sentence breaks */
+       private final LinkedList fSentenceBreaks = new LinkedList();
+
+       /** Does the current word start a sentence? */
+       private boolean fStartsSentence = false;
+
+       /** The successor break */
+       private int fSuccessor;
+
+       /** The word iterator */
+       private final BreakIterator fWordIterator;
+
+       /**
+        * Creates a new spell check iterator.
+        * 
+        * @param document
+        *            The document containing the specified partition
+        * @param region
+        *            The region to spell-check
+        * @param locale
+        *            The locale to use for spell-checking
+        */
+       public SpellCheckIterator(final IDocument document, final IRegion region,
+                       final Locale locale) {
+
+               fOffset = region.getOffset();
+               fWordIterator = BreakIterator.getWordInstance(locale);
+               fDelimiter = TextUtilities.getDefaultLineDelimiter(document);
+
+               String content;
+               try {
+
+                       content = document.get(region.getOffset(), region.getLength());
+                       if (content.startsWith(NLSElement.TAG_PREFIX))
+                               content = ""; //$NON-NLS-1$
+
+               } catch (Exception exception) {
+                       content = ""; //$NON-NLS-1$
+               }
+               fContent = content;
+
+               fWordIterator.setText(content);
+               fPredecessor = fWordIterator.first();
+               fSuccessor = fWordIterator.next();
+
+               final BreakIterator iterator = BreakIterator
+                               .getSentenceInstance(locale);
+               iterator.setText(content);
+
+               int offset = iterator.current();
+               while (offset != BreakIterator.DONE) {
+
+                       fSentenceBreaks.add(new Integer(offset));
+                       offset = iterator.next();
+               }
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellCheckIterator#getBegin()
+        */
+       public final int getBegin() {
+               return fPrevious + fOffset;
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellCheckIterator#getEnd()
+        */
+       public final int getEnd() {
+               return fNext + fOffset - 1;
+       }
+
+       /*
+        * @see java.util.Iterator#hasNext()
+        */
+       public final boolean hasNext() {
+               return fSuccessor != BreakIterator.DONE;
+       }
+
+       /**
+        * Does the specified token consist of at least one letter and digits only?
+        * 
+        * @param begin
+        *            The begin index
+        * @param end
+        *            The end index
+        * @return <code>true</code> iff the token consists of digits and at least
+        *         one letter only, <code>false</code> otherwise
+        */
+       protected final boolean isAlphaNumeric(final int begin, final int end) {
+
+               char character = 0;
+
+               boolean letter = false;
+               for (int index = begin; index < end; index++) {
+
+                       character = fContent.charAt(index);
+                       if (Character.isLetter(character))
+                               letter = true;
+
+                       if (!Character.isLetterOrDigit(character))
+                               return false;
+               }
+               return letter;
+       }
+
+       /**
+        * Was the last token a Javadoc tag tag?
+        * 
+        * @param tags
+        *            The javadoc tags to check
+        * @return <code>true</code> iff the last token was a Javadoc tag,
+        *         <code>false</code> otherwise
+        */
+       protected final boolean isJavadocToken(final String[] tags) {
+
+               if (fLastToken != null) {
+
+                       for (int index = 0; index < tags.length; index++) {
+
+                               if (fLastToken.equals(tags[index]))
+                                       return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Is the current token a single letter token surrounded by non-whitespace
+        * characters?
+        * 
+        * @param begin
+        *            The begin index
+        * @return <code>true</code> iff the token is a single letter token,
+        *         <code>false</code> otherwise
+        */
+       protected final boolean isSingleLetter(final int begin) {
+
+               if (begin > 0 && begin < fContent.length() - 1)
+                       return Character.isWhitespace(fContent.charAt(begin - 1))
+                                       && Character.isLetter(fContent.charAt(begin))
+                                       && Character.isWhitespace(fContent.charAt(begin + 1));
+
+               return false;
+       }
+
+       /**
+        * Does the specified token look like an URL?
+        * 
+        * @param begin
+        *            The begin index
+        * @return <code>true</code> iff this token look like an URL,
+        *         <code>false</code> otherwise
+        */
+       protected final boolean isUrlToken(final int begin) {
+
+               for (int index = 0; index < DefaultSpellChecker.URL_PREFIXES.length; index++) {
+
+                       if (fContent.startsWith(DefaultSpellChecker.URL_PREFIXES[index],
+                                       begin))
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Does the specified token consist of whitespace only?
+        * 
+        * @param begin
+        *            The begin index
+        * @param end
+        *            The end index
+        * @return <code>true</code> iff the token consists of whitespace only,
+        *         <code>false</code> otherwise
+        */
+       protected final boolean isWhitespace(final int begin, final int end) {
+
+               for (int index = begin; index < end; index++) {
+
+                       if (!Character.isWhitespace(fContent.charAt(index)))
+                               return false;
+               }
+               return true;
+       }
+
+       /*
+        * @see java.util.Iterator#next()
+        */
+       public final Object next() {
+
+               String token = nextToken();
+               while (token == null && fSuccessor != BreakIterator.DONE)
+                       token = nextToken();
+
+               fLastToken = token;
+
+               return token;
+       }
+
+       /**
+        * Advances the end index to the next word break.
+        */
+       protected final void nextBreak() {
+
+               fNext = fSuccessor;
+               fPredecessor = fSuccessor;
+
+               fSuccessor = fWordIterator.next();
+       }
+
+       /**
+        * Returns the next sentence break.
+        * 
+        * @return The next sentence break
+        */
+       protected final int nextSentence() {
+               return ((Integer) fSentenceBreaks.getFirst()).intValue();
+       }
+
+       /**
+        * Determines the next token to be spell-checked.
+        * 
+        * @return The next token to be spell-checked, or <code>null</code> iff
+        *         the next token is not a candidate for spell-checking.
+        */
+       protected String nextToken() {
+
+               String token = null;
+
+               fPrevious = fPredecessor;
+               fStartsSentence = false;
+
+               nextBreak();
+
+               boolean update = false;
+               if (fNext - fPrevious > 0) {
+
+                       if (fSuccessor != BreakIterator.DONE
+                                       && fContent.charAt(fPrevious) == JAVADOC_TAG_PREFIX) {
+
+                               nextBreak();
+                               if (Character.isLetter(fContent.charAt(fPrevious + 1))) {
+                                       update = true;
+                                       token = fContent.substring(fPrevious, fNext);
+                               } else
+                                       fPredecessor = fNext;
+
+                       } else if (fSuccessor != BreakIterator.DONE
+                                       && fContent.charAt(fPrevious) == HTML_TAG_PREFIX
+                                       && (Character.isLetter(fContent.charAt(fNext)) || fContent
+                                                       .charAt(fNext) == '/')) {
+
+                               if (fContent.startsWith(HTML_CLOSE_PREFIX, fPrevious))
+                                       nextBreak();
+
+                               nextBreak();
+
+                               if (fSuccessor != BreakIterator.DONE
+                                               && fContent.charAt(fNext) == HTML_TAG_POSTFIX) {
+
+                                       nextBreak();
+                                       if (fSuccessor != BreakIterator.DONE) {
+                                               update = true;
+                                               token = fContent.substring(fPrevious, fNext);
+                                       }
+                               }
+                       } else if (!isWhitespace(fPrevious, fNext)
+                                       && isAlphaNumeric(fPrevious, fNext)) {
+
+                               if (isUrlToken(fPrevious))
+                                       skipTokens(fPrevious, ' ');
+                               else if (isJavadocToken(JAVADOC_PARAM_TAGS))
+                                       fLastToken = null;
+                               else if (isJavadocToken(JAVADOC_REFERENCE_TAGS)) {
+                                       fLastToken = null;
+                                       skipTokens(fPrevious, fDelimiter.charAt(0));
+                               } else if (fNext - fPrevious > 1 || isSingleLetter(fPrevious))
+                                       token = fContent.substring(fPrevious, fNext);
+
+                               update = true;
+                       }
+               }
+
+               if (update && fSentenceBreaks.size() > 0) {
+
+                       if (fPrevious >= nextSentence()) {
+
+                               while (fSentenceBreaks.size() > 0
+                                               && fPrevious >= nextSentence())
+                                       fSentenceBreaks.removeFirst();
+
+                               fStartsSentence = (fLastToken == null) || (token != null);
+                       }
+               }
+               return token;
+       }
+
+       /*
+        * @see java.util.Iterator#remove()
+        */
+       public final void remove() {
+               throw new UnsupportedOperationException();
+       }
+
+       /**
+        * Skip the tokens until the stop character is reached.
+        * 
+        * @param begin
+        *            The begin index
+        * @param stop
+        *            The stop character
+        */
+       protected final void skipTokens(final int begin, final char stop) {
+
+               int end = begin;
+
+               while (end < fContent.length() && fContent.charAt(end) != stop)
+                       end++;
+
+               if (end < fContent.length()) {
+
+                       fNext = end;
+                       fPredecessor = fNext;
+
+                       fSuccessor = fWordIterator.following(fNext);
+               } else
+                       fSuccessor = BreakIterator.DONE;
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellCheckIterator#startsSentence()
+        */
+       public final boolean startsSentence() {
+               return fStartsSentence;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellReconcileDictionary.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellReconcileDictionary.java
new file mode 100644 (file)
index 0000000..4e3530c
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.net.URL;
+import java.util.Locale;
+
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.IHtmlTagConstants;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.IJavaDocTagConstants;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.LocaleSensitiveSpellDictionary;
+
+/**
+ * Dictionary used by the spell reconciling strategy.
+ * 
+ * @since 3.0
+ */
+public class SpellReconcileDictionary extends LocaleSensitiveSpellDictionary
+               implements IJavaDocTagConstants, IHtmlTagConstants {
+
+       /**
+        * Creates a new locale sensitive spell dictionary.
+        * 
+        * @param locale
+        *            The locale for this dictionary
+        * @param location
+        *            The location of the locale sensitive dictionaries
+        */
+       public SpellReconcileDictionary(final Locale locale, final URL location) {
+               super(locale, location);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary#isCorrect(java.lang.String)
+        */
+       public boolean isCorrect(final String word) {
+
+               final char character = word.charAt(0);
+               if (character != JAVADOC_TAG_PREFIX && character != HTML_TAG_PREFIX)
+                       return super.isCorrect(word);
+
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellReconcileStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/SpellReconcileStrategy.java
new file mode 100644 (file)
index 0000000..9074743
--- /dev/null
@@ -0,0 +1,413 @@
+/*****************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *****************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+
+import net.sourceforge.phpdt.core.IProblemRequestor;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckEngine;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckPreferenceKeys;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellChecker;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEvent;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEventListener;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Reconcile strategy to spell-check comments.
+ * 
+ * @since 3.0
+ */
+public class SpellReconcileStrategy implements IReconcilingStrategy,
+               IReconcilingStrategyExtension, ISpellEventListener {
+
+       /**
+        * Spelling problem to be accepted by problem requestors.
+        */
+       public class SpellProblem implements IProblem {
+
+               /** The id of the problem */
+               public static final int Spelling = 0x80000000;
+
+               /** The end offset of the problem */
+               private int fEnd = 0;
+
+               /** The line number of the problem */
+               private int fLine = 1;
+
+               /** Was the word found in the dictionary? */
+               private boolean fMatch;
+
+               /** Does the word start a new sentence? */
+               private boolean fSentence = false;
+
+               /** The start offset of the problem */
+               private int fStart = 0;
+
+               /** The word which caused the problem */
+               private final String fWord;
+
+               /**
+                * Creates a new spelling problem
+                * 
+                * @param word
+                *            The word which caused the problem
+                */
+               protected SpellProblem(final String word) {
+                       fWord = word;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#getArguments()
+                */
+               public String[] getArguments() {
+
+                       String prefix = ""; //$NON-NLS-1$
+                       String postfix = ""; //$NON-NLS-1$
+
+                       try {
+
+                               final IRegion line = fDocument
+                                               .getLineInformationOfOffset(fStart);
+
+                               prefix = fDocument.get(line.getOffset(), fStart
+                                               - line.getOffset());
+                               postfix = fDocument.get(fEnd + 1, line.getOffset()
+                                               + line.getLength() - fEnd);
+
+                       } catch (BadLocationException exception) {
+                               // Do nothing
+                       }
+                       return new String[] {
+                                       fWord,
+                                       prefix,
+                                       postfix,
+                                       fSentence ? Boolean.toString(true) : Boolean
+                                                       .toString(false),
+                                       fMatch ? Boolean.toString(true) : Boolean.toString(false) };
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#getID()
+                */
+               public int getID() {
+                       return Spelling;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#getMessage()
+                */
+               public String getMessage() {
+
+                       if (fSentence && fMatch)
+                               return MessageFormat
+                                               .format(
+                                                               PHPUIMessages
+                                                                               .getString("Spelling.error.case.label"), new String[] { fWord }); //$NON-NLS-1$
+
+                       return MessageFormat.format(PHPUIMessages
+                                       .getString("Spelling.error.label"), new String[] { fWord }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#getOriginatingFileName()
+                */
+               public char[] getOriginatingFileName() {
+                       return fEditor.getEditorInput().getName().toCharArray();
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#getSourceEnd()
+                */
+               public final int getSourceEnd() {
+                       return fEnd;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#getSourceLineNumber()
+                */
+               public final int getSourceLineNumber() {
+                       return fLine;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#getSourceStart()
+                */
+               public final int getSourceStart() {
+                       return fStart;
+               }
+
+               /**
+                * Was the problem word found in the dictionary?
+                * 
+                * @return <code>true</code> iff the word was found,
+                *         <code>false</code> otherwise
+                */
+               public final boolean isDictionaryMatch() {
+                       return fMatch;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#isError()
+                */
+               public final boolean isError() {
+                       return false;
+               }
+
+               /**
+                * Does the problem word start a new sentence?
+                * 
+                * @return <code>true</code> iff it starts a new sentence,
+                *         <code>false</code> otherwise
+                */
+               public final boolean isSentenceStart() {
+                       return fSentence;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#isWarning()
+                */
+               public final boolean isWarning() {
+                       return true;
+               }
+
+               /**
+                * Sets whether the problem word was found in the dictionary.
+                * 
+                * @param match
+                *            <code>true</code> iff the word was found,
+                *            <code>false</code> otherwise
+                */
+               public final void setDictionaryMatch(final boolean match) {
+                       fMatch = match;
+               }
+
+               /**
+                * Sets whether the problem word starts a new sentence.
+                * 
+                * @param sentence
+                *            <code>true</code> iff the word starts a new sentence,
+                *            <code>false</code> otherwise.
+                */
+               public final void setSentenceStart(final boolean sentence) {
+                       fSentence = sentence;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#setSourceEnd(int)
+                */
+               public final void setSourceEnd(final int end) {
+                       fEnd = end;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#setSourceLineNumber(int)
+                */
+               public final void setSourceLineNumber(final int line) {
+                       fLine = line;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.core.compiler.IProblem#setSourceStart(int)
+                */
+               public final void setSourceStart(final int start) {
+                       fStart = start;
+               }
+       }
+
+       /** The document to operate on */
+       private IDocument fDocument = null;
+
+       /** The text editor to operate on */
+       private final ITextEditor fEditor;
+
+       /** The current locale */
+       private Locale fLocale = SpellCheckEngine.getDefaultLocale();
+
+       /** The partitioning of the document */
+       private final String fPartitioning;
+
+       /** The preference store to use */
+       private final IPreferenceStore fPreferences;
+
+       /** The problem requestor */
+       private IProblemRequestor fRequestor;
+
+       /**
+        * Creates a new comment reconcile strategy.
+        * 
+        * @param editor
+        *            The text editor to operate on
+        * @param partitioning
+        *            The partitioning of the document
+        * @param store
+        *            The preference store to get the preferences from
+        */
+       public SpellReconcileStrategy(final ITextEditor editor,
+                       final String partitioning, final IPreferenceStore store) {
+               fEditor = editor;
+               fPartitioning = partitioning;
+               fPreferences = store;
+
+               updateProblemRequestor();
+       }
+
+       /**
+        * Returns the current locale of the spell checking preferences.
+        * 
+        * @return The current locale of the spell checking preferences
+        */
+       public Locale getLocale() {
+
+               final String locale = fPreferences
+                               .getString(ISpellCheckPreferenceKeys.SPELLING_LOCALE);
+               if (locale.equals(fLocale.toString()))
+                       return fLocale;
+
+               if (locale.length() >= 5)
+                       return new Locale(locale.substring(0, 2), locale.substring(3, 5));
+
+               return SpellCheckEngine.getDefaultLocale();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEventListener#handle(net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEvent)
+        */
+       public void handle(final ISpellEvent event) {
+
+               if (fRequestor != null) {
+
+                       final SpellProblem problem = new SpellProblem(event.getWord());
+
+                       problem.setSourceStart(event.getBegin());
+                       problem.setSourceEnd(event.getEnd());
+                       problem.setSentenceStart(event.isStart());
+                       problem.setDictionaryMatch(event.isMatch());
+
+                       try {
+                               problem.setSourceLineNumber(fDocument.getLineOfOffset(event
+                                               .getBegin()) + 1);
+                       } catch (BadLocationException x) {
+                               // Do nothing
+                       }
+
+                       fRequestor.acceptProblem(problem);
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
+        */
+       public void initialReconcile() {
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion,org.eclipse.jface.text.IRegion)
+        */
+       public void reconcile(final DirtyRegion dirtyRegion, final IRegion subRegion) {
+               reconcile(subRegion);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
+        */
+       public void reconcile(final IRegion region) {
+
+               if (fPreferences
+                               .getBoolean(ISpellCheckPreferenceKeys.SPELLING_CHECK_SPELLING)
+                               && fRequestor != null) {
+
+                       try {
+
+                               fRequestor.beginReporting();
+
+                               ITypedRegion partition = null;
+                               final ITypedRegion[] partitions = TextUtilities
+                                               .computePartitioning(fDocument, fPartitioning, 0,
+                                                               fDocument.getLength(), false);
+
+                               final Locale locale = getLocale();
+                               final ISpellCheckEngine engine = SpellCheckEngine.getInstance();
+
+                               final ISpellChecker checker = engine.createSpellChecker(locale,
+                                               fPreferences);
+                               if (checker != null) {
+                                       try {
+                                               checker.addListener(this);
+
+                                               for (int index = 0; index < partitions.length; index++) {
+                                                       partition = partitions[index];
+                                                       if (!partition.getType().equals(
+                                                                       IDocument.DEFAULT_CONTENT_TYPE)
+                                                                       && !partition
+                                                                                       .getType()
+                                                                                       .equals(
+                                                                                                       PHPDocumentPartitioner.PHP_SCRIPT_CODE))
+                                                               checker.execute(new SpellCheckIterator(
+                                                                               fDocument, partition, locale));
+                                               }
+
+                                       } finally {
+                                               checker.removeListener(this);
+                                       }
+                               }
+                       } catch (BadLocationException exception) {
+                               // Do nothing
+                       } finally {
+                               fRequestor.endReporting();
+                       }
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
+        */
+       public final void setDocument(final IDocument document) {
+               fDocument = document;
+
+               updateProblemRequestor();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
+        */
+       public final void setProgressMonitor(final IProgressMonitor monitor) {
+               // Do nothing
+       }
+
+       /**
+        * Update the problem requestor based on the current editor
+        * 
+        * @since 3.0
+        */
+       private void updateProblemRequestor() {
+               final IAnnotationModel model = fEditor.getDocumentProvider()
+                               .getAnnotationModel(fEditor.getEditorInput());
+               fRequestor = (model instanceof IProblemRequestor) ? (IProblemRequestor) model
+                               : null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/TaskTagDictionary.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/TaskTagDictionary.java
new file mode 100644 (file)
index 0000000..867690b
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.net.URL;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.AbstractSpellDictionary;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+
+/**
+ * Dictionary for task tags.
+ * 
+ * @since 3.0
+ */
+public class TaskTagDictionary extends AbstractSpellDictionary implements
+               IPropertyChangeListener {
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.AbstractSpellDictionary#getName()
+        */
+       protected final URL getURL() {
+               return null;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.AbstractSpellDictionary#load(java.net.URL)
+        */
+       protected boolean load(final URL url) {
+
+               final Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null) {
+
+                       plugin.getPluginPreferences().addPropertyChangeListener(this);
+                       return updateTaskTags();
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
+        */
+       public void propertyChange(final PropertyChangeEvent event) {
+
+               if (JavaCore.COMPILER_TASK_TAGS.equals(event.getProperty()))
+                       updateTaskTags();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary#unload()
+        */
+       public void unload() {
+
+               final Plugin plugin = JavaCore.getPlugin();
+               if (plugin != null)
+                       plugin.getPluginPreferences().removePropertyChangeListener(this);
+
+               super.unload();
+       }
+
+       /**
+        * Handles the compiler task tags property change event.
+        */
+       protected boolean updateTaskTags() {
+
+               final String tags = JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS);
+               if (tags != null) {
+
+                       unload();
+
+                       final StringTokenizer tokenizer = new StringTokenizer(tags, ","); //$NON-NLS-1$
+                       while (tokenizer.hasMoreTokens())
+                               hashWord(tokenizer.nextToken());
+
+                       return true;
+               }
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/WordCorrectionProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/WordCorrectionProposal.java
new file mode 100644 (file)
index 0000000..60aaeb0
--- /dev/null
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.text.MessageFormat;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.java.IInvocationContext;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.IHtmlTagConstants;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Proposal to correct the incorrectly spelled word.
+ * 
+ * @since 3.0
+ */
+public class WordCorrectionProposal implements IPHPCompletionProposal,
+               IHtmlTagConstants {
+
+       /**
+        * Returns the html representation of the specified string.
+        * 
+        * @param string
+        *            The string to return the html representation for
+        * @return The html representation for the string
+        */
+       public static String getHtmlRepresentation(final String string) {
+
+               final int length = string.length();
+               final StringBuffer buffer = new StringBuffer(string);
+
+               for (int offset = length - 1; offset >= 0; offset--) {
+
+                       for (int index = 0; index < HTML_ENTITY_CHARACTERS.length; index++) {
+
+                               if (string.charAt(offset) == HTML_ENTITY_CHARACTERS[index]) {
+
+                                       buffer.replace(offset, offset + 1, String
+                                                       .valueOf(HTML_ENTITY_CODES[index]));
+                                       break;
+                               }
+                       }
+               }
+               return buffer.toString();
+       }
+
+       /** The invocation context */
+       private final IInvocationContext fContext;
+
+       /** The length in the document */
+       private final int fLength;
+
+       /** The line where to apply the correction */
+       private final String fLine;
+
+       /** The offset in the document */
+       private final int fOffset;
+
+       /** The relevance of this proposal */
+       private final int fRelevance;
+
+       /** The word to complete */
+       private final String fWord;
+
+       /**
+        * Creates a new word correction proposal.
+        * 
+        * @param word
+        *            The corrected word
+        * @param arguments
+        *            The problem arguments associated with the spelling problem
+        * @param offset
+        *            The offset in the document where to apply the proposal
+        * @param length
+        *            The lenght in the document to apply the proposal
+        * @param context
+        *            The invocation context for this proposal
+        * @param relevance
+        *            The relevance of this proposal
+        */
+       public WordCorrectionProposal(final String word, final String[] arguments,
+                       final int offset, final int length,
+                       final IInvocationContext context, final int relevance) {
+
+               fWord = Character.isUpperCase(arguments[0].charAt(0)) ? Character
+                               .toUpperCase(word.charAt(0))
+                               + word.substring(1) : word;
+
+               fOffset = offset;
+               fLength = length;
+               fContext = context;
+               fRelevance = relevance;
+
+               final StringBuffer buffer = new StringBuffer(80);
+
+               buffer.append("...<br>"); //$NON-NLS-1$
+               buffer.append(getHtmlRepresentation(arguments[1]));
+               buffer.append("<b>"); //$NON-NLS-1$
+               buffer.append(getHtmlRepresentation(fWord));
+               buffer.append("</b>"); //$NON-NLS-1$
+               buffer.append(getHtmlRepresentation(arguments[2]));
+               buffer.append("<br>..."); //$NON-NLS-1$
+
+               fLine = buffer.toString();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
+        */
+       public final void apply(final IDocument document) {
+               try {
+                       document.replace(fOffset, fLength, fWord);
+               } catch (BadLocationException exception) {
+                       // Do nothing
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               return fLine;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
+        */
+       public final IContextInformation getContextInformation() {
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return MessageFormat.format(PHPUIMessages
+                               .getString("Spelling.correct.label"), new String[] { fWord }); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return PHPUiImages.get(PHPUiImages.IMG_CORRECTION_RENAME);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.java.IJavaCompletionProposal#getRelevance()
+        */
+       public final int getRelevance() {
+               return fRelevance;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(org.eclipse.jface.text.IDocument)
+        */
+       public final Point getSelection(final IDocument document) {
+
+               int offset = fContext.getSelectionOffset();
+               int length = fContext.getSelectionLength();
+
+               final int delta = fWord.length() - fLength;
+               if (offset <= fOffset && offset + length >= fOffset)
+                       length += delta;
+               else if (offset > fOffset && offset + length > fOffset + fLength) {
+                       offset += delta;
+                       length -= delta;
+               } else
+                       length += delta;
+
+               return new Point(offset, length);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/WordIgnoreProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/WordIgnoreProposal.java
new file mode 100644 (file)
index 0000000..47add64
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling;
+
+import java.text.MessageFormat;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.java.IInvocationContext;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckEngine;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellChecker;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Proposal to ignore the word during the current editing session.
+ * 
+ * @since 3.0
+ */
+public class WordIgnoreProposal implements IPHPCompletionProposal {
+
+       /** The invocation context */
+       private IInvocationContext fContext;
+
+       /** The word to ignore */
+       private String fWord;
+
+       /**
+        * Creates a new spell ignore proposal.
+        * 
+        * @param word
+        *            The word to ignore
+        * @param context
+        *            The invocation context
+        */
+       public WordIgnoreProposal(final String word,
+                       final IInvocationContext context) {
+               fWord = word;
+               fContext = context;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
+        */
+       public final void apply(final IDocument document) {
+
+               final ISpellCheckEngine engine = SpellCheckEngine.getInstance();
+               final ISpellChecker checker = engine.createSpellChecker(engine
+                               .getLocale(), PreferenceConstants.getPreferenceStore());
+
+               if (checker != null)
+                       checker.ignoreWord(fWord);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               return MessageFormat
+                               .format(
+                                               PHPUIMessages.getString("Spelling.ignore.info"), new String[] { WordCorrectionProposal.getHtmlRepresentation(fWord) }); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
+        */
+       public final IContextInformation getContextInformation() {
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return MessageFormat.format(PHPUIMessages
+                               .getString("Spelling.ignore.label"), new String[] { fWord }); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return PHPUiImages.get(PHPUiImages.IMG_OBJS_NLS_NEVER_TRANSLATE);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.java.IJavaCompletionProposal#getRelevance()
+        */
+       public final int getRelevance() {
+               return Integer.MIN_VALUE + 1;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(org.eclipse.jface.text.IDocument)
+        */
+       public final Point getSelection(final IDocument document) {
+               return new Point(fContext.getSelectionOffset(), fContext
+                               .getSelectionLength());
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/AbstractSpellDictionary.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/AbstractSpellDictionary.java
new file mode 100644 (file)
index 0000000..8e0bab5
--- /dev/null
@@ -0,0 +1,445 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Partial implementation of a spell dictionary.
+ * 
+ * @since 3.0
+ */
+public abstract class AbstractSpellDictionary implements ISpellDictionary {
+
+       /** The bucket capacity */
+       protected static final int BUCKET_CAPACITY = 4;
+
+       /** The word buffer capacity */
+       protected static final int BUFFER_CAPACITY = 32;
+
+       /** The distance threshold */
+       protected static final int DISTANCE_THRESHOLD = 160;
+
+       /** The hash capacity */
+       protected static final int HASH_CAPACITY = 22 * 1024;
+
+       /** The phonetic distance algorithm */
+       private IPhoneticDistanceAlgorithm fDistanceAlgorithm = new DefaultPhoneticDistanceAlgorithm();
+
+       /** The mapping from phonetic hashes to word lists */
+       private final Map fHashBuckets = new HashMap(HASH_CAPACITY);
+
+       /** The phonetic hash provider */
+       private IPhoneticHashProvider fHashProvider = new DefaultPhoneticHashProvider();
+
+       /** Is the dictionary already loaded? */
+       private boolean fLoaded = false;
+
+       /**
+        * Returns all candidates with the same phonetic hash.
+        * 
+        * @param hash
+        *            The hash to retrieve the candidates of
+        * @return Array of candidates for the phonetic hash
+        */
+       protected final ArrayList getCandidates(final String hash) {
+
+               ArrayList list = (ArrayList) fHashBuckets.get(hash);
+               if (list == null)
+                       list = new ArrayList(0);
+
+               return list;
+       }
+
+       /**
+        * Returns all candidates that have a phonetic hash within a bounded
+        * distance to the specified word.
+        * 
+        * @param word
+        *            The word to find the nearest matches for
+        * @param sentence
+        *            <code>true</code> iff the proposals start a new sentence,
+        *            <code>false</code> otherwise
+        * @param hashs
+        *            Array of close hashes to find the matches
+        * @return Set of ranked words with bounded distance to the specified word
+        */
+       protected final HashSet getCandidates(final String word,
+                       final boolean sentence, final ArrayList hashs) {
+
+               int distance = 0;
+               String hash = null;
+
+               String candidate = null;
+               List candidates = null;
+
+               final StringBuffer buffer = new StringBuffer(BUFFER_CAPACITY);
+               final HashSet result = new HashSet(BUCKET_CAPACITY * hashs.size());
+
+               for (int index = 0; index < hashs.size(); index++) {
+
+                       hash = (String) hashs.get(index);
+                       candidates = getCandidates(hash);
+
+                       for (int offset = 0; offset < candidates.size(); offset++) {
+
+                               candidate = (String) candidates.get(offset);
+                               distance = fDistanceAlgorithm.getDistance(word, candidate);
+
+                               if (distance < DISTANCE_THRESHOLD) {
+
+                                       buffer.setLength(0);
+                                       buffer.append(candidate);
+
+                                       if (sentence)
+                                               buffer.setCharAt(0, Character.toUpperCase(buffer
+                                                               .charAt(0)));
+
+                                       result.add(new RankedWordProposal(buffer.toString(),
+                                                       -distance));
+                               }
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * Returns all approximations that have a phonetic hash with smallest
+        * possible distance to the specified word.
+        * 
+        * @param word
+        *            The word to find the nearest matches for
+        * @param sentence
+        *            <code>true</code> iff the proposals start a new sentence,
+        *            <code>false</code> otherwise
+        * @param result
+        *            Set of ranked words with smallest possible distance to the
+        *            specified word
+        */
+       protected final void getCandidates(final String word,
+                       final boolean sentence, final HashSet result) {
+
+               int distance = 0;
+               int minimum = Integer.MAX_VALUE;
+
+               String candidate = null;
+               StringBuffer buffer = new StringBuffer(BUFFER_CAPACITY);
+
+               final ArrayList candidates = getCandidates(fHashProvider.getHash(word));
+               final ArrayList matches = new ArrayList(candidates.size());
+
+               for (int index = 0; index < candidates.size(); index++) {
+
+                       candidate = (String) candidates.get(index);
+                       distance = fDistanceAlgorithm.getDistance(word, candidate);
+
+                       if (distance <= minimum) {
+
+                               buffer.setLength(0);
+                               buffer.append(candidate);
+
+                               if (sentence)
+                                       buffer
+                                                       .setCharAt(0, Character.toUpperCase(buffer
+                                                                       .charAt(0)));
+
+                               matches
+                                               .add(new RankedWordProposal(buffer.toString(),
+                                                               -distance));
+                               minimum = distance;
+                       }
+               }
+
+               RankedWordProposal match = null;
+
+               for (int index = 0; index < matches.size(); index++) {
+
+                       match = (RankedWordProposal) matches.get(index);
+                       if (match.getRank() == minimum)
+                               result.add(match);
+               }
+       }
+
+       /**
+        * Returns the used phonetic distance algorithm.
+        * 
+        * @return The phonetic distance algorithm
+        */
+       protected final IPhoneticDistanceAlgorithm getDistanceAlgorithm() {
+               return fDistanceAlgorithm;
+       }
+
+       /**
+        * Returns the used phonetic hash provider.
+        * 
+        * @return The phonetic hash provider
+        */
+       protected final IPhoneticHashProvider getHashProvider() {
+               return fHashProvider;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary#getProposals(java.lang.String,boolean)
+        */
+       public Set getProposals(final String word, final boolean sentence) {
+
+               try {
+
+                       if (!fLoaded)
+                               load(getURL());
+
+               } catch (MalformedURLException exception) {
+                       // Do nothing
+               }
+
+               final String hash = fHashProvider.getHash(word);
+               final char[] mutators = fHashProvider.getMutators();
+
+               final ArrayList neighborhood = new ArrayList((word.length() + 1)
+                               * (mutators.length + 2));
+               neighborhood.add(hash);
+
+               final HashSet candidates = getCandidates(word, sentence, neighborhood);
+               neighborhood.clear();
+
+               char previous = 0;
+               char next = 0;
+
+               char[] characters = word.toCharArray();
+               for (int index = 0; index < word.length() - 1; index++) {
+
+                       next = characters[index];
+                       previous = characters[index + 1];
+
+                       characters[index] = previous;
+                       characters[index + 1] = next;
+
+                       neighborhood.add(fHashProvider.getHash(new String(characters)));
+
+                       characters[index] = next;
+                       characters[index + 1] = previous;
+               }
+
+               final String sentinel = word + " "; //$NON-NLS-1$
+
+               characters = sentinel.toCharArray();
+               int offset = characters.length - 1;
+
+               while (true) {
+
+                       for (int index = 0; index < mutators.length; index++) {
+
+                               characters[offset] = mutators[index];
+                               neighborhood.add(fHashProvider.getHash(new String(characters)));
+                       }
+
+                       if (offset == 0)
+                               break;
+
+                       characters[offset] = characters[offset - 1];
+                       --offset;
+               }
+
+               char mutated = 0;
+               characters = word.toCharArray();
+
+               for (int index = 0; index < word.length(); index++) {
+
+                       mutated = characters[index];
+                       for (int mutator = 0; mutator < mutators.length; mutator++) {
+
+                               characters[index] = mutators[mutator];
+                               neighborhood.add(fHashProvider.getHash(new String(characters)));
+                       }
+                       characters[index] = mutated;
+               }
+
+               characters = word.toCharArray();
+               final char[] deleted = new char[characters.length - 1];
+
+               for (int index = 0; index < deleted.length; index++)
+                       deleted[index] = characters[index];
+
+               next = characters[characters.length - 1];
+               offset = deleted.length;
+
+               while (true) {
+
+                       neighborhood.add(fHashProvider.getHash(new String(characters)));
+                       if (offset == 0)
+                               break;
+
+                       previous = next;
+                       next = deleted[offset - 1];
+
+                       deleted[offset - 1] = previous;
+                       --offset;
+               }
+
+               neighborhood.remove(hash);
+               final HashSet matches = getCandidates(word, sentence, neighborhood);
+
+               if (matches.size() == 0 && candidates.size() == 0)
+                       getCandidates(word, sentence, candidates);
+
+               candidates.addAll(matches);
+
+               return candidates;
+       }
+
+       /**
+        * Returns the URL of the dictionary word list.
+        * 
+        * @throws MalformedURLException
+        *             if the URL could not be retrieved
+        * @return The URL of the dictionary word list
+        */
+       protected abstract URL getURL() throws MalformedURLException;
+
+       /**
+        * Hashes the word into the dictionary.
+        * 
+        * @param word
+        *            The word to hash in the dictionary
+        */
+       protected final void hashWord(final String word) {
+
+               final String hash = fHashProvider.getHash(word);
+               ArrayList bucket = (ArrayList) fHashBuckets.get(hash);
+
+               if (bucket == null) {
+
+                       bucket = new ArrayList(BUCKET_CAPACITY);
+                       fHashBuckets.put(hash, bucket);
+               }
+
+               bucket.add(word);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary#isCorrect(java.lang.String)
+        */
+       public boolean isCorrect(final String word) {
+
+               try {
+
+                       if (!fLoaded)
+                               load(getURL());
+
+               } catch (MalformedURLException exception) {
+                       // Do nothing
+               }
+
+               final ArrayList candidates = getCandidates(fHashProvider.getHash(word));
+
+               if (candidates.contains(word)
+                               || candidates.contains(word.toLowerCase()))
+                       return true;
+
+               return false;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary#isLoaded()
+        */
+       public final synchronized boolean isLoaded() {
+               return fLoaded || fHashBuckets.size() > 0;
+       }
+
+       /**
+        * Loads a dictionary word list from disk.
+        * 
+        * @param url
+        *            The URL of the word list to load
+        * @return <code>true</code> iff the word list could be loaded,
+        *         <code>false</code> otherwise
+        */
+       protected synchronized boolean load(final URL url) {
+
+               if (url != null) {
+
+                       try {
+
+                               final InputStream stream = url.openStream();
+                               if (stream != null) {
+
+                                       String word = null;
+
+                                       final BufferedReader reader = new BufferedReader(
+                                                       new InputStreamReader(stream));
+                                       while ((word = reader.readLine()) != null)
+                                               hashWord(word);
+
+                                       return fLoaded = true;
+                               }
+                       } catch (IOException exception) {
+                               // Do nothing
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Sets the phonetic distance algorithm to use.
+        * 
+        * @param algorithm
+        *            The phonetic distance algorithm
+        */
+       protected final void setDistanceAlgorithm(
+                       final IPhoneticDistanceAlgorithm algorithm) {
+               fDistanceAlgorithm = algorithm;
+       }
+
+       /**
+        * Sets the phonetic hash provider to use.
+        * 
+        * @param provider
+        *            The phonetic hash provider
+        */
+       protected final void setHashProvider(final IPhoneticHashProvider provider) {
+               fHashProvider = provider;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary#unload()
+        */
+       public synchronized void unload() {
+
+               fLoaded = false;
+               fHashBuckets.clear();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary#acceptsWords()
+        */
+       public boolean acceptsWords() {
+               return false;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary#addWord(java.lang.String)
+        */
+       public void addWord(final String word) {
+               // Do nothing
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultPhoneticDistanceAlgorithm.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultPhoneticDistanceAlgorithm.java
new file mode 100644 (file)
index 0000000..cb95f37
--- /dev/null
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+/**
+ * Default phonetic distance algorithm for english words.
+ * <p>
+ * This algorithm implements the Levenshtein text edit distance.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public final class DefaultPhoneticDistanceAlgorithm implements
+               IPhoneticDistanceAlgorithm {
+
+       /** The change case cost */
+       public static final int COST_CASE = 10;
+
+       /** The insert character cost */
+       public static final int COST_INSERT = 95;
+
+       /** The remove character cost */
+       public static final int COST_REMOVE = 95;
+
+       /** The substitute characters cost */
+       public static final int COST_SUBSTITUTE = 100;
+
+       /** The swap characters cost */
+       public static final int COST_SWAP = 90;
+
+       /*
+        * @see org.eclipse.spelling.done.IPhoneticDistanceAlgorithm#getDistance(java.lang.String,java.lang.String)
+        */
+       public final int getDistance(final String from, final String to) {
+
+               final char[] first = (" " + from).toCharArray(); //$NON-NLS-1$
+               final char[] second = (" " + to).toCharArray(); //$NON-NLS-1$
+
+               final int rows = first.length;
+               final int columns = second.length;
+
+               final int[][] metric = new int[rows][columns];
+               for (int column = 1; column < columns; column++)
+                       metric[0][column] = metric[0][column - 1] + COST_REMOVE;
+
+               for (int row = 1; row < rows; row++)
+                       metric[row][0] = metric[row - 1][0] + COST_INSERT;
+
+               char source, target;
+
+               int swap = Integer.MAX_VALUE;
+               int change = Integer.MAX_VALUE;
+
+               int minimum, diagonal, insert, remove;
+               for (int row = 1; row < rows; row++) {
+
+                       source = first[row];
+                       for (int column = 1; column < columns; column++) {
+
+                               target = second[column];
+                               diagonal = metric[row - 1][column - 1];
+
+                               if (source == target) {
+                                       metric[row][column] = diagonal;
+                                       continue;
+                               }
+
+                               change = Integer.MAX_VALUE;
+                               if (Character.toLowerCase(source) == Character
+                                               .toLowerCase(target))
+                                       change = COST_CASE + diagonal;
+
+                               swap = Integer.MAX_VALUE;
+                               if (row != 1 && column != 1 && source == second[column - 1]
+                                               && first[row - 1] == target)
+                                       swap = COST_SWAP + metric[row - 2][column - 2];
+
+                               minimum = COST_SUBSTITUTE + diagonal;
+                               if (swap < minimum)
+                                       minimum = swap;
+
+                               remove = metric[row][column - 1];
+                               if (COST_REMOVE + remove < minimum)
+                                       minimum = COST_REMOVE + remove;
+
+                               insert = metric[row - 1][column];
+                               if (COST_INSERT + insert < minimum)
+                                       minimum = COST_INSERT + insert;
+                               if (change < minimum)
+                                       minimum = change;
+
+                               metric[row][column] = minimum;
+                       }
+               }
+               return metric[rows - 1][columns - 1];
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultPhoneticHashProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultPhoneticHashProvider.java
new file mode 100644 (file)
index 0000000..2229bcf
--- /dev/null
@@ -0,0 +1,852 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+/**
+ * Default phonetic hash provider for english languages.
+ * <p>
+ * This algorithm uses an adapted version double metaphone algorithm by Lawrence
+ * Philips.
+ * <p>
+ * 
+ * @since 3.0
+ */
+public final class DefaultPhoneticHashProvider implements IPhoneticHashProvider {
+
+       private static final String[] meta01 = { "ACH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta02 = { "BACHER", "MACHER", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta03 = { "CAESAR", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta04 = { "CHIA", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta05 = { "CH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta06 = { "CHAE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta07 = { "HARAC", "HARIS", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta08 = { "HOR", "HYM", "HIA", "HEM", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta09 = { "CHORE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta10 = { "VAN ", "VON ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta11 = { "SCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta12 = { "ORCHES", "ARCHIT", "ORCHID", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta13 = { "T", "S", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta14 = { "A", "O", "U", "E", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta15 = {
+                       "L", "R", "N", "M", "B", "H", "F", "V", "W", " ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$
+
+       private static final String[] meta16 = { "MC", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta17 = { "CZ", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta18 = { "WICZ", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta19 = { "CIA", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta20 = { "CC", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta21 = { "I", "E", "H", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta22 = { "HU", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta23 = { "UCCEE", "UCCES", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta24 = { "CK", "CG", "CQ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta25 = { "CI", "CE", "CY", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta26 = { "GN", "KN", "PN", "WR", "PS", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+
+       private static final String[] meta27 = { " C", " Q", " G", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta28 = { "C", "K", "Q", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta29 = { "CE", "CI", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta30 = { "DG", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta31 = { "I", "E", "Y", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta32 = { "DT", "DD", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta33 = { "B", "H", "D", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta34 = { "B", "H", "D", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta35 = { "B", "H", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta36 = { "C", "G", "L", "R", "T", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+
+       private static final String[] meta37 = { "EY", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta38 = { "LI", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta39 = {
+                       "ES", "EP", "EB", "EL", "EY", "IB", "IL", "IN", "IE", "EI", "ER", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$
+
+       private static final String[] meta40 = { "ER", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta41 = { "DANGER", "RANGER", "MANGER", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta42 = { "E", "I", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta43 = { "RGY", "OGY", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta44 = { "E", "I", "Y", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta45 = { "AGGI", "OGGI", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta46 = { "VAN ", "VON ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta47 = { "SCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta48 = { "ET", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta49 = { "C", "X", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta50 = { "JOSE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta51 = { "SAN ", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta52 = { "SAN ", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta53 = { "JOSE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta54 = {
+                       "L", "T", "K", "S", "N", "M", "B", "Z", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
+
+       private static final String[] meta55 = { "S", "K", "L", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta56 = { "ILLO", "ILLA", "ALLE", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta57 = { "AS", "OS", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta58 = { "A", "O", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta59 = { "ALLE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta60 = { "UMB", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta61 = { "ER", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta62 = { "P", "B", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta63 = { "IE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta64 = { "ME", "MA", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta65 = { "ISL", "YSL", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta66 = { "SUGAR", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta67 = { "SH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta68 = { "HEIM", "HOEK", "HOLM", "HOLZ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta69 = { "SIO", "SIA", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta70 = { "SIAN", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta71 = { "M", "N", "L", "W", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta72 = { "Z", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta73 = { "Z", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta74 = { "SC", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta75 = {
+                       "OO", "ER", "EN", "UY", "ED", "EM", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+
+       private static final String[] meta76 = { "ER", "EN", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta77 = { "I", "E", "Y", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta78 = { "AI", "OI", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta79 = { "S", "Z", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta80 = { "TION", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta81 = { "TIA", "TCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta82 = { "TH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta83 = { "TTH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta84 = { "OM", "AM", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta85 = { "VAN ", "VON ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta86 = { "SCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta87 = { "T", "D", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta88 = { "WR", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta89 = { "WH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta90 = {
+                       "EWSKI", "EWSKY", "OWSKI", "OWSKY", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta91 = { "SCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta92 = { "WICZ", "WITZ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta93 = { "IAU", "EAU", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta94 = { "AU", "OU", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta95 = { "W", "K", "CZ", "WITZ" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       /** The mutator characters */
+       private static final char[] MUTATOR_CHARACTERS = { 'A', 'B', 'X', 'S', 'K',
+                       'J', 'T', 'F', 'H', 'L', 'M', 'N', 'P', 'R', '0' };
+
+       /** The vowel characters */
+       private static final char[] VOWEL_CHARACTERS = new char[] { 'A', 'E', 'I',
+                       'O', 'U', 'Y' };
+
+       /**
+        * Test whether the specified string contains one of the candidates in the
+        * list.
+        * 
+        * @param candidates
+        *            Array of candidates to check
+        * @param token
+        *            The token to check for occurrences of the candidates
+        * @param offset
+        *            The offset where to begin checking in the string
+        * @param length
+        *            The length of the range in the string to check
+        * @return <code>true</code> iff the string contains one of the
+        *         candidates, <code>false</code> otherwise.
+        */
+       protected static final boolean hasOneOf(final String[] candidates,
+                       final char[] token, final int offset, final int length) {
+
+               if (offset < 0 || offset >= token.length || candidates.length == 0)
+                       return false;
+
+               final String checkable = new String(token, offset, length);
+               for (int index = 0; index < candidates.length; index++) {
+
+                       if (candidates[index].equals(checkable))
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Test whether the specified token contains one of the candidates in the
+        * list.
+        * 
+        * @param candidates
+        *            Array of candidates to check
+        * @param token
+        *            The token to check for occurrences of the candidates
+        * @return <code>true</code> iff the string contains one of the
+        *         candidates, <code>false</code> otherwise.
+        */
+       protected static final boolean hasOneOf(final String[] candidates,
+                       final String token) {
+
+               for (int index = 0; index < candidates.length; index++) {
+
+                       if (token.indexOf(candidates[index]) >= 0)
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Tests whether the specified token contains a vowel at the specified
+        * offset.
+        * 
+        * @param token
+        *            The token to check for a vowel
+        * @param offset
+        *            The offset where to begin checking in the token
+        * @param length
+        *            The length of the range in the token to check
+        * @return <code>true</code> iff the token contains a vowel,
+        *         <code>false</code> otherwise.
+        */
+       protected static final boolean hasVowel(final char[] token,
+                       final int offset, final int length) {
+
+               if (offset >= 0 && offset < length) {
+
+                       final char character = token[offset];
+                       for (int index = 0; index < VOWEL_CHARACTERS.length; index++) {
+
+                               if (VOWEL_CHARACTERS[index] == character)
+                                       return true;
+                       }
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.IPhoneticHasher#getHash(java.lang.String)
+        */
+       public final String getHash(final String word) {
+
+               final String input = word.toUpperCase() + "     "; //$NON-NLS-1$
+               final char[] hashable = input.toCharArray();
+
+               final boolean has95 = hasOneOf(meta95, input);
+               final StringBuffer buffer = new StringBuffer(hashable.length);
+
+               int offset = 0;
+               if (hasOneOf(meta26, hashable, 0, 2))
+                       offset += 1;
+
+               if (hashable[0] == 'X') {
+                       buffer.append('S');
+                       offset += 1;
+               }
+
+               while (offset < hashable.length) {
+
+                       switch (hashable[offset]) {
+                       case 'A':
+                       case 'E':
+                       case 'I':
+                       case 'O':
+                       case 'U':
+                       case 'Y':
+                               if (offset == 0)
+                                       buffer.append('A');
+                               offset += 1;
+                               break;
+                       case 'B':
+                               buffer.append('P');
+                               if (hashable[offset + 1] == 'B')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'C':
+                               if ((offset > 1)
+                                               && !hasVowel(hashable, offset - 2, hashable.length)
+                                               && hasOneOf(meta01, hashable, (offset - 1), 3)
+                                               && (hashable[offset + 2] != 'I')
+                                               && (hashable[offset + 2] != 'E')
+                                               || hasOneOf(meta02, hashable, (offset - 2), 6)) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               }
+                               if ((offset == 0) && hasOneOf(meta03, hashable, offset, 6)) {
+                                       buffer.append('S');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta04, hashable, offset, 4)) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta05, hashable, offset, 2)) {
+                                       if ((offset > 0) && hasOneOf(meta06, hashable, offset, 4)) {
+                                               buffer.append('K');
+                                               offset += 2;
+                                               break;
+                                       }
+                                       if ((offset == 0)
+                                                       && hasOneOf(meta07, hashable, (offset + 1), 5)
+                                                       || hasOneOf(meta08, hashable, offset + 1, 3)
+                                                       && !hasOneOf(meta09, hashable, 0, 5)) {
+                                               buffer.append('K');
+                                               offset += 2;
+                                               break;
+                                       }
+                                       if (hasOneOf(meta10, hashable, 0, 4)
+                                                       || hasOneOf(meta11, hashable, 0, 3)
+                                                       || hasOneOf(meta12, hashable, offset - 2, 6)
+                                                       || hasOneOf(meta13, hashable, offset + 2, 1)
+                                                       || (hasOneOf(meta14, hashable, offset - 1, 1) || (offset == 0))
+                                                       && hasOneOf(meta15, hashable, offset + 2, 1)) {
+                                               buffer.append('K');
+                                       } else {
+                                               if (offset > 0) {
+                                                       if (hasOneOf(meta16, hashable, 0, 2))
+                                                               buffer.append('K');
+                                                       else
+                                                               buffer.append('X');
+                                               } else {
+                                                       buffer.append('X');
+                                               }
+                                       }
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta17, hashable, offset, 2)
+                                               && !hasOneOf(meta18, hashable, offset, 4)) {
+                                       buffer.append('S');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta19, hashable, offset, 2)) {
+                                       buffer.append('X');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta20, hashable, offset, 2)
+                                               && !((offset == 1) && hashable[0] == 'M')) {
+                                       if (hasOneOf(meta21, hashable, offset + 2, 1)
+                                                       && !hasOneOf(meta22, hashable, offset + 2, 2)) {
+                                               if (((offset == 1) && (hashable[offset - 1] == 'A'))
+                                                               || hasOneOf(meta23, hashable, (offset - 1), 5))
+                                                       buffer.append("KS"); //$NON-NLS-1$
+                                               else
+                                                       buffer.append('X');
+                                               offset += 3;
+                                               break;
+                                       } else {
+                                               buffer.append('K');
+                                               offset += 2;
+                                               break;
+                                       }
+                               }
+                               if (hasOneOf(meta24, hashable, offset, 2)) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               } else if (hasOneOf(meta25, hashable, offset, 2)) {
+                                       buffer.append('S');
+                                       offset += 2;
+                                       break;
+                               }
+                               buffer.append('K');
+                               if (hasOneOf(meta27, hashable, offset + 1, 2))
+                                       offset += 3;
+                               else if (hasOneOf(meta28, hashable, offset + 1, 1)
+                                               && !hasOneOf(meta29, hashable, offset + 1, 2))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case '\u00C7':
+                               buffer.append('S');
+                               offset += 1;
+                               break;
+                       case 'D':
+                               if (hasOneOf(meta30, hashable, offset, 2)) {
+                                       if (hasOneOf(meta31, hashable, offset + 2, 1)) {
+                                               buffer.append('J');
+                                               offset += 3;
+                                               break;
+                                       } else {
+                                               buffer.append("TK"); //$NON-NLS-1$
+                                               offset += 2;
+                                               break;
+                                       }
+                               }
+                               buffer.append('T');
+                               if (hasOneOf(meta32, hashable, offset, 2)) {
+                                       offset += 2;
+                               } else {
+                                       offset += 1;
+                               }
+                               break;
+                       case 'F':
+                               if (hashable[offset + 1] == 'F')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('F');
+                               break;
+                       case 'G':
+                               if (hashable[offset + 1] == 'H') {
+                                       if ((offset > 0)
+                                                       && !hasVowel(hashable, offset - 1, hashable.length)) {
+                                               buffer.append('K');
+                                               offset += 2;
+                                               break;
+                                       }
+                                       if (offset < 3) {
+                                               if (offset == 0) {
+                                                       if (hashable[offset + 2] == 'I')
+                                                               buffer.append('J');
+                                                       else
+                                                               buffer.append('K');
+                                                       offset += 2;
+                                                       break;
+                                               }
+                                       }
+                                       if ((offset > 1)
+                                                       && hasOneOf(meta33, hashable, offset - 2, 1)
+                                                       || ((offset > 2) && hasOneOf(meta34, hashable,
+                                                                       offset - 3, 1))
+                                                       || ((offset > 3) && hasOneOf(meta35, hashable,
+                                                                       offset - 4, 1))) {
+                                               offset += 2;
+                                               break;
+                                       } else {
+                                               if ((offset > 2) && (hashable[offset - 1] == 'U')
+                                                               && hasOneOf(meta36, hashable, offset - 3, 1)) {
+                                                       buffer.append('F');
+                                               } else {
+                                                       if ((offset > 0) && (hashable[offset - 1] != 'I'))
+                                                               buffer.append('K');
+                                               }
+                                               offset += 2;
+                                               break;
+                                       }
+                               }
+                               if (hashable[offset + 1] == 'N') {
+                                       if ((offset == 1) && hasVowel(hashable, 0, hashable.length)
+                                                       && !has95) {
+                                               buffer.append("KN"); //$NON-NLS-1$
+                                       } else {
+                                               if (!hasOneOf(meta37, hashable, offset + 2, 2)
+                                                               && (hashable[offset + 1] != 'Y') && !has95) {
+                                                       buffer.append("N"); //$NON-NLS-1$
+                                               } else {
+                                                       buffer.append("KN"); //$NON-NLS-1$
+                                               }
+                                       }
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta38, hashable, offset + 1, 2) && !has95) {
+                                       buffer.append("KL"); //$NON-NLS-1$
+                                       offset += 2;
+                                       break;
+                               }
+                               if ((offset == 0)
+                                               && ((hashable[offset + 1] == 'Y') || hasOneOf(meta39,
+                                                               hashable, offset + 1, 2))) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               }
+                               if ((hasOneOf(meta40, hashable, offset + 1, 2) || (hashable[offset + 1] == 'Y'))
+                                               && !hasOneOf(meta41, hashable, 0, 6)
+                                               && !hasOneOf(meta42, hashable, offset - 1, 1)
+                                               && !hasOneOf(meta43, hashable, offset - 1, 3)) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta44, hashable, offset + 1, 1)
+                                               || hasOneOf(meta45, hashable, offset - 1, 4)) {
+                                       if (hasOneOf(meta46, hashable, 0, 4)
+                                                       || hasOneOf(meta47, hashable, 0, 3)
+                                                       || hasOneOf(meta48, hashable, offset + 1, 2)) {
+                                               buffer.append('K');
+                                       } else {
+                                               buffer.append('J');
+                                       }
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hashable[offset + 1] == 'G')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('K');
+                               break;
+                       case 'H':
+                               if (((offset == 0) || hasVowel(hashable, offset - 1,
+                                               hashable.length))
+                                               && hasVowel(hashable, offset + 1, hashable.length)) {
+                                       buffer.append('H');
+                                       offset += 2;
+                               } else {
+                                       offset += 1;
+                               }
+                               break;
+                       case 'J':
+                               if (hasOneOf(meta50, hashable, offset, 4)
+                                               || hasOneOf(meta51, hashable, 0, 4)) {
+                                       if ((offset == 0) && (hashable[offset + 4] == ' ')
+                                                       || hasOneOf(meta52, hashable, 0, 4)) {
+                                               buffer.append('H');
+                                       } else {
+                                               buffer.append('J');
+                                       }
+                                       offset += 1;
+                                       break;
+                               }
+                               if ((offset == 0) && !hasOneOf(meta53, hashable, offset, 4)) {
+                                       buffer.append('J');
+                               } else {
+                                       if (hasVowel(hashable, offset - 1, hashable.length)
+                                                       && !has95
+                                                       && ((hashable[offset + 1] == 'A') || hashable[offset + 1] == 'O')) {
+                                               buffer.append('J');
+                                       } else {
+                                               if (offset == (hashable.length - 1)) {
+                                                       buffer.append('J');
+                                               } else {
+                                                       if (!hasOneOf(meta54, hashable, offset + 1, 1)
+                                                                       && !hasOneOf(meta55, hashable, offset - 1,
+                                                                                       1)) {
+                                                               buffer.append('J');
+                                                       }
+                                               }
+                                       }
+                               }
+                               if (hashable[offset + 1] == 'J')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'K':
+                               if (hashable[offset + 1] == 'K')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('K');
+                               break;
+                       case 'L':
+                               if (hashable[offset + 1] == 'L') {
+                                       if (((offset == (hashable.length - 3)) && hasOneOf(meta56,
+                                                       hashable, offset - 1, 4))
+                                                       || ((hasOneOf(meta57, hashable,
+                                                                       (hashable.length - 1) - 1, 2) || hasOneOf(
+                                                                       meta58, hashable, hashable.length - 1, 1)) && hasOneOf(
+                                                                       meta59, hashable, offset - 1, 4))) {
+                                               buffer.append('L');
+                                               offset += 2;
+                                               break;
+                                       }
+                                       offset += 2;
+                               } else
+                                       offset += 1;
+                               buffer.append('L');
+                               break;
+                       case 'M':
+                               if ((hasOneOf(meta60, hashable, offset - 1, 3) && (((offset + 1) == (hashable.length - 1)) || hasOneOf(
+                                               meta61, hashable, offset + 2, 2)))
+                                               || (hashable[offset + 1] == 'M'))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('M');
+                               break;
+                       case 'N':
+                               if (hashable[offset + 1] == 'N')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('N');
+                               break;
+                       case '\u00D1':
+                               offset += 1;
+                               buffer.append('N');
+                               break;
+                       case 'P':
+                               if (hashable[offset + 1] == 'N') {
+                                       buffer.append('F');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta62, hashable, offset + 1, 1))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('P');
+                               break;
+                       case 'Q':
+                               if (hashable[offset + 1] == 'Q')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('K');
+                               break;
+                       case 'R':
+                               if (!((offset == (hashable.length - 1)) && !has95
+                                               && hasOneOf(meta63, hashable, offset - 2, 2) && !hasOneOf(
+                                               meta64, hashable, offset - 4, 2)))
+                                       buffer.append('R');
+                               if (hashable[offset + 1] == 'R')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'S':
+                               if (hasOneOf(meta65, hashable, offset - 1, 3)) {
+                                       offset += 1;
+                                       break;
+                               }
+                               if ((offset == 0) && hasOneOf(meta66, hashable, offset, 5)) {
+                                       buffer.append('X');
+                                       offset += 1;
+                                       break;
+                               }
+                               if (hasOneOf(meta67, hashable, offset, 2)) {
+                                       if (hasOneOf(meta68, hashable, offset + 1, 4))
+                                               buffer.append('S');
+                                       else
+                                               buffer.append('X');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta69, hashable, offset, 3)
+                                               || hasOneOf(meta70, hashable, offset, 4)) {
+                                       buffer.append('S');
+                                       offset += 3;
+                                       break;
+                               }
+                               if (((offset == 0) && hasOneOf(meta71, hashable, offset + 1, 1))
+                                               || hasOneOf(meta72, hashable, offset + 1, 1)) {
+                                       buffer.append('S');
+                                       if (hasOneOf(meta73, hashable, offset + 1, 1))
+                                               offset += 2;
+                                       else
+                                               offset += 1;
+                                       break;
+                               }
+                               if (hasOneOf(meta74, hashable, offset, 2)) {
+                                       if (hashable[offset + 2] == 'H')
+                                               if (hasOneOf(meta75, hashable, offset + 3, 2)) {
+                                                       if (hasOneOf(meta76, hashable, offset + 3, 2)) {
+                                                               buffer.append("X"); //$NON-NLS-1$
+                                                       } else {
+                                                               buffer.append("SK"); //$NON-NLS-1$
+                                                       }
+                                                       offset += 3;
+                                                       break;
+                                               } else {
+                                                       buffer.append('X');
+                                                       offset += 3;
+                                                       break;
+                                               }
+                                       if (hasOneOf(meta77, hashable, offset + 2, 1)) {
+                                               buffer.append('S');
+                                               offset += 3;
+                                               break;
+                                       }
+                                       buffer.append("SK"); //$NON-NLS-1$
+                                       offset += 3;
+                                       break;
+                               }
+                               if (!((offset == (hashable.length - 1)) && hasOneOf(meta78,
+                                               hashable, offset - 2, 2)))
+                                       buffer.append('S');
+                               if (hasOneOf(meta79, hashable, offset + 1, 1))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'T':
+                               if (hasOneOf(meta80, hashable, offset, 4)) {
+                                       buffer.append('X');
+                                       offset += 3;
+                                       break;
+                               }
+                               if (hasOneOf(meta81, hashable, offset, 3)) {
+                                       buffer.append('X');
+                                       offset += 3;
+                                       break;
+                               }
+                               if (hasOneOf(meta82, hashable, offset, 2)
+                                               || hasOneOf(meta83, hashable, offset, 3)) {
+                                       if (hasOneOf(meta84, hashable, (offset + 2), 2)
+                                                       || hasOneOf(meta85, hashable, 0, 4)
+                                                       || hasOneOf(meta86, hashable, 0, 3)) {
+                                               buffer.append('T');
+                                       } else {
+                                               buffer.append('0');
+                                       }
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta87, hashable, offset + 1, 1)) {
+                                       offset += 2;
+                               } else
+                                       offset += 1;
+                               buffer.append('T');
+                               break;
+                       case 'V':
+                               if (hashable[offset + 1] == 'V')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('F');
+                               break;
+                       case 'W':
+                               if (hasOneOf(meta88, hashable, offset, 2)) {
+                                       buffer.append('R');
+                                       offset += 2;
+                                       break;
+                               }
+                               if ((offset == 0)
+                                               && (hasVowel(hashable, offset + 1, hashable.length) || hasOneOf(
+                                                               meta89, hashable, offset, 2))) {
+                                       buffer.append('A');
+                               }
+                               if (((offset == (hashable.length - 1)) && hasVowel(hashable,
+                                               offset - 1, hashable.length))
+                                               || hasOneOf(meta90, hashable, offset - 1, 5)
+                                               || hasOneOf(meta91, hashable, 0, 3)) {
+                                       buffer.append('F');
+                                       offset += 1;
+                                       break;
+                               }
+                               if (hasOneOf(meta92, hashable, offset, 4)) {
+                                       buffer.append("TS"); //$NON-NLS-1$
+                                       offset += 4;
+                                       break;
+                               }
+                               offset += 1;
+                               break;
+                       case 'X':
+                               if (!((offset == (hashable.length - 1)) && (hasOneOf(meta93,
+                                               hashable, offset - 3, 3) || hasOneOf(meta94, hashable,
+                                               offset - 2, 2))))
+                                       buffer.append("KS"); //$NON-NLS-1$
+                               if (hasOneOf(meta49, hashable, offset + 1, 1))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'Z':
+                               if (hashable[offset + 1] == 'H') {
+                                       buffer.append('J');
+                                       offset += 2;
+                                       break;
+                               } else {
+                                       buffer.append('S');
+                               }
+                               if (hashable[offset + 1] == 'Z')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       default:
+                               offset += 1;
+                       }
+               }
+               return buffer.toString();
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.IPhoneticHasher#getMutators()
+        */
+       public final char[] getMutators() {
+               return MUTATOR_CHARACTERS;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultSpellChecker.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultSpellChecker.java
new file mode 100644 (file)
index 0000000..2b4da35
--- /dev/null
@@ -0,0 +1,366 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Default spell checker for standard text.
+ * 
+ * @since 3.0
+ */
+public class DefaultSpellChecker implements ISpellChecker {
+
+       /** Array of url prefixes */
+       public static final String[] URL_PREFIXES = new String[] {
+                       "http://", "https://", "www.", "ftp://", "ftps://", "news://", "mailto://" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+
+       /**
+        * Does this word contain digits?
+        * 
+        * @param word
+        *            The word to check
+        * @return <code>true</code> iff this word contains digits,
+        *         <code>false></code> otherwise
+        */
+       protected static boolean isDigits(final String word) {
+
+               for (int index = 0; index < word.length(); index++) {
+
+                       if (Character.isDigit(word.charAt(index)))
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Does this word contain mixed-case letters?
+        * 
+        * @param word
+        *            The word to check
+        * @param sentence
+        *            <code>true</code> iff the specified word starts a new
+        *            sentence, <code>false</code> otherwise
+        * @return <code>true</code> iff the contains mixed-case letters,
+        *         <code>false</code> otherwise
+        */
+       protected static boolean isMixedCase(final String word,
+                       final boolean sentence) {
+
+               final int length = word.length();
+               boolean upper = Character.isUpperCase(word.charAt(0));
+
+               if (sentence && upper && (length > 1))
+                       upper = Character.isUpperCase(word.charAt(1));
+
+               if (upper) {
+
+                       for (int index = length - 1; index > 0; index--) {
+                               if (Character.isLowerCase(word.charAt(index)))
+                                       return true;
+                       }
+               } else {
+
+                       for (int index = length - 1; index > 0; index--) {
+                               if (Character.isUpperCase(word.charAt(index)))
+                                       return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Does this word contain upper-case letters only?
+        * 
+        * @param word
+        *            The word to check
+        * @return <code>true</code> iff this word only contains upper-case
+        *         letters, <code>false</code> otherwise
+        */
+       protected static boolean isUpperCase(final String word) {
+
+               for (int index = word.length() - 1; index >= 0; index--) {
+
+                       if (Character.isLowerCase(word.charAt(index)))
+                               return false;
+               }
+               return true;
+       }
+
+       /**
+        * Does this word look like an URL?
+        * 
+        * @param word
+        *            The word to check
+        * @return <code>true</code> iff this word looks like an URL,
+        *         <code>false</code> otherwise
+        */
+       protected static boolean isUrl(final String word) {
+
+               for (int index = 0; index < URL_PREFIXES.length; index++) {
+
+                       if (word.startsWith(URL_PREFIXES[index]))
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * The dictionaries to use for spell-checking. Synchronized to avoid
+        * concurrent modifications.
+        */
+       private final Set fDictionaries = Collections
+                       .synchronizedSet(new HashSet());
+
+       /**
+        * The words to be ignored. Synchronized to avoid concurrent modifications.
+        */
+       private final Set fIgnored = Collections.synchronizedSet(new HashSet());
+
+       /**
+        * The spell event listeners. Synchronized to avoid concurrent
+        * modifications.
+        */
+       private final Set fListeners = Collections.synchronizedSet(new HashSet());
+
+       /**
+        * The preference store. Assumes the <code>IPreferenceStore</code>
+        * implementation is thread safe.
+        */
+       private final IPreferenceStore fPreferences;
+
+       /**
+        * Creates a new default spell-checker.
+        * 
+        * @param store
+        *            The preference store for this spell-checker
+        */
+       public DefaultSpellChecker(final IPreferenceStore store) {
+               fPreferences = store;
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellChecker#addDictionary(org.eclipse.spelling.done.ISpellDictionary)
+        */
+       public final void addDictionary(final ISpellDictionary dictionary) {
+               // synchronizing is necessary as this is a write access
+               fDictionaries.add(dictionary);
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellChecker#addListener(org.eclipse.spelling.done.ISpellEventListener)
+        */
+       public final void addListener(final ISpellEventListener listener) {
+               // synchronizing is necessary as this is a write access
+               fListeners.add(listener);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellChecker#acceptsWords()
+        */
+       public boolean acceptsWords() {
+               // synchronizing might not be needed here since acceptWords is
+               // a read-only access and only called in the same thread as
+               // the modifing methods add/checkWord (?)
+               Set copy;
+               synchronized (fDictionaries) {
+                       copy = new HashSet(fDictionaries);
+               }
+
+               ISpellDictionary dictionary = null;
+               for (final Iterator iterator = copy.iterator(); iterator.hasNext();) {
+
+                       dictionary = (ISpellDictionary) iterator.next();
+                       if (dictionary.acceptsWords())
+                               return true;
+               }
+               return false;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellChecker#addWord(java.lang.String)
+        */
+       public void addWord(final String word) {
+               // synchronizing is necessary as this is a write access
+               Set copy;
+               synchronized (fDictionaries) {
+                       copy = new HashSet(fDictionaries);
+               }
+
+               final String addable = word.toLowerCase();
+               fIgnored.add(addable);
+
+               ISpellDictionary dictionary = null;
+               for (final Iterator iterator = copy.iterator(); iterator.hasNext();) {
+
+                       dictionary = (ISpellDictionary) iterator.next();
+                       dictionary.addWord(addable);
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellChecker#checkWord(java.lang.String)
+        */
+       public final void checkWord(final String word) {
+               // synchronizing is necessary as this is a write access
+               fIgnored.remove(word.toLowerCase());
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellChecker#execute(org.eclipse.spelling.ISpellCheckTokenizer)
+        */
+       public void execute(final ISpellCheckIterator iterator) {
+
+               final boolean ignoreDigits = fPreferences
+                               .getBoolean(ISpellCheckPreferenceKeys.SPELLING_IGNORE_DIGITS);
+               final boolean ignoreMixed = fPreferences
+                               .getBoolean(ISpellCheckPreferenceKeys.SPELLING_IGNORE_MIXED);
+               final boolean ignoreSentence = fPreferences
+                               .getBoolean(ISpellCheckPreferenceKeys.SPELLING_IGNORE_SENTENCE);
+               final boolean ignoreUpper = fPreferences
+                               .getBoolean(ISpellCheckPreferenceKeys.SPELLING_IGNORE_UPPER);
+               final boolean ignoreURLS = fPreferences
+                               .getBoolean(ISpellCheckPreferenceKeys.SPELLING_IGNORE_URLS);
+
+               String word = null;
+               boolean starts = false;
+
+               while (iterator.hasNext()) {
+
+                       word = (String) iterator.next();
+                       if (word != null) {
+
+                               // synchronizing is necessary as this is called inside the
+                               // reconciler
+                               if (!fIgnored.contains(word)) {
+
+                                       starts = iterator.startsSentence();
+                                       if (!isCorrect(word)) {
+
+                                               boolean isMixed = isMixedCase(word, true);
+                                               boolean isUpper = isUpperCase(word);
+                                               boolean isDigits = isDigits(word);
+                                               boolean isURL = isUrl(word);
+
+                                               if (!ignoreMixed && isMixed || !ignoreUpper && isUpper
+                                                               || !ignoreDigits && isDigits || !ignoreURLS
+                                                               && isURL
+                                                               || !(isMixed || isUpper || isDigits || isURL))
+                                                       fireEvent(new SpellEvent(this, word, iterator
+                                                                       .getBegin(), iterator.getEnd(), starts,
+                                                                       false));
+
+                                       } else {
+
+                                               if (!ignoreSentence && starts
+                                                               && Character.isLowerCase(word.charAt(0)))
+                                                       fireEvent(new SpellEvent(this, word, iterator
+                                                                       .getBegin(), iterator.getEnd(), true, true));
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Fires the specified event.
+        * 
+        * @param event
+        *            Event to fire
+        */
+       protected final void fireEvent(final ISpellEvent event) {
+               // synchronizing is necessary as this is called from execute
+               Set copy;
+               synchronized (fListeners) {
+                       copy = new HashSet(fListeners);
+               }
+               for (final Iterator iterator = copy.iterator(); iterator.hasNext();) {
+                       ((ISpellEventListener) iterator.next()).handle(event);
+               }
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellChecker#getProposals(java.lang.String,boolean)
+        */
+       public Set getProposals(final String word, final boolean sentence) {
+
+               // synchronizing might not be needed here since getProposals is
+               // a read-only access and only called in the same thread as
+               // the modifing methods add/removeDictionary (?)
+               Set copy;
+               synchronized (fDictionaries) {
+                       copy = new HashSet(fDictionaries);
+               }
+
+               ISpellDictionary dictionary = null;
+               final HashSet proposals = new HashSet();
+
+               for (final Iterator iterator = copy.iterator(); iterator.hasNext();) {
+
+                       dictionary = (ISpellDictionary) iterator.next();
+                       proposals.addAll(dictionary.getProposals(word, sentence));
+               }
+               return proposals;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellChecker#ignoreWord(java.lang.String)
+        */
+       public final void ignoreWord(final String word) {
+               // synchronizing is necessary as this is a write access
+               fIgnored.add(word.toLowerCase());
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellChecker#isCorrect(java.lang.String)
+        */
+       public final boolean isCorrect(final String word) {
+               // synchronizing is necessary as this is called from execute
+               Set copy;
+               synchronized (fDictionaries) {
+                       copy = new HashSet(fDictionaries);
+               }
+
+               if (fIgnored.contains(word.toLowerCase()))
+                       return true;
+
+               ISpellDictionary dictionary = null;
+               for (final Iterator iterator = copy.iterator(); iterator.hasNext();) {
+
+                       dictionary = (ISpellDictionary) iterator.next();
+                       if (dictionary.isCorrect(word))
+                               return true;
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellChecker#removeDictionary(org.eclipse.spelling.done.ISpellDictionary)
+        */
+       public final void removeDictionary(final ISpellDictionary dictionary) {
+               // synchronizing is necessary as this is a write access
+               fDictionaries.remove(dictionary);
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.ISpellChecker#removeListener(org.eclipse.spelling.done.ISpellEventListener)
+        */
+       public final void removeListener(final ISpellEventListener listener) {
+               // synchronizing is necessary as this is a write access
+               fListeners.remove(listener);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/IPhoneticDistanceAlgorithm.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/IPhoneticDistanceAlgorithm.java
new file mode 100644 (file)
index 0000000..9dc335e
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+/**
+ * Interface of algorithms to compute the phonetic distance between two words.
+ * 
+ * @since 3.0
+ */
+public interface IPhoneticDistanceAlgorithm {
+
+       /**
+        * Returns the non-negative phonetic distance between two words
+        * 
+        * @param from
+        *            The first word
+        * @param to
+        *            The second word
+        * @return The non-negative phonetic distance between the words.
+        */
+       public int getDistance(String from, String to);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/IPhoneticHashProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/IPhoneticHashProvider.java
new file mode 100644 (file)
index 0000000..ddc9b82
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+/**
+ * Interface of hashers to compute the phonetic hash for a word.
+ * 
+ * @since 3.0
+ */
+public interface IPhoneticHashProvider {
+
+       /**
+        * Returns the phonetic hash for the word.
+        * 
+        * @param word
+        *            The word to get the phonetic hash for
+        * @return The phonetic hash for the word
+        */
+       public String getHash(String word);
+
+       /**
+        * Returns an array of characters to compute possible mutations.
+        * 
+        * @return Array of possible mutator characters
+        */
+       public char[] getMutators();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckEngine.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckEngine.java
new file mode 100644 (file)
index 0000000..b857bd7
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.util.Locale;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Interface for spell-check engines.
+ * 
+ * @since 3.0
+ */
+public interface ISpellCheckEngine {
+
+       /**
+        * Creates a configured instance of a spell-checker that uses the
+        * appropriate dictionaries.
+        * 
+        * @param locale
+        *            The locale to get the spell checker for
+        * @param store
+        *            The preference store for the spell-checker
+        * @return A configured instance of a spell checker, or <code>null</code>
+        *         iff no dictionary could be found for that locale
+        */
+       ISpellChecker createSpellChecker(Locale locale, IPreferenceStore store);
+
+       /**
+        * Returns the current locale of the spell check engine.
+        * 
+        * @return The current locale of the engine
+        */
+       Locale getLocale();
+
+       /**
+        * Registers a dictionary for all locales available on the platform.
+        * <p>
+        * This call is equivalent to calling
+        * <code>registerDictionary(Locale,ISpellDictionary)</code> for each of
+        * the locales returned by <code>Locale.getAvailableLocales()</code>.
+        * </p>
+        * 
+        * @param dictionary
+        *            The dictionary to register
+        */
+       void registerDictionary(ISpellDictionary dictionary);
+
+       /**
+        * Registers a dictionary tuned for the specified locale with this engine.
+        * 
+        * @param locale
+        *            The locale to register the dictionary with
+        * @param dictionary
+        *            The dictionary to register
+        */
+       void registerDictionary(Locale locale, ISpellDictionary dictionary);
+
+       /**
+        * Unloads the spell check engine and its associated components.
+        * <p>
+        * All registered dictionaries are unloaded and the engine unregisters for
+        * preference changes. After a new call to
+        * <code>getSpellChecker(Locale)</code>, it registers again for
+        * preference changes. The dictionaries perform lazy loading, that is to say
+        * on the next query they reload their associated word lists.
+        */
+       void unload();
+
+       /**
+        * Unregisters a dictionary previously registered either by a call to
+        * <code>registerDictionary(Locale,ISpellDictionary)</code> or
+        * <code>registerDictionary(ISpellDictionary)</code>. If the dictionary
+        * was not registered before, nothing happens.
+        * 
+        * @param dictionary
+        *            The dictionary to unregister
+        */
+       void unregisterDictionary(ISpellDictionary dictionary);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckIterator.java
new file mode 100644 (file)
index 0000000..6f1ec96
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.util.Iterator;
+
+/**
+ * Interface for iterators used for spell-checking.
+ * 
+ * @since 3.0
+ */
+public interface ISpellCheckIterator extends Iterator {
+
+       /**
+        * Returns the begin index (inclusive) of the current word.
+        * 
+        * @return The begin index of the current word
+        */
+       public int getBegin();
+
+       /**
+        * Returns the end index (exclusive) of the current word.
+        * 
+        * @return The end index of the current word
+        */
+       public int getEnd();
+
+       /**
+        * Does the current word start a new sentence?
+        * 
+        * @return <code>true<code> iff the current word starts a new sentence, <code>false</code> otherwise
+        */
+       public boolean startsSentence();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckPreferenceKeys.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellCheckPreferenceKeys.java
new file mode 100644 (file)
index 0000000..b11c817
--- /dev/null
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+/**
+ * Preference keys for the comment spell-checker.
+ * 
+ * @since 3.0
+ */
+public interface ISpellCheckPreferenceKeys {
+
+       /**
+        * A named preference that controls whether spell-checking should be
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String SPELLING_CHECK_SPELLING = "spelling_check_spelling"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether words containing digits should
+        * be skipped during spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String SPELLING_IGNORE_DIGITS = "spelling_ignore_digits"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether mixed case words should be
+        * skipped during spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String SPELLING_IGNORE_MIXED = "spelling_ignore_mixed"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether sentence capitalization should
+        * be ignored during spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String SPELLING_IGNORE_SENTENCE = "spelling_ignore_sentence"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether upper case words should be
+        * skipped during spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String SPELLING_IGNORE_UPPER = "spelling_ignore_upper"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether urls should be ignored during
+        * spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String SPELLING_IGNORE_URLS = "spelling_ignore_urls"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the locale used for spell-checking.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        */
+       public final static String SPELLING_LOCALE = "spelling_locale"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the number of proposals offered during
+        * spell-checking.
+        * <p>
+        * Value is of type <code>Integer</code>.
+        * </p>
+        */
+       public final static String SPELLING_PROPOSAL_THRESHOLD = "spelling_proposal_threshold"; //$NON-NLS-1$
+
+       /**
+        * A named preference that specifies the workspace user dictionary.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        */
+       public final static String SPELLING_USER_DICTIONARY = "spelling_user_dictionary"; //$NON-NLS-1$
+
+       /**
+        * A named preference that specifies whether spelling dictionaries are
+        * available to content assist.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String SPELLING_ENABLE_CONTENTASSIST = "spelling_enable_contentassist"; //$NON-NLS-1$
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellChecker.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellChecker.java
new file mode 100644 (file)
index 0000000..13a9a92
--- /dev/null
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.util.Set;
+
+/**
+ * Interface for spell-checkers.
+ * 
+ * @since 3.0
+ */
+public interface ISpellChecker {
+
+       /**
+        * Adds a dictionary to the list of active dictionaries.
+        * 
+        * @param dictionary
+        *            The dictionary to add
+        */
+       public void addDictionary(ISpellDictionary dictionary);
+
+       /**
+        * Adds a spell event listener to the active listeners.
+        * 
+        * @param listener
+        *            The listener to add
+        */
+       public void addListener(ISpellEventListener listener);
+
+       /**
+        * Returns whether this spell checker accepts word additions.
+        * 
+        * @return <code>true</code> if word additions are accepted,
+        *         <code>false</code> otherwise
+        */
+       public boolean acceptsWords();
+
+       /**
+        * Adds the specified word to the set of correct words.
+        * 
+        * @param word
+        *            The word to add to the set of correct words
+        */
+       public void addWord(String word);
+
+       /**
+        * Checks the specified word until calling <code>ignoreWord(String)</code>.
+        * 
+        * @param word
+        *            The word to check
+        */
+       public void checkWord(String word);
+
+       /**
+        * Checks the spelling with the spell-check iterator. Implementations must
+        * be thread safe as this may be called inside a reconciler thread.
+        * 
+        * @param iterator
+        *            The iterator to use for spell-checking
+        */
+       public void execute(ISpellCheckIterator iterator);
+
+       /**
+        * Returns the ranked proposals for a word.
+        * 
+        * @param word
+        *            The word to retrieve the proposals for
+        * @param sentence
+        *            <code>true</code> iff the proposals should start a sentence,
+        *            <code>false</code> otherwise
+        * @return Set of ranked proposals for the word
+        */
+       public Set getProposals(String word, boolean sentence);
+
+       /**
+        * Ignores the specified word until calling <code>checkWord(String)</code>.
+        * 
+        * @param word
+        *            The word to ignore
+        */
+       public void ignoreWord(String word);
+
+       /**
+        * Is the specified word correctly spelled? Implementations must be thread
+        * safe as this may be called from within a reconciler thread.
+        * 
+        * @param word
+        *            The word to check its spelling
+        * @return <code>true</code> iff the word is correctly spelled,
+        *         <code>false</code> otherwise
+        */
+       public boolean isCorrect(String word);
+
+       /**
+        * Remove a dictionary from the list of active dictionaries.
+        * 
+        * @param dictionary
+        *            The dictionary to remove
+        */
+       public void removeDictionary(ISpellDictionary dictionary);
+
+       /**
+        * Removes a spell event listener from the active listeners.
+        * 
+        * @param listener
+        *            The listener to remove
+        */
+       public void removeListener(ISpellEventListener listener);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellDictionary.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellDictionary.java
new file mode 100644 (file)
index 0000000..213b548
--- /dev/null
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.util.Set;
+
+/**
+ * Interface of dictionaries to use for spell-checking.
+ * 
+ * @since 3.0
+ */
+public interface ISpellDictionary {
+
+       /**
+        * Returns whether this dictionary accepts new words.
+        * 
+        * @return <code>true</code> if this dictionary accepts new words,
+        *         <code>false</code> otherwise
+        */
+       public boolean acceptsWords();
+
+       /**
+        * Externalizes the specified word.
+        * 
+        * @param word
+        *            The word to externalize in the dictionary
+        */
+       public void addWord(String word);
+
+       /**
+        * Returns the ranked word proposals for an incorrectly spelled word.
+        * 
+        * @param word
+        *            The word to retrieve the proposals for
+        * @param sentence
+        *            <code>true</code> iff the proposals start a new sentence,
+        *            <code>false</code> otherwise
+        * @return Array of ranked word proposals
+        */
+       public Set getProposals(String word, boolean sentence);
+
+       /**
+        * Is the specified word correctly spelled?
+        * 
+        * @param word
+        *            The word to spell-check
+        * @return <code>true</code> iff this word is correctly spelled,
+        *         <code>false</code> otherwise.
+        */
+       public boolean isCorrect(String word);
+
+       /**
+        * Is the dictionary loaded?
+        * 
+        * @return <code>true</code> iff it is loaded, <code>false</code>
+        *         otherwise
+        */
+       public boolean isLoaded();
+
+       /**
+        * Empties the dictionary.
+        */
+       public void unload();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellEvent.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellEvent.java
new file mode 100644 (file)
index 0000000..ccbd107
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.util.Set;
+
+/**
+ * Event fired by spell-checkers.
+ * 
+ * @since 3.0
+ */
+public interface ISpellEvent {
+
+       /**
+        * Returns the begin index of the incorrectly spelled word.
+        * 
+        * @return The begin index of the word
+        */
+       public int getBegin();
+
+       /**
+        * Returns the end index of the incorrectly spelled word.
+        * 
+        * @return The end index of the word
+        */
+       public int getEnd();
+
+       /**
+        * Returns the proposals for the incorrectly spelled word.
+        * 
+        * @return Array of proposals for the word
+        */
+       public Set getProposals();
+
+       /**
+        * Returns the incorrectly spelled word.
+        * 
+        * @return The incorrect word
+        */
+       public String getWord();
+
+       /**
+        * Was the incorrectly spelled word found in the dictionary?
+        * 
+        * @return <code>true</code> iff the word was found, <code>false</code>
+        *         otherwise
+        */
+       public boolean isMatch();
+
+       /**
+        * Does the incorrectly spelled word start a new sentence?
+        * 
+        * @return <code>true<code> iff the word starts a new sentence, <code>false</code> otherwise
+        */
+       public boolean isStart();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellEventListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/ISpellEventListener.java
new file mode 100644 (file)
index 0000000..bd38687
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+/**
+ * Interface for spell event listeners.
+ * 
+ * @since 3.0
+ */
+public interface ISpellEventListener {
+
+       /**
+        * Handles a spell event.
+        * 
+        * @param event
+        *            Event to handle
+        */
+       public void handle(ISpellEvent event);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/LocaleSensitiveSpellDictionary.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/LocaleSensitiveSpellDictionary.java
new file mode 100644 (file)
index 0000000..a80ba1a
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Locale;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+
+/**
+ * Platform wide read-only locale sensitive dictionary for spell-checking.
+ * 
+ * @since 3.0
+ */
+public class LocaleSensitiveSpellDictionary extends AbstractSpellDictionary {
+
+       /** The locale of this dictionary */
+       private final Locale fLocale;
+
+       /** The location of the dictionaries */
+       private final URL fLocation;
+
+       /**
+        * Creates a new locale sensitive spell dictionary.
+        * 
+        * @param locale
+        *            The locale for this dictionary
+        * @param location
+        *            The location of the locale sensitive dictionaries
+        */
+       public LocaleSensitiveSpellDictionary(final Locale locale,
+                       final URL location) {
+               fLocation = location;
+               fLocale = locale;
+       }
+
+       /**
+        * Returns the locale of this dictionary.
+        * 
+        * @return The locale of this dictionary
+        */
+       public final Locale getLocale() {
+               return fLocale;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.AbstractSpellDictionary#getURL()
+        */
+       protected final URL getURL() throws MalformedURLException {
+               return new URL(
+                               fLocation,
+                               fLocale.toString().toLowerCase()
+                                               + "." + PHPUIMessages.getString("Spelling.dictionary.file.extension")); //$NON-NLS-1$ //$NON-NLS-2$
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/PersistentSpellDictionary.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/PersistentSpellDictionary.java
new file mode 100644 (file)
index 0000000..20cb55c
--- /dev/null
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * Persistent modifiable word-list based dictionary.
+ * 
+ * @since 3.0
+ */
+public class PersistentSpellDictionary extends AbstractSpellDictionary {
+
+       /** The word list location */
+       private final URL fLocation;
+
+       /**
+        * Creates a new persistent spell dictionary.
+        * 
+        * @param url
+        *            The URL of the word list for this dictionary
+        */
+       public PersistentSpellDictionary(final URL url) {
+               fLocation = url;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.text.spelling.engine.AbstractSpellDictionary#acceptsWords()
+        */
+       public boolean acceptsWords() {
+               return true;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary#addWord(java.lang.String)
+        */
+       public void addWord(final String word) {
+
+               if (!isCorrect(word)) {
+
+                       hashWord(word);
+                       try {
+
+                               final FileWriter writer = new FileWriter(fLocation.getPath(),
+                                               true);
+                               writer.write(word);
+                               writer.write("\n"); //$NON-NLS-1$
+                               writer.close();
+
+                       } catch (IOException exception) {
+                               // Do nothing
+                       }
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.AbstractSpellDictionary#getURL()
+        */
+       protected final URL getURL() {
+               return fLocation;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/RankedWordProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/RankedWordProposal.java
new file mode 100644 (file)
index 0000000..282d05f
--- /dev/null
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+/**
+ * Ranked word proposal for quick fix and content assist.
+ * 
+ * @since 3.0
+ */
+public class RankedWordProposal implements Comparable {
+
+       /** The word rank */
+       private int fRank;
+
+       /** The word text */
+       private final String fText;
+
+       /**
+        * Creates a new ranked word proposal.
+        * 
+        * @param text
+        *            The text of this proposal
+        * @param rank
+        *            The rank of this proposal
+        */
+       public RankedWordProposal(final String text, final int rank) {
+               fText = text;
+               fRank = rank;
+       }
+
+       /*
+        * @see java.lang.Comparable#compareTo(java.lang.Object)
+        */
+       public final int compareTo(Object object) {
+
+               final RankedWordProposal word = (RankedWordProposal) object;
+               final int rank = word.getRank();
+
+               if (fRank < rank)
+                       return -1;
+
+               if (fRank > rank)
+                       return 1;
+
+               return 0;
+       }
+
+       /*
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public final boolean equals(Object object) {
+
+               if (object instanceof RankedWordProposal)
+                       return object.hashCode() == hashCode();
+
+               return false;
+       }
+
+       /**
+        * Returns the rank of the word
+        * 
+        * @return The rank of the word
+        */
+       public final int getRank() {
+               return fRank;
+       }
+
+       /**
+        * Returns the text of this word.
+        * 
+        * @return The text of this word
+        */
+       public final String getText() {
+               return fText;
+       }
+
+       /*
+        * @see java.lang.Object#hashCode()
+        */
+       public final int hashCode() {
+               return fText.hashCode();
+       }
+
+       /**
+        * Sets the rank of the word.
+        * 
+        * @param rank
+        *            The rank to set
+        */
+       public final void setRank(final int rank) {
+               fRank = rank;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/SpellEvent.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/SpellEvent.java
new file mode 100644 (file)
index 0000000..da9d671
--- /dev/null
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+import java.util.Set;
+
+/**
+ * Spell event fired for words detected by a spell-check iterator.
+ * 
+ * @since 3.0
+ */
+public class SpellEvent implements ISpellEvent {
+
+       /** The begin index of the word in the spell-checkable medium */
+       private final int fBegin;
+
+       /** The spell-checker that causes the event */
+       private final ISpellChecker fChecker;
+
+       /** The end index of the word in the spell-checkable medium */
+       private final int fEnd;
+
+       /** Was the word found in the dictionary? */
+       private final boolean fMatch;
+
+       /** Does the word start a new sentence? */
+       private final boolean fSentence;
+
+       /** The word that causes the spell event */
+       private final String fWord;
+
+       /**
+        * Creates a new spell event.
+        * 
+        * @param checker
+        *            The spell-checker that causes the event
+        * @param word
+        *            The word that causes the event
+        * @param begin
+        *            The begin index of the word in the spell-checkable medium
+        * @param end
+        *            The end index of the word in the spell-checkable medium
+        * @param sentence
+        *            <code>true</code> iff the word starts a new sentence,
+        *            <code>false</code> otherwise
+        * @param match
+        *            <code>true</code> iff the word was found in the dictionary,
+        *            <code>false</code> otherwise
+        */
+       protected SpellEvent(final ISpellChecker checker, final String word,
+                       final int begin, final int end, final boolean sentence,
+                       final boolean match) {
+               fChecker = checker;
+               fEnd = end;
+               fBegin = begin;
+               fWord = word;
+               fSentence = sentence;
+               fMatch = match;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEvent#getBegin()
+        */
+       public final int getBegin() {
+               return fBegin;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEvent#getEnd()
+        */
+       public final int getEnd() {
+               return fEnd;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEvent#getProposals()
+        */
+       public final Set getProposals() {
+               return fChecker.getProposals(fWord, fSentence);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEvent#getWord()
+        */
+       public final String getWord() {
+               return fWord;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEvent#isMatch()
+        */
+       public final boolean isMatch() {
+               return fMatch;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellEvent#isStart()
+        */
+       public final boolean isStart() {
+               return fSentence;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/package.html b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/package.html
new file mode 100644 (file)
index 0000000..6ecebe0
--- /dev/null
@@ -0,0 +1,84 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; I) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides the core functionality for spell-checking documents
+<h2>
+Package Specification</h2>
+This package provides the interfaces for the notions of dictionary, edit distance, phonetic hash, 
+spell event and spell-check iterator. For most of these interfaces a default implementation 
+for english languages is provided. These implementations can be reused in custom dictionaries or 
+spell-check iterators, or replaced by more specialized algorithms for a particular group of languages.
+<h3>
+Spell Check Engine</h3>
+The central point to access the spell-checker functionality is the interface <tt>ISpellCheckEngine</tt>. 
+Implementations of this interface provide support for life-cycle management, registering and unregistering
+dictionaries, changing the locale of the engine and creating a spell-checker for a specific language.
+<p>
+The following steps are needed to obtain a spell-checker for a specific language:
+<ul>
+<li>Create an instance of <tt>ISpellCheckEngine</tt>. In this package, no default implementation is provided, 
+since the management of the dictionary registering and loading is application dependent. Usually, instances 
+of <tt>ISpellCheckEngine</tt> are implemented as singletons.</li>
+<li>Create the appropriate dictionaries that should be used during the spell-check process. All dictionaries that 
+can be registered with <tt>ISpellCheckEngine</tt> must implement the interface <tt>ISpellCheckDictionary</tt>. 
+For this interface, an abstract implementation is provided in the class <tt>AbstractSpellDictionary</tt>.
+Depending on the language of the words contained in this dictionary, custom algorithms for the phonetic hash
+ (<tt>IPhoneticHashProvider</tt>) and the edit distance (<tt>IPhoneticDistanceAlgorithm</tt>) should be implemented 
+ and registered with the dictionary.</li>
+ <li>Instances of spell-checkers can now be created by calling <tt>createSpellChecker(Locale)</tt>, where the locale 
+ denotes the language that the spell-checker should use while executing.</li>
+</ul>
+When requesting a new spell-checker with a different locale via <tt>createSpellChecker(Locale)</tt>, the spell-checker is 
+reconfigured with the new dictionaries. More concretely, the old dictionary is unregistered and a new one registered for the 
+desired locale is associated with the spell-checker. If no such dictionary is available, no spell-checker is returned and 
+the locale of the engine is reset to its default locale.
+<h3>
+Dictionaries</h3>
+Dictionaries are the data structures to hold word lists for a particular language. All implementations of dictionaries must 
+implement the interface <tt>ISpellDictionary</tt>. It provides support for life-cycle management as well as the facility to query 
+words from the list, add words to the list and get correction proposals for incorrectly spelt words.
+<p>
+This package provides a default implementation of a dictionary (<tt>AbstractSpellDictionary</tt>) that uses algorithms 
+convenient for english languages. <br>
+Every dictionary needs two kinds of algorithms to be plugged in:
+<ul>
+<li>An edit distance algorithm: Edit distance algorithms implement the interface <tt>IPhoneticDistanceAlgorithm</tt>. The algorithm 
+is used to determine the similarity between two words. This package provides a default implementation for languages using the latin alphabet (<tt>DefaultPhoneticDistanceAlgorithm</tt>). 
+The default algorithm uses the Levenshtein text edit distance.</li>
+<li>A hash algorithm: Phonetic hash providers implement the interface <tt>IPhoneticHashProvider</tt>. The purpose of 
+phonetic hashes is to have a representation of words which allows comparing it to other, similar words. This package provides a default 
+implementation which is convenient for slavic and english languages. It uses the double metaphone algorithm by published 
+Lawrence Philips.</li>
+</ul>
+By plugging in custom implementations of one or both of these algorithms the abstract implementation <tt>AbstractSpellDictionary</tt> can 
+be customized to specified languages and alphabets.
+<h3>
+Spell Check Iterators</h3>
+Instances of <tt>ISpellChecker</tt> are usually language-, locale- and medium independent implementations and therefore need an input provider. The 
+interface <tt>ISpellCheckIterator</tt> serves this purpose by abstracting the tokenizing of text media to a simple iteration. The actual spell-check process 
+is launched by calling <tt>ISpellChecker#execute(ISpellCheckIterator)</tt>. This method uses the indicated spell-check iterator to determine the 
+words that are to be spell-checked. This package provides no default implementation of a spell-check iterator.
+<h3>
+Event Handling</h3>
+To communicate the results of a spell-check pass, spell-checkers fire spell events that inform listeners about the status 
+of a particular word being spell-checked. Instances that are interested in receiving spell events must implement 
+the interface <tt>ISpellEventListener</tt> and register with the spell-checker before the spell-check process starts.<p>
+A spell event contains the following information:
+<ul>
+<li>The word being spell-checked</li>
+<li>The begin index of the current word in the text medium</li>
+<li>The end index in the text medium</li>
+<li>A flag whether this word was found in one of the registered dictionaries</li>
+<li>A flag that indicates whether this word starts a new sentence</li>
+<li>The set of proposals if the word was not correctly spelt. This information is lazily computed.</li>
+</ul>
+Spell event listeners are free to handle the events in any way. However, listeners are not allowed to block during 
+the event handling unless the spell-checking process happens in another thread.
+</body>
+</html>
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/package.html b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/package.html
new file mode 100644 (file)
index 0000000..f880e28
--- /dev/null
@@ -0,0 +1,70 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; I) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides facilities for spell-checking of comments and strings in Java source code.
+<h2>
+Package Specification</h2>
+The content of this package extends the base functionality of the spell-checking engine.
+<p>
+It contains a spell-check engine specialized in Javadoc comments. 
+Several dictionaries with Java specific content like Javadoc keywords, HTML tags and Task tags 
+are provided. 
+Additionally, the engine contributes correction proposals to the QuickFix processor. 
+For non Java specific content the engine also contributes
+word completion proposals to the content assist processor.
+<h3>
+Spell-check engine</h3>
+<tt>SpellCheckEngine</tt> is the default implementation of the interface <tt>ISpellCheckEngine</tt>.
+It provides a facade for dealing with the setup of a spell-checker. This class provides methods
+to retrieve the available dictionaries and is responsible for the registration of those with the spell-checker.
+<tt>SpellCheckEngine</tt> also has support for life-cycle management. Single dictionaries can be temporarily
+unloaded from memory or unregistered.<br>
+To contribute own dictionaries use the methods to register locale sensitive or insensitive dictionaries. A dictionary can
+be associated to a specified locale, but can also be available for spell-checking arbitrary text in arbitrary languages.
+The actual spell-checker for a specified language can then be obtained by calling <tt>createSpellChecker(Locale)</tt>.
+This is the central point to working with the spell-checker. When requesting a spell-checker for a specified locale, the
+engine looks up the corresponding dictionary and registers it with the spell-checker. Note that the dictionaries
+are lazily loaded and can be further optimized by prefiltering the queried words.
+<p>
+<b>Note:</b> Locale sensitive dictionaries must be located in the "dictionaries/" subdirectory of the JDT UI plugin install 
+location. The dictionaries are newline-separated word lists having the filename "language_country.dictionary", where "language" and "country" are 
+the lowercase ISO-3166 language and country codes, respectively. The default dictionary is "en_us.dictionary". For correct 
+behavior of the spell-check engine, at least the default dictionary must be installed. The default dictionary corresponds to the default locale 
+of the spell-check engine.
+<h3>
+Dictionaries</h3>
+This implementation for a Javadoc comment spell-checker provides the following read-only
+dictionaries:
+<ul>
+<li>A dictionary for Javadoc tags: This dictionary contains the most commonly used Javadoc tags. When
+spell-checking Javadoc comments, this dictionary contributes correction proposals to the QuickFix processor to correct misspelt Javadoc tags.</li>
+<li>A dictionary for HTML tags: This dictionary contains the most commonly used HTML tags for writing Javadoc comments. When spell-checking
+Javadoc- or multiline comments, this dictionary contributes correction proposals to the QuickFix processor as well as
+word completion proposals to the Content Assist processor.</li>
+<li>A dictionary for Task tags: This dictionary reflects the currently available Java Task tags. When spell-checking arbitrary text in Java files, 
+this dictionary contributes proposals both to the QuickFix processor and the Content Assist processor.</li>
+</ul>
+<h3>
+QuickFix processor</h3>
+The comment spell-checker also contributes a quickfix processor as an extension. This implementation of a quickfix processor
+contributes the following correction proposals:
+<ul>
+<li>Proposals for correct spelling: A number of words considered most similar to the incorrectly spelt word.</li>
+<li>The proposal to correct the sentence capitalization: This proposal is offered on incorrectly spelt words at the beginning of a sentence.
+<li>The proposal to add the unrecognized word to the locale-insensitive dictionaries</li>
+<li>The proposal to ignore the word during the current editing session</li>
+</ul>
+<h3>
+Content Assist processor</h3>
+The last contribution of the spell-checker is the support for word completion. The spell-checker provides a custom 
+content assist processor to produce word completion proposals.<br>
+Word completion works on all non Java code content types and delivers a number of proposals based on the current
+caret position.
+</body>
+</html>
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/AbstractProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/AbstractProposal.java
new file mode 100644 (file)
index 0000000..e79994e
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import java.util.WeakHashMap;
+
+import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+
+
+/**
+ * A PHP identifier proposal.
+ */
+public abstract class AbstractProposal implements IPHPCompletionProposal {
+       protected IRegion fSelectedRegion; // initialized by apply()
+
+       protected final ITextViewer fViewer;
+
+       protected ContextInformation fContextInfo;
+
+       public AbstractProposal(ITextViewer viewer) {
+               fContextInfo = null;
+               fViewer = viewer;
+       }
+
+       protected static String textToHTML(String string) {
+               StringBuffer buffer = new StringBuffer(string.length());
+               buffer.append("<pre>"); //$NON-NLS-1$
+
+               for (int i = 0; i != string.length(); i++) {
+                       char ch = string.charAt(i);
+
+                       switch (ch) {
+                       case '&':
+                               buffer.append("&amp;"); //$NON-NLS-1$
+                               break;
+
+                       case '<':
+                               buffer.append("&lt;"); //$NON-NLS-1$
+                               break;
+
+                       case '>':
+                               buffer.append("&gt;"); //$NON-NLS-1$
+                               break;
+
+                       case '\t':
+                               buffer.append("    "); //$NON-NLS-1$
+                               break;
+
+                       case '\n':
+                               buffer.append("<br>"); //$NON-NLS-1$
+                               break;
+
+                       default:
+                               buffer.append(ch);
+                               break;
+                       }
+               }
+
+               buffer.append("</pre>"); //$NON-NLS-1$
+               return buffer.toString();
+       }
+
+       /*
+        * @see ICompletionProposal#getSelection(IDocument)
+        */
+       public Point getSelection(IDocument document) {
+               return new Point(fSelectedRegion.getOffset(), fSelectedRegion
+                               .getLength());
+       }
+
+       protected void handleException(CoreException e) {
+               WebUI.log(e);
+       }
+
+       protected void openErrorDialog(BadLocationException e) {
+               Shell shell = fViewer.getTextWidget().getShell();
+               MessageDialog.openError(shell, TemplateMessages
+                               .getString("TemplateEvaluator.error.title"), e.getMessage()); //$NON-NLS-1$
+       }
+
+       public IContextInformation getContextInformation() {
+               return null;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/BuiltInEngine.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/BuiltInEngine.java
new file mode 100644 (file)
index 0000000..22cface
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContextType;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPElement;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPFunction;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.swt.graphics.Point;
+
+public class BuiltInEngine {
+
+       /** The context type. */
+       private JavaContextType fContextType;
+
+       /** The result proposals. */
+       private ArrayList fProposals = new ArrayList();
+
+       /**
+        * Creates the template engine for a particular context type. See
+        * <code>TemplateContext</code> for supported context types.
+        */
+       public BuiltInEngine(JavaContextType contextType) {
+               // Assert.isNotNull(contextType);
+               fContextType = contextType;
+       }
+
+       /**
+        * Empties the collector.
+        * 
+        * @param viewer
+        *            the text viewer
+        * @param unit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       public void reset() {
+               fProposals.clear();
+       }
+
+       /**
+        * Returns the array of matching templates.
+        */
+       public IPHPCompletionProposal[] getResults() {
+               return (IPHPCompletionProposal[]) fProposals
+                               .toArray(new IPHPCompletionProposal[fProposals.size()]);
+       }
+
+       /**
+        * Inspects the context of the compilation unit around
+        * <code>completionPosition</code> and feeds the collector with proposals.
+        * 
+        * @param viewer
+        *            the text viewer
+        * @param completionPosition
+        *            the context position in the document of the text viewer
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       public void complete(ITextViewer viewer, int completionPosition,
+                       ArrayList identifiers, ICompilationUnit compilationUnit)
+       // hrows JavaModelException
+       {
+               IDocument document = viewer.getDocument();
+
+               // prohibit recursion
+               // if (LinkedPositionManager.hasActiveManager(document))
+               // return;
+
+               if (!(fContextType instanceof CompilationUnitContextType))
+                       return;
+               Point selection = viewer.getSelectedRange();
+               // remember selected text
+               String selectedText = null;
+               if (selection.y != 0) {
+                       try {
+                               selectedText = document.get(selection.x, selection.y);
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               // ((CompilationUnitContextType)
+               // fContextType).setContextParameters(document, completionPosition,
+               // selection.y); //mpilationUnit);
+               // JavaContext context = (JavaContext) fContextType.createContext();
+               JavaContext context = (JavaContext) fContextType.createContext(
+                               document, completionPosition, selection.y, compilationUnit);
+               context.setVariable("selection", selectedText); //$NON-NLS-1$
+               int start = context.getStart();
+               int end = context.getEnd();
+               IRegion region = new Region(start, end - start);
+
+               // Template[] templates= Templates.getInstance().getTemplates();
+               String identifier = null;
+               int maxProposals = WebUI.MAX_PROPOSALS;
+               PHPElement element = null;
+               for (int i = 0; i != identifiers.size(); i++) {
+                       element = (PHPElement) identifiers.get(i);
+                       if (element instanceof PHPFunction) {
+                               identifier = ((PHPFunction) element).getName();
+                               if (context.canEvaluate(identifier)) {
+                                       if (maxProposals-- < 0) {
+                                               return;
+                                       }
+                                       fProposals.add(new BuiltInProposal(identifier,
+                                                       (PHPFunction) element, context, region, viewer));
+                               }
+                       }
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/BuiltInProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/BuiltInProposal.java
new file mode 100644 (file)
index 0000000..f05e19d
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPFunction;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.swt.graphics.Image;
+
+// import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+// import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+// import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+
+/**
+ * A PHP identifier proposal.
+ */
+public class BuiltInProposal extends AbstractProposal {
+       private final TemplateContext fContext;
+
+       private final PHPFunction fFunction;
+
+       private final IRegion fRegion;
+
+       private final String fBuiltinFunctionName;
+
+       /**
+        * Creates a template proposal with a template and its context.
+        * 
+        * @param template
+        *            the template
+        * @param context
+        *            the context in which the template was requested.
+        * @param image
+        *            the icon of the proposal.
+        */
+       public BuiltInProposal(String functionName, PHPFunction function,
+                       TemplateContext context, IRegion region, ITextViewer viewer) {
+               super(viewer);
+               fBuiltinFunctionName = functionName;
+               fFunction = function;
+               fContext = context;
+               // fViewer = viewer;
+               fRegion = region;
+       }
+
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public void apply(IDocument document) {
+               try {
+                       // if (fTemplateBuffer == null)
+                       // fTemplateBuffer= fContext.evaluate(fTemplate);
+
+                       int start = fRegion.getOffset();
+                       int end = fRegion.getOffset() + fRegion.getLength();
+
+                       // insert template string
+                       // String templateString = fTemplate; //
+                       // fTemplateBuffer.getString();
+                       document.replace(start, end - start, fBuiltinFunctionName + "()");
+
+                       // translate positions
+                       LinkedPositionManager manager = new LinkedPositionManager(document);
+                       // TemplatePosition[] variables= fTemplateBuffer.getVariables();
+                       // for (int i= 0; i != variables.length; i++) {
+                       // TemplatePosition variable= variables[i];
+                       //
+                       // if (variable.isResolved())
+                       // continue;
+                       //
+                       // int[] offsets= variable.getOffsets();
+                       // int length= variable.getLength();
+                       //
+                       // for (int j= 0; j != offsets.length; j++)
+                       // manager.addPosition(offsets[j] + start, length);
+                       // }
+
+                       LinkedPositionUI editor = new LinkedPositionUI(fViewer, manager);
+                       editor.setFinalCaretOffset(fBuiltinFunctionName.length() + start
+                                       + 1);
+                       // editor.setFinalCaretOffset(getCaretOffset(fTemplateBuffer) +
+                       // start);
+                       editor.enter();
+
+                       fSelectedRegion = editor.getSelectedRegion();
+
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+                       openErrorDialog(e);
+
+               }
+               // catch (CoreException e) {
+               // handleException(e);
+               // }
+       }
+
+       public String getAdditionalProposalInfo() {
+               return fFunction.getHoverText();
+       }
+
+       public IContextInformation getContextInformation() {
+               if (fContextInfo == null) {
+                       String contextInfoString = fFunction.getHoverText();
+                       if (contextInfoString != null && contextInfoString.length() > 0) {
+                               // extract the parameter context information for the function:
+                               int i0 = contextInfoString.indexOf('(');
+                               int newline = contextInfoString.indexOf('\n');
+                               if (i0 >= 0 && (i0 < newline || newline < 0)) {
+                                       int i1 = contextInfoString.indexOf(')', i0 + 1);
+                                       if (i1 > 0) {
+                                               fContextInfo = new ContextInformation(null,
+                                                               contextInfoString.substring(i0 + 1, i1));
+                                       } else {
+                                               fContextInfo = new ContextInformation(null,
+                                                               contextInfoString);
+                                       }
+                               } else {
+                                       fContextInfo = new ContextInformation(null,
+                                                       contextInfoString);
+                               }
+                       }
+               }
+               return fContextInfo;
+       }
+
+       /*
+        * @see ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return fBuiltinFunctionName
+                               + TemplateMessages.getString("TemplateProposal.delimiter") + fFunction.getUsage(); // $NON-NLS-1$
+               // //$NON-NLS-1$
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return PHPUiImages.get(PHPUiImages.IMG_BUILTIN);
+       }
+
+       /*
+        * @see IJavaCompletionProposal#getRelevance()
+        */
+       public int getRelevance() {
+
+               if (fContext instanceof JavaContext) {
+                       JavaContext context = (JavaContext) fContext;
+                       switch (context.getCharacterBeforeStart()) {
+                       // high relevance after whitespace
+                       case ' ':
+                       case '\r':
+                       case '\n':
+                       case '\t':
+                               return 50;
+
+                       default:
+                               return 0;
+                       }
+               } else {
+                       return 50;
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java
new file mode 100644 (file)
index 0000000..f393c18
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.SortedMap;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContextType;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.swt.graphics.Point;
+
+public class DeclarationEngine {
+
+       /** The context type. */
+       private JavaContextType fContextType;
+
+       /** The result proposals. */
+       private ArrayList fProposals = new ArrayList();
+
+       /** Token determines last which declarations are allowed for proposal */
+       private int fLastSignificantToken;
+
+       private IProject fProject;
+
+       // private IFile fFile;
+       private String fFileName;
+
+       /**
+        * Creates the template engine for a particular context type. See
+        * <code>TemplateContext</code> for supported context types.
+        */
+       public DeclarationEngine(IProject project, JavaContextType contextType,
+                       int lastSignificantToken, IFile file) {
+               // Assert.isNotNull(contextType);
+               fProject = project;
+               fContextType = contextType;
+
+               fLastSignificantToken = lastSignificantToken;
+               // fFile = file;
+               if (file != null) {
+                       fFileName = file.getProjectRelativePath().toString();
+               } else {
+                       fFileName = "";
+               }
+       }
+
+       /**
+        * Empties the collector.
+        * 
+        * @param viewer
+        *            the text viewer
+        * @param unit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       public void reset() {
+               fProposals.clear();
+       }
+
+       /**
+        * Returns the array of matching templates.
+        */
+       public IPHPCompletionProposal[] getResults() {
+               return (IPHPCompletionProposal[]) fProposals
+                               .toArray(new IPHPCompletionProposal[fProposals.size()]);
+       }
+
+       /**
+        * Inspects the context of the compilation unit around
+        * <code>completionPosition</code> and feeds the collector with proposals.
+        * 
+        * @param viewer
+        *            the text viewer
+        * @param completionPosition
+        *            the context position in the document of the text viewer
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       public void completeObject(ITextViewer viewer, int completionPosition,
+                       SortedMap map, ICompilationUnit compilationUnit) {
+               IDocument document = viewer.getDocument();
+
+               if (!(fContextType instanceof CompilationUnitContextType))
+                       return;
+
+               Point selection = viewer.getSelectedRange();
+
+               // remember selected text
+               String selectedText = null;
+
+               if (selection.y != 0) {
+                       try {
+                               selectedText = document.get(selection.x, selection.y);
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               JavaContext context = (JavaContext) fContextType.createContext(
+                               document, completionPosition, selection.y, compilationUnit);
+               context.setVariable("selection", selectedText); //$NON-NLS-1$
+
+               int start = context.getStart();
+               int end = context.getEnd();
+               String prefix = context.getKey();
+               IRegion region = new Region(start, end - start);
+
+               String identifier = null;
+
+               SortedMap subMap = map.subMap(prefix, prefix + '\255');
+               Iterator iter = subMap.keySet().iterator();
+               PHPIdentifierLocation location;
+               ArrayList list;
+               int maxProposals = PHPeclipsePlugin.MAX_PROPOSALS;
+               while (iter.hasNext()) {
+                       identifier = (String) iter.next();
+                       if (context.canEvaluate(identifier)) {
+                               list = (ArrayList) subMap.get(identifier);
+                               for (int i = 0; i < list.size(); i++) {
+                                       location = (PHPIdentifierLocation) list.get(i);
+                                       int type = location.getType();
+                                       switch (fLastSignificantToken) {
+                                       case ITerminalSymbols.TokenNameMINUS_GREATER:
+                                               if (type != PHPIdentifierLocation.METHOD
+                                                               && type != PHPIdentifierLocation.VARIABLE) {
+                                                       continue; // for loop
+                                               }
+                                               break;
+                                       case ITerminalSymbols.TokenNameVariable:
+                                               if (type != PHPIdentifierLocation.METHOD
+                                                               && type != PHPIdentifierLocation.VARIABLE) {
+                                                       continue; // for loop
+                                               }
+                                               // check all filenames of the subclasses
+                                               // if (fFileName.equals(location.getFilename())) {
+                                               // continue; // for loop
+                                               // }
+                                               break;
+                                       case ITerminalSymbols.TokenNamethis_PHP_COMPLETION:
+                                               if (type != PHPIdentifierLocation.METHOD
+                                                               && type != PHPIdentifierLocation.VARIABLE) {
+                                                       continue; // for loop
+                                               }
+                                               // check all filenames of the subclasses
+                                               // if (!fFileName.equals(location.getFilename())) {
+                                               // continue; // for loop
+                                               // }
+                                               break;
+                                       case ITerminalSymbols.TokenNamenew:
+                                               if (type != PHPIdentifierLocation.CLASS
+                                                               && type != PHPIdentifierLocation.CONSTRUCTOR) {
+                                                       continue; // for loop
+                                               }
+                                               break;
+                                       default:
+                                               if (type == PHPIdentifierLocation.METHOD
+                                                               || type == PHPIdentifierLocation.CONSTRUCTOR
+                                                               || type == PHPIdentifierLocation.VARIABLE) {
+                                                       continue; // for loop
+                                               }
+                                       }
+                                       if (maxProposals-- < 0) {
+                                               return;
+                                       }
+                                       fProposals.add(new DeclarationProposal(fProject,
+                                                       identifier, location, context, region, viewer));
+                               }
+                       }
+               }
+
+       }
+
+       /**
+        * Inspects the context of the compilation unit around
+        * <code>completionPosition</code> and feeds the collector with proposals.
+        * 
+        * @param viewer
+        *            the text viewer
+        * @param completionPosition
+        *            the context position in the document of the text viewer
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       public void complete(ITextViewer viewer, int completionPosition,
+                       SortedMap map, ICompilationUnit compilationUnit) {
+               IDocument document = viewer.getDocument();
+
+               if (!(fContextType instanceof CompilationUnitContextType))
+                       return;
+
+               Point selection = viewer.getSelectedRange();
+
+               // remember selected text
+               String selectedText = null;
+
+               if (selection.y != 0) {
+                       try {
+                               selectedText = document.get(selection.x, selection.y);
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               // ((CompilationUnitContextType)
+               // fContextType).setContextParameters(document, completionPosition,
+               // selection.y);
+
+               // CompilationUnitContext context = (CompilationUnitContext)
+               // fContextType.createContext();
+               JavaContext context = (JavaContext) fContextType.createContext(
+                               document, completionPosition, selection.y, compilationUnit);
+               context.setVariable("selection", selectedText); //$NON-NLS-1$
+
+               int start = context.getStart();
+               int end = context.getEnd();
+               String prefix = context.getKey();
+               IRegion region = new Region(start, end - start);
+
+               String identifier = null;
+
+               SortedMap subMap = map.subMap(prefix, prefix + '\255');
+               Iterator iter = subMap.keySet().iterator();
+               PHPIdentifierLocation location;
+               ArrayList list;
+               int maxProposals = PHPeclipsePlugin.MAX_PROPOSALS;
+               while (iter.hasNext()) {
+                       identifier = (String) iter.next();
+                       if (context.canEvaluate(identifier)) {
+                               list = (ArrayList) subMap.get(identifier);
+                               for (int i = 0; i < list.size(); i++) {
+                                       location = (PHPIdentifierLocation) list.get(i);
+                                       int type = location.getType();
+                                       switch (fLastSignificantToken) {
+                                       case ITerminalSymbols.TokenNameMINUS_GREATER:
+                                               if (type != PHPIdentifierLocation.METHOD
+                                                               && type != PHPIdentifierLocation.VARIABLE) {
+                                                       continue; // for loop
+                                               }
+                                               break;
+                                       case ITerminalSymbols.TokenNameVariable:
+                                               if (type != PHPIdentifierLocation.METHOD
+                                                               && type != PHPIdentifierLocation.VARIABLE) {
+                                                       continue; // for loop
+                                               }
+                                               // check all filenames of the subclasses
+                                               if (fFileName.equals(location.getFilename())) {
+                                                       continue; // for loop
+                                               }
+                                               break;
+                                       case ITerminalSymbols.TokenNamethis_PHP_COMPLETION:
+                                               if (type != PHPIdentifierLocation.METHOD
+                                                               && type != PHPIdentifierLocation.VARIABLE) {
+                                                       continue; // for loop
+                                               }
+                                               // check all filenames of the subclasses
+                                               if (!fFileName.equals(location.getFilename())) {
+                                                       continue; // for loop
+                                               }
+                                               break;
+                                       case ITerminalSymbols.TokenNamenew:
+                                               if (type != PHPIdentifierLocation.CLASS
+                                                               && type != PHPIdentifierLocation.CONSTRUCTOR) {
+                                                       continue; // for loop
+                                               }
+                                               break;
+                                       default:
+                                               if (type == PHPIdentifierLocation.METHOD
+                                                               || type == PHPIdentifierLocation.CONSTRUCTOR
+                                                               || type == PHPIdentifierLocation.VARIABLE) {
+                                                       continue; // for loop
+                                               }
+                                       }
+                                       if (maxProposals-- < 0) {
+                                               return;
+                                       }
+                                       fProposals.add(new DeclarationProposal(fProject,
+                                                       identifier, location, context, region, viewer));
+                               }
+                       }
+               }
+
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java
new file mode 100644 (file)
index 0000000..d08d6e8
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.corext.phpdoc.PHPDocUtil;
+import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.swt.graphics.Image;
+
+// import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+// import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+// import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+
+/**
+ * A PHP identifier proposal.
+ */
+public class DeclarationProposal extends AbstractProposal { // implements
+       // IPHPCompletionProposal
+       // {
+       private IProject fProject;
+
+       private final TemplateContext fContext;
+
+       private final PHPIdentifierLocation fLocation;
+
+       String fInfo;
+
+       // private TemplateBuffer fTemplateBuffer;
+       // private String fOldText;
+       // private final Image fImage_fun;
+       // private final Image fImage_var;
+       private final IRegion fRegion;
+
+       // private IRegion fSelectedRegion; // initialized by apply()
+
+       private final String fIdentifierName;
+
+       // private final ITextViewer fViewer;
+
+       /**
+        * Creates a template proposal with a template and its context.
+        * 
+        * @param template
+        *            the template
+        * @param context
+        *            the context in which the template was requested.
+        * @param image
+        *            the icon of the proposal.
+        */
+       public DeclarationProposal(IProject project, String identifierName,
+                       PHPIdentifierLocation location, TemplateContext context,
+                       IRegion region, ITextViewer viewer) {
+               super(viewer);
+               // Image image_fun,
+               // Image image_var) {
+               fProject = project;
+               fIdentifierName = identifierName;
+               fLocation = location;
+               fContext = context;
+               fRegion = region;
+               fInfo = null;
+       }
+
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public void apply(IDocument document) {
+               try {
+                       // if (fTemplateBuffer == null)
+                       // fTemplateBuffer= fContext.evaluate(fTemplate);
+
+                       int start = fRegion.getOffset();
+                       int end = fRegion.getOffset() + fRegion.getLength();
+
+                       switch (fLocation.getType()) {
+                       case PHPIdentifierLocation.FUNCTION:
+                               document.replace(start, end - start, fIdentifierName + "()");
+                               break;
+                       case PHPIdentifierLocation.CONSTRUCTOR:
+                               document.replace(start, end - start, fIdentifierName + "()");
+                               break;
+                       case PHPIdentifierLocation.METHOD:
+                               document.replace(start, end - start, fIdentifierName + "()");
+                               break;
+
+                       default:
+                               document.replace(start, end - start, fIdentifierName);
+                       }
+
+                       // translate positions
+                       LinkedPositionManager manager = new LinkedPositionManager(document);
+                       // TemplatePosition[] variables= fTemplateBuffer.getVariables();
+                       // for (int i= 0; i != variables.length; i++) {
+                       // TemplatePosition variable= variables[i];
+                       //
+                       // if (variable.isResolved())
+                       // continue;
+                       //
+                       // int[] offsets= variable.getOffsets();
+                       // int length= variable.getLength();
+                       //
+                       // for (int j= 0; j != offsets.length; j++)
+                       // manager.addPosition(offsets[j] + start, length);
+                       // }
+
+                       LinkedPositionUI editor = new LinkedPositionUI(fViewer, manager);
+                       switch (fLocation.getType()) {
+                       case PHPIdentifierLocation.FUNCTION:
+                               editor
+                                               .setFinalCaretOffset(fIdentifierName.length() + start
+                                                               + 1);
+                               break;
+                       case PHPIdentifierLocation.CONSTRUCTOR:
+                               editor
+                                               .setFinalCaretOffset(fIdentifierName.length() + start
+                                                               + 1);
+                               break;
+                       case PHPIdentifierLocation.METHOD:
+                               editor
+                                               .setFinalCaretOffset(fIdentifierName.length() + start
+                                                               + 1);
+                               break;
+
+                       default:
+                               editor.setFinalCaretOffset(fIdentifierName.length() + start);
+                       }
+                       editor.enter();
+
+                       fSelectedRegion = editor.getSelectedRegion();
+
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+                       openErrorDialog(e);
+
+               }
+               // catch (CoreException e) {
+               // handleException(e);
+               // }
+       }
+
+       /*
+        * @see ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               if (fInfo == null) {
+                       fInfo = computeProposalInfo();
+               }
+               return fInfo;
+       }
+
+       private String computeProposalInfo() {
+               StringBuffer hoverInfoBuffer = new StringBuffer();
+               // String workspaceLocation =
+               // PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+               String workspaceLocation;
+               if (fProject != null) {
+                       workspaceLocation = fProject.getLocation().toString() + '/';
+               } else {
+                       // should never happen?
+                       workspaceLocation = WebUI.getWorkspace().getRoot()
+                                       .getFullPath().toString();
+               }
+               String filename = workspaceLocation + fLocation.getFilename();
+               PHPDocUtil.appendPHPDoc(hoverInfoBuffer, filename, fLocation);
+               return hoverInfoBuffer.toString();
+       }
+
+       public IContextInformation getContextInformation() {
+               if (fContextInfo == null) {
+                       if (fLocation != null) {
+                               fInfo = fLocation.getUsage();
+                               if (fInfo != null) {
+                                       // extract the parameter context information for the
+                                       // function:
+                                       int i0 = fInfo.indexOf('(');
+                                       int newline = fInfo.indexOf('\n');
+                                       if (i0 >= 0 && (i0 < newline || newline < 0)) {
+                                               int i1 = fInfo.indexOf(')', i0 + 1);
+                                               if (i1 > 0) {
+
+                                                       fContextInfo = new ContextInformation(null, fInfo
+                                                                       .substring(i0 + 1, i1));
+                                               } else {
+                                                       fContextInfo = new ContextInformation(null, fInfo);
+                                               }
+                                       } else {
+                                               fContextInfo = new ContextInformation(null, fInfo);
+                                       }
+                               }
+                       }
+               }
+               return fContextInfo;
+       }
+
+       /*
+        * @see ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               String workspaceLocation;
+               String workspaceName;
+               if (fProject != null) {
+                       workspaceLocation = fProject.getFullPath().toString() + '/';
+                       workspaceName = fProject.getName().toString() + '/';
+               } else {
+                       // should never happen?
+                       workspaceLocation = WebUI.getWorkspace().getRoot()
+                                       .getFullPath().toString();
+                       workspaceName = workspaceLocation;
+               }
+               String filename = fLocation.getFilename();
+               String usage = PHPDocUtil.getUsage(workspaceLocation + filename, fLocation);
+               String result = fIdentifierName
+                               + TemplateMessages.getString("TemplateProposal.delimiter");
+               if (usage.length() > 0) {
+                       result += usage
+                                       + TemplateMessages.getString("TemplateProposal.delimiter");
+               }
+               result += workspaceName + filename;
+               return result;
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               switch (fLocation.getType()) {
+               case PHPIdentifierLocation.FUNCTION:
+                       return PHPUiImages.get(PHPUiImages.IMG_FUN);
+               case PHPIdentifierLocation.CLASS:
+                       return PHPUiImages.get(PHPUiImages.IMG_CLASS);
+               case PHPIdentifierLocation.CONSTRUCTOR:
+                       return PHPUiImages.get(PHPUiImages.IMG_CLASS);
+               case PHPIdentifierLocation.METHOD:
+                       return PHPUiImages.get(PHPUiImages.IMG_FUN);
+               case PHPIdentifierLocation.DEFINE:
+                       return PHPUiImages.get(PHPUiImages.IMG_DEFINE);
+               case PHPIdentifierLocation.VARIABLE:
+                       return PHPUiImages.get(PHPUiImages.IMG_VAR);
+               case PHPIdentifierLocation.GLOBAL_VARIABLE:
+                       return PHPUiImages.get(PHPUiImages.IMG_VAR);
+               }
+               return PHPUiImages.get(PHPUiImages.IMG_FUN);
+       }
+
+       /*
+        * @see IJavaCompletionProposal#getRelevance()
+        */
+       public int getRelevance() {
+
+               if (fContext instanceof JavaContext) {
+                       JavaContext context = (JavaContext) fContext;
+                       switch (context.getCharacterBeforeStart()) {
+                       // high relevance after whitespace
+                       case ' ':
+                       case '\r':
+                       case '\n':
+                       case '\t':
+                               return 80;
+                       case '>': // ->
+                       case ':': // ::
+                               return 85;
+                       default:
+                               return 0;
+                       }
+               } else {
+                       return 80;
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/IdentifierEngine.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/IdentifierEngine.java
new file mode 100644 (file)
index 0000000..58d82e9
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContextType;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.swt.graphics.Point;
+
+public class IdentifierEngine {
+
+       /** The context type. */
+       private JavaContextType fContextType;
+
+       /** The result proposals. */
+       private ArrayList fProposals = new ArrayList();
+
+       /**
+        * Creates the template engine for a particular context type. See
+        * <code>TemplateContext</code> for supported context types.
+        */
+       public IdentifierEngine(JavaContextType contextType) {
+               // Assert.isNotNull(contextType);
+               fContextType = contextType;
+       }
+
+       /**
+        * Empties the collector.
+        * 
+        * @param viewer
+        *            the text viewer
+        * @param unit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       public void reset() {
+               fProposals.clear();
+       }
+
+       /**
+        * Returns the array of matching templates.
+        */
+       public IPHPCompletionProposal[] getResults() {
+               return (IPHPCompletionProposal[]) fProposals
+                               .toArray(new IPHPCompletionProposal[fProposals.size()]);
+       }
+
+       /**
+        * Inspects the context of the compilation unit around
+        * <code>completionPosition</code> and feeds the collector with proposals.
+        * 
+        * @param viewer
+        *            the text viewer
+        * @param completionPosition
+        *            the context position in the document of the text viewer
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       public void complete(ITextViewer viewer, int completionPosition,
+                       Object[] identifiers, ICompilationUnit compilationUnit)
+       // hrows JavaModelException
+       {
+               IDocument document = viewer.getDocument();
+
+               if (!(fContextType instanceof CompilationUnitContextType))
+                       return;
+
+               Point selection = viewer.getSelectedRange();
+               // remember selected text
+               String selectedText = null;
+               if (selection.y != 0) {
+                       try {
+                               selectedText = document.get(selection.x, selection.y);
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               // ((CompilationUnitContextType)
+               // fContextType).setContextParameters(document, completionPosition,
+               // selection.y); //mpilationUnit);
+
+               // JavaContext context = (JavaContext) fContextType.createContext();
+               JavaContext context = (JavaContext) fContextType.createContext(
+                               document, completionPosition, selection.y, compilationUnit);
+               context.setVariable("selection", selectedText); //$NON-NLS-1$
+
+               int start = context.getStart();
+               int end = context.getEnd();
+               IRegion region = new Region(start, end - start);
+
+               // Template[] templates= Templates.getInstance().getTemplates();
+               String identifier = null;
+               int maxProposals = WebUI.MAX_PROPOSALS;
+
+               for (int i = 0; i != identifiers.length; i++) {
+                       identifier = (String) identifiers[i];
+                       if (context.canEvaluate(identifier)) {
+                               if (maxProposals-- < 0) {
+                                       return;
+                               }
+                               fProposals.add(new IdentifierProposal(identifier, context,
+                                               region, viewer, PHPUiImages.get(PHPUiImages.IMG_FUN),
+                                               PHPUiImages.get(PHPUiImages.IMG_VAR)));
+                       }
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/IdentifierProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/IdentifierProposal.java
new file mode 100644 (file)
index 0000000..3f27aad
--- /dev/null
@@ -0,0 +1,94 @@
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A PHP identifier proposal.
+ */
+public class IdentifierProposal extends AbstractProposal {
+       private final TemplateContext fContext;
+
+       private final Image fImage_fun;
+
+       private final Image fImage_var;
+
+       private final IRegion fRegion;
+
+       private final String fTemplate;
+
+       public IdentifierProposal(String template, TemplateContext context,
+                       IRegion region, ITextViewer viewer, Image image_fun, Image image_var) {
+               super(viewer);
+               fTemplate = template;
+               fContext = context;
+
+               fImage_fun = image_fun;
+               fImage_var = image_var;
+               fRegion = region;
+       }
+
+       public void apply(IDocument document) {
+               try {
+                       int start = fRegion.getOffset();
+                       int end = fRegion.getOffset() + fRegion.getLength();
+                       document.replace(start, end - start, fTemplate);
+                       // translate positions
+                       LinkedPositionManager manager = new LinkedPositionManager(document);
+
+                       LinkedPositionUI editor = new LinkedPositionUI(fViewer, manager);
+                       editor.setFinalCaretOffset(fTemplate.length() + start);
+                       editor.enter();
+                       fSelectedRegion = editor.getSelectedRegion();
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+                       openErrorDialog(e);
+               }
+       }
+
+       public String getAdditionalProposalInfo() {
+               return textToHTML(fTemplate); 
+       }
+
+       public String getDisplayString() {
+               return fTemplate
+                               + TemplateMessages.getString("TemplateProposal.delimiter")
+                               + fTemplate; // $NON-NLS-1$
+       }
+
+       public Image getImage() {
+               if (fTemplate.charAt(0) == '$') {
+                       return fImage_var;
+               }
+               return fImage_fun;
+       }
+
+       public int getRelevance() {
+               if (fContext instanceof JavaContext) {
+                       JavaContext context = (JavaContext) fContext;
+                       switch (context.getCharacterBeforeStart()) {
+                       // high relevance after whitespace
+                       case ' ':
+                       case '\r':
+                       case '\n':
+                       case '\t':
+                               return 50;
+                       default:
+                               return 0;
+                       }
+               } else {
+                       return 50;
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/LocalVariableProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/LocalVariableProposal.java
new file mode 100644 (file)
index 0000000..0d67c8a
--- /dev/null
@@ -0,0 +1,144 @@
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A PHP local identifier proposal.
+ */
+public class LocalVariableProposal extends AbstractProposal {
+
+       private final String fIdentifierName;
+
+       private final IRegion fRegion;
+
+       private final int fRelevance;
+
+       /**
+        * Creates a template proposal with a template and its context.
+        * 
+        * @param template
+        *            the template
+        * @param image
+        *            the icon of the proposal.
+        */
+       public LocalVariableProposal(String identifierName, IRegion region,
+                       ITextViewer viewer) {
+               this(identifierName, region, viewer, 99);
+       }
+
+       public LocalVariableProposal(String identifierName, IRegion region,
+                       ITextViewer viewer, int relevance) {
+               super(viewer);
+               fIdentifierName = identifierName;
+               fRegion = region;
+               fRelevance = relevance;
+       }
+
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public void apply(IDocument document) {
+               try {
+                       // if (fTemplateBuffer == null)
+                       // fTemplateBuffer= fContext.evaluate(fTemplate);
+
+                       int start = fRegion.getOffset();
+                       int end = fRegion.getOffset() + fRegion.getLength();
+
+                       document.replace(start, end - start, fIdentifierName);
+
+                       // translate positions
+                       LinkedPositionManager manager = new LinkedPositionManager(document);
+
+                       LinkedPositionUI editor = new LinkedPositionUI(fViewer, manager);
+                       editor.setFinalCaretOffset(fIdentifierName.length() + start);
+                       editor.enter();
+
+                       fSelectedRegion = editor.getSelectedRegion();
+
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+                       openErrorDialog(e);
+
+               }
+               // catch (CoreException e) {
+               // handleException(e);
+               // }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object obj) {
+               if (obj instanceof LocalVariableProposal) {
+                       return fIdentifierName
+                                       .equals(((LocalVariableProposal) obj).fIdentifierName);
+               }
+               return false;
+       }
+
+       /*
+        * @see ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               StringBuffer hoverInfoBuffer = new StringBuffer();
+               if (fRelevance > 95) {
+                       hoverInfoBuffer.append("function source variable -");
+               } else {
+                       hoverInfoBuffer.append("editor source variable -");
+               }
+               hoverInfoBuffer.append(fIdentifierName);
+               return hoverInfoBuffer.toString();
+       }
+
+       /*
+        * @see ICompletionProposal#getContextInformation()
+        */
+       public IContextInformation getContextInformation() {
+               return null;
+       }
+
+       /*
+        * @see ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return fIdentifierName; // $NON-NLS-1$ //$NON-NLS-1$
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return PHPUiImages.get(PHPUiImages.IMG_VAR);
+       }
+
+       /*
+        * @see IJavaCompletionProposal#getRelevance()
+        */
+       public int getRelevance() {
+               return fRelevance;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#hashCode()
+        */
+       public int hashCode() {
+               return fIdentifierName.hashCode();
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/SQLProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/SQLProposal.java
new file mode 100644 (file)
index 0000000..a7af0d6
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A PHP identifier proposal.
+ */
+public class SQLProposal extends AbstractProposal { 
+       private final TemplateContext fContext;
+
+       private final Image fImage_var;
+
+       private final IRegion fRegion;
+
+       private final String fColumnName;
+
+       private final String fTableName;
+
+       private int fRelevance;
+
+       /**
+        * Creates a template proposal with a template and its context.
+        * 
+        * @param template
+        *            the template
+        * @param context
+        *            the context in which the template was requested.
+        * @param image
+        *            the icon of the proposal.
+        */
+       public SQLProposal(String tableName, TemplateContext context,
+                       IRegion region, ITextViewer viewer, Image image_var) {
+               super(viewer);
+               fTableName = tableName;
+               fColumnName = null;
+               fContext = context;
+               fImage_var = image_var;
+               fRegion = region;
+               fRelevance = 0;
+       }
+
+       public SQLProposal(String tableName, String columnName,
+                       TemplateContext context, IRegion region, ITextViewer viewer,
+                       Image image_var) {
+               super(viewer);
+               fTableName = tableName;
+               fColumnName = columnName;
+               fContext = context;
+               fImage_var = image_var;
+               fRegion = region;
+               fRelevance = 0;
+       }
+
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public void apply(IDocument document) {
+               try {
+                       int start = fRegion.getOffset();
+                       int end = fRegion.getOffset() + fRegion.getLength();
+                       String resultString = fTableName;
+                       if (fColumnName != null) {
+                               resultString = fColumnName;
+                       }
+                       // insert template string
+                       document.replace(start, end - start, resultString);
+                       // translate positions
+                       LinkedPositionManager manager = new LinkedPositionManager(document);
+                       LinkedPositionUI editor = new LinkedPositionUI(fViewer, manager);
+                       editor.setFinalCaretOffset(resultString.length() + start);
+                       editor.enter();
+                       fSelectedRegion = editor.getSelectedRegion();
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+                       openErrorDialog(e);
+               }
+       }
+
+       /*
+        * @see ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               if (fColumnName == null) {
+                       return textToHTML(fTableName);
+               }
+               return fColumnName + " (Table: " + fTableName + ")";
+       }
+
+       /*
+        * @see ICompletionProposal#getContextInformation()
+        */
+       public IContextInformation getContextInformation() {
+               return null;
+       }
+
+       /*
+        * @see ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               if (fColumnName == null) {
+                       return fTableName;
+               }
+               return fColumnName + " (Table: " + fTableName + ")"; // $NON-NLS-1$
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return fImage_var;
+       }
+
+       /*
+        * @see IJavaCompletionProposal#getRelevance()
+        */
+       public int getRelevance() {
+               return fRelevance;
+       }
+
+       /**
+        * @param relevance
+        *            The relevance to set.
+        */
+       public void setRelevance(int relevance) {
+               fRelevance = relevance;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/InclusivePositionUpdater.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/InclusivePositionUpdater.java
new file mode 100644 (file)
index 0000000..dcd7b5f
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IPositionUpdater;
+import org.eclipse.jface.text.Position;
+
+/**
+ * Position updater that takes any change in [position.offset, position.offset +
+ * position.length] as belonging to the position.
+ * 
+ * @since 3.0
+ */
+class InclusivePositionUpdater implements IPositionUpdater {
+
+       /** The position category. */
+       private final String fCategory;
+
+       /**
+        * Creates a new updater for the given <code>category</code>.
+        * 
+        * @param category
+        *            the new category.
+        */
+       public InclusivePositionUpdater(String category) {
+               fCategory = category;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IPositionUpdater#update(org.eclipse.jface.text.DocumentEvent)
+        */
+       public void update(DocumentEvent event) {
+
+               int eventOffset = event.getOffset();
+               int eventOldLength = event.getLength();
+               int eventNewLength = event.getText() == null ? 0 : event.getText()
+                               .length();
+               int deltaLength = eventNewLength - eventOldLength;
+
+               try {
+                       Position[] positions = event.getDocument().getPositions(fCategory);
+
+                       for (int i = 0; i != positions.length; i++) {
+
+                               Position position = positions[i];
+
+                               if (position.isDeleted())
+                                       continue;
+
+                               int offset = position.getOffset();
+                               int length = position.getLength();
+                               int end = offset + length;
+
+                               if (offset > eventOffset + eventOldLength)
+                                       // position comes way
+                                       // after change - shift
+                                       position.setOffset(offset + deltaLength);
+                               else if (end < eventOffset) {
+                                       // position comes way before change -
+                                       // leave alone
+                               } else if (offset <= eventOffset
+                                               && end >= eventOffset + eventOldLength) {
+                                       // event completely internal to the position - adjust length
+                                       position.setLength(length + deltaLength);
+                               } else if (offset < eventOffset) {
+                                       // event extends over end of position - adjust length
+                                       int newEnd = eventOffset + eventNewLength;
+                                       position.setLength(newEnd - offset);
+                               } else if (end > eventOffset + eventOldLength) {
+                                       // event extends from before position into it - adjust
+                                       // offset
+                                       // and length
+                                       // offset becomes end of event, length ajusted acordingly
+                                       // we want to recycle the overlapping part
+                                       position.setOffset(eventOffset);
+                                       int deleted = eventOffset + eventOldLength - offset;
+                                       position.setLength(length - deleted + eventNewLength);
+                               } else {
+                                       // event consumes the position - delete it
+                                       position.delete();
+                               }
+                       }
+               } catch (BadPositionCategoryException e) {
+                       // ignore and return
+               }
+       }
+
+       /**
+        * Returns the position category.
+        * 
+        * @return the position category
+        */
+       public String getCategory() {
+               return fCategory;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/MultiVariable.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/MultiVariable.java
new file mode 100644 (file)
index 0000000..4ed0899
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.templates.TemplateVariable;
+
+/**
+ * 
+ */
+public class MultiVariable extends TemplateVariable {
+       private final Map fValueMap = new HashMap();
+
+       private Object fSet;
+
+       private Object fDefaultKey = null;
+
+       public MultiVariable(String type, String defaultValue, int[] offsets) {
+               super(type, defaultValue, offsets);
+               fValueMap.put(fDefaultKey, new String[] { defaultValue });
+               fSet = getDefaultValue();
+       }
+
+       /**
+        * Sets the values of this variable under a specific set.
+        * 
+        * @param set
+        *            the set identifier for which the values are valid
+        * @param values
+        *            the possible values of this variable
+        */
+       public void setValues(Object set, String[] values) {
+               Assert.isNotNull(set);
+               Assert.isTrue(values.length > 0);
+               fValueMap.put(set, values);
+               if (fDefaultKey == null) {
+                       fDefaultKey = set;
+                       fSet = getDefaultValue();
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.templates.TemplateVariable#setValues(java.lang.String[])
+        */
+       public void setValues(String[] values) {
+               if (fValueMap != null) {
+                       Assert.isNotNull(values);
+                       Assert.isTrue(values.length > 0);
+                       fValueMap.put(fDefaultKey, values);
+                       fSet = getDefaultValue();
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.templates.TemplateVariable#getValues()
+        */
+       public String[] getValues() {
+               return (String[]) fValueMap.get(fDefaultKey);
+       }
+
+       /**
+        * Returns the choices for the set identified by <code>set</code>.
+        * 
+        * @param set
+        *            the set identifier
+        * @return the choices for this variable and the given set, or
+        *         <code>null</code> if the set is not defined.
+        */
+       public String[] getValues(Object set) {
+               return (String[]) fValueMap.get(set);
+       }
+
+       /**
+        * @return
+        */
+       public Object getSet() {
+               return fSet;
+       }
+
+       public void setSet(Object set) {
+               fSet = set;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/MultiVariableGuess.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/MultiVariableGuess.java
new file mode 100644 (file)
index 0000000..1f0ebc2
--- /dev/null
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Global state for templates. Selecting a proposal for the master template
+ * variable will cause the value (and the proposals) for the slave variables to
+ * change.
+ * 
+ * @see MultiVariable
+ */
+public class MultiVariableGuess {
+
+       /**
+        * Implementation of the <code>ICompletionProposal</code> interface and
+        * extension.
+        */
+       class Proposal implements ICompletionProposal,
+                       ICompletionProposalExtension2 {
+
+               /** The string to be displayed in the completion proposal popup */
+               private String fDisplayString;
+
+               /** The replacement string */
+               String fReplacementString;
+
+               /** The replacement offset */
+               private int fReplacementOffset;
+
+               /** The replacement length */
+               private int fReplacementLength;
+
+               /** The cursor position after this proposal has been applied */
+               private int fCursorPosition;
+
+               /** The image to be displayed in the completion proposal popup */
+               private Image fImage;
+
+               /** The context information of this proposal */
+               private IContextInformation fContextInformation;
+
+               /** The additional info of this proposal */
+               private String fAdditionalProposalInfo;
+
+               /**
+                * Creates a new completion proposal based on the provided information.
+                * The replacement string is considered being the display string too.
+                * All remaining fields are set to <code>null</code>.
+                * 
+                * @param replacementString
+                *            the actual string to be inserted into the document
+                * @param replacementOffset
+                *            the offset of the text to be replaced
+                * @param replacementLength
+                *            the length of the text to be replaced
+                * @param cursorPosition
+                *            the position of the cursor following the insert relative
+                *            to replacementOffset
+                */
+               public Proposal(String replacementString, int replacementOffset,
+                               int replacementLength, int cursorPosition) {
+                       this(replacementString, replacementOffset, replacementLength,
+                                       cursorPosition, null, null, null, null);
+               }
+
+               /**
+                * Creates a new completion proposal. All fields are initialized based
+                * on the provided information.
+                * 
+                * @param replacementString
+                *            the actual string to be inserted into the document
+                * @param replacementOffset
+                *            the offset of the text to be replaced
+                * @param replacementLength
+                *            the length of the text to be replaced
+                * @param cursorPosition
+                *            the position of the cursor following the insert relative
+                *            to replacementOffset
+                * @param image
+                *            the image to display for this proposal
+                * @param displayString
+                *            the string to be displayed for the proposal
+                * @param contextInformation
+                *            the context information associated with this proposal
+                * @param additionalProposalInfo
+                *            the additional information associated with this proposal
+                */
+               public Proposal(String replacementString, int replacementOffset,
+                               int replacementLength, int cursorPosition, Image image,
+                               String displayString, IContextInformation contextInformation,
+                               String additionalProposalInfo) {
+                       Assert.isNotNull(replacementString);
+                       Assert.isTrue(replacementOffset >= 0);
+                       Assert.isTrue(replacementLength >= 0);
+                       Assert.isTrue(cursorPosition >= 0);
+
+                       fReplacementString = replacementString;
+                       fReplacementOffset = replacementOffset;
+                       fReplacementLength = replacementLength;
+                       fCursorPosition = cursorPosition;
+                       fImage = image;
+                       fDisplayString = displayString;
+                       fContextInformation = contextInformation;
+                       fAdditionalProposalInfo = additionalProposalInfo;
+               }
+
+               /*
+                * @see ICompletionProposal#apply(IDocument)
+                */
+               public void apply(IDocument document) {
+                       try {
+                               document.replace(fReplacementOffset, fReplacementLength,
+                                               fReplacementString);
+                       } catch (BadLocationException x) {
+                               // ignore
+                       }
+               }
+
+               /*
+                * @see ICompletionProposal#getSelection(IDocument)
+                */
+               public Point getSelection(IDocument document) {
+                       return new Point(fReplacementOffset + fCursorPosition, 0);
+               }
+
+               /*
+                * @see ICompletionProposal#getContextInformation()
+                */
+               public IContextInformation getContextInformation() {
+                       return fContextInformation;
+               }
+
+               /*
+                * @see ICompletionProposal#getImage()
+                */
+               public Image getImage() {
+                       return fImage;
+               }
+
+               /*
+                * @see ICompletionProposal#getDisplayString()
+                */
+               public String getDisplayString() {
+                       if (fDisplayString != null)
+                               return fDisplayString;
+                       return fReplacementString;
+               }
+
+               /*
+                * @see ICompletionProposal#getAdditionalProposalInfo()
+                */
+               public String getAdditionalProposalInfo() {
+                       return fAdditionalProposalInfo;
+               }
+
+               /*
+                * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer,
+                *      char, int, int)
+                */
+               public void apply(ITextViewer viewer, char trigger, int stateMask,
+                               int offset) {
+                       apply(viewer.getDocument());
+               }
+
+               /*
+                * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(org.eclipse.jface.text.ITextViewer,
+                *      boolean)
+                */
+               public void selected(ITextViewer viewer, boolean smartToggle) {
+               }
+
+               /*
+                * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(org.eclipse.jface.text.ITextViewer)
+                */
+               public void unselected(ITextViewer viewer) {
+               }
+
+               /*
+                * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument,
+                *      int, org.eclipse.jface.text.DocumentEvent)
+                */
+               public boolean validate(IDocument document, int offset,
+                               DocumentEvent event) {
+                       try {
+                               String content = document.get(fReplacementOffset,
+                                               fReplacementLength);
+                               if (content.startsWith(fReplacementString))
+                                       return true;
+                       } catch (BadLocationException e) {
+                               // ignore concurrently modified document
+                       }
+                       return false;
+               }
+       }
+
+       private final List fSlaves = new ArrayList();
+
+       private MultiVariable fMaster;
+
+       /**
+        * @param mv
+        */
+       public MultiVariableGuess(MultiVariable mv) {
+               fMaster = mv;
+       }
+
+       /**
+        * @param variable
+        * @return
+        */
+       public ICompletionProposal[] getProposals(MultiVariable variable,
+                       int offset, int length) {
+               if (variable.equals(fMaster)) {
+                       String[] choices = variable.getValues();
+
+                       ICompletionProposal[] ret = new ICompletionProposal[choices.length];
+                       for (int i = 0; i < ret.length; i++) {
+                               ret[i] = new Proposal(choices[i], offset, length, offset
+                                               + length) {
+
+                                       /*
+                                        * @see org.eclipse.jface.text.link.MultiVariableGuess.Proposal#apply(org.eclipse.jface.text.IDocument)
+                                        */
+                                       public void apply(IDocument document) {
+                                               super.apply(document);
+
+                                               try {
+                                                       Object old = fMaster.getSet();
+                                                       fMaster.setSet(fReplacementString);
+                                                       if (!fReplacementString.equals(old)) {
+                                                               for (Iterator it = fSlaves.iterator(); it
+                                                                               .hasNext();) {
+                                                                       VariablePosition pos = (VariablePosition) it
+                                                                                       .next();
+                                                                       String[] values = pos.getVariable()
+                                                                                       .getValues(fReplacementString);
+                                                                       if (values != null)
+                                                                               document.replace(pos.getOffset(), pos
+                                                                                               .getLength(), values[0]);
+                                                               }
+                                                       }
+                                               } catch (BadLocationException e) {
+                                                       // ignore and continue
+                                               }
+
+                                       }
+                               };
+                       }
+
+                       return ret;
+
+               } else {
+
+                       String[] choices = variable.getValues(fMaster.getSet());
+
+                       if (choices == null || choices.length < 2)
+                               return null;
+
+                       ICompletionProposal[] ret = new ICompletionProposal[choices.length];
+                       for (int i = 0; i < ret.length; i++) {
+                               ret[i] = new Proposal(choices[i], offset, length, offset
+                                               + length);
+                       }
+
+                       return ret;
+               }
+       }
+
+       /**
+        * @param position
+        */
+       public void addSlave(VariablePosition position) {
+               fSlaves.add(position);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/PositionBasedCompletionProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/PositionBasedCompletionProposal.java
new file mode 100644 (file)
index 0000000..b2396fb
--- /dev/null
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * An enhanced implementation of the <code>ICompletionProposal</code>
+ * interface implementing all the extension interfaces. It uses a position to
+ * track its replacement offset and length. The position must be set up
+ * externally.
+ */
+public class PositionBasedCompletionProposal implements ICompletionProposal,
+               ICompletionProposalExtension, ICompletionProposalExtension2 {
+
+       /** The string to be displayed in the completion proposal popup */
+       private String fDisplayString;
+
+       /** The replacement string */
+       private String fReplacementString;
+
+       /** The replacement position. */
+       private Position fReplacementPosition;
+
+       /** The cursor position after this proposal has been applied */
+       private int fCursorPosition;
+
+       /** The image to be displayed in the completion proposal popup */
+       private Image fImage;
+
+       /** The context information of this proposal */
+       private IContextInformation fContextInformation;
+
+       /** The additional info of this proposal */
+       private String fAdditionalProposalInfo;
+
+       /**
+        * Creates a new completion proposal based on the provided information. The
+        * replacement string is considered being the display string too. All
+        * remaining fields are set to <code>null</code>.
+        * 
+        * @param replacementString
+        *            the actual string to be inserted into the document
+        * @param replacementPosition
+        *            the position of the text to be replaced
+        * @param cursorPosition
+        *            the position of the cursor following the insert relative to
+        *            replacementOffset
+        */
+       public PositionBasedCompletionProposal(String replacementString,
+                       Position replacementPosition, int cursorPosition) {
+               this(replacementString, replacementPosition, cursorPosition, null,
+                               null, null, null);
+       }
+
+       /**
+        * Creates a new completion proposal. All fields are initialized based on
+        * the provided information.
+        * 
+        * @param replacementString
+        *            the actual string to be inserted into the document
+        * @param replacementPosition
+        *            the position of the text to be replaced
+        * @param cursorPosition
+        *            the position of the cursor following the insert relative to
+        *            replacementOffset
+        * @param image
+        *            the image to display for this proposal
+        * @param displayString
+        *            the string to be displayed for the proposal
+        * @param contextInformation
+        *            the context information associated with this proposal
+        * @param additionalProposalInfo
+        *            the additional information associated with this proposal
+        */
+       public PositionBasedCompletionProposal(String replacementString,
+                       Position replacementPosition, int cursorPosition, Image image,
+                       String displayString, IContextInformation contextInformation,
+                       String additionalProposalInfo) {
+               Assert.isNotNull(replacementString);
+               Assert.isTrue(replacementPosition != null);
+
+               fReplacementString = replacementString;
+               fReplacementPosition = replacementPosition;
+               fCursorPosition = cursorPosition;
+               fImage = image;
+               fDisplayString = displayString;
+               fContextInformation = contextInformation;
+               fAdditionalProposalInfo = additionalProposalInfo;
+       }
+
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public void apply(IDocument document) {
+               try {
+                       document.replace(fReplacementPosition.getOffset(),
+                                       fReplacementPosition.getLength(), fReplacementString);
+               } catch (BadLocationException x) {
+                       // ignore
+               }
+       }
+
+       /*
+        * @see ICompletionProposal#getSelection(IDocument)
+        */
+       public Point getSelection(IDocument document) {
+               return new Point(fReplacementPosition.getOffset() + fCursorPosition, 0);
+       }
+
+       /*
+        * @see ICompletionProposal#getContextInformation()
+        */
+       public IContextInformation getContextInformation() {
+               return fContextInformation;
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return fImage;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               if (fDisplayString != null)
+                       return fDisplayString;
+               return fReplacementString;
+       }
+
+       /*
+        * @see ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               return fAdditionalProposalInfo;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer,
+        *      char, int, int)
+        */
+       public void apply(ITextViewer viewer, char trigger, int stateMask,
+                       int offset) {
+               apply(viewer.getDocument());
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(org.eclipse.jface.text.ITextViewer,
+        *      boolean)
+        */
+       public void selected(ITextViewer viewer, boolean smartToggle) {
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(org.eclipse.jface.text.ITextViewer)
+        */
+       public void unselected(ITextViewer viewer) {
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument,
+        *      int, org.eclipse.jface.text.DocumentEvent)
+        */
+       public boolean validate(IDocument document, int offset, DocumentEvent event) {
+               try {
+                       String content = document.get(fReplacementPosition.getOffset(),
+                                       fReplacementPosition.getLength());
+                       if (content.startsWith(fReplacementString))
+                               return true;
+               } catch (BadLocationException e) {
+                       // ignore concurrently modified document
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#apply(org.eclipse.jface.text.IDocument,
+        *      char, int)
+        */
+       public void apply(IDocument document, char trigger, int offset) {
+               // not called any more
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#isValidFor(org.eclipse.jface.text.IDocument,
+        *      int)
+        */
+       public boolean isValidFor(IDocument document, int offset) {
+               // not called any more
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#getTriggerCharacters()
+        */
+       public char[] getTriggerCharacters() {
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension#getContextInformationPosition()
+        */
+       public int getContextInformationPosition() {
+               return fReplacementPosition.getOffset();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateContentAssistMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateContentAssistMessages.java
new file mode 100644 (file)
index 0000000..c675e0a
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+class TemplateContentAssistMessages {
+
+       private static final String RESOURCE_BUNDLE = TemplateContentAssistMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private TemplateContentAssistMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateContentAssistMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateContentAssistMessages.properties
new file mode 100644 (file)
index 0000000..3664fd8
--- /dev/null
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2000, 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+# template proposal
+TemplateProposal.delimiter=\ - 
+
+# template evaluator
+TemplateEvaluator.error.title=Template Evaluation Error
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateEngine.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateEngine.java
new file mode 100644 (file)
index 0000000..7d6d35d
--- /dev/null
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.internal.corext.Assert;
+import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContext;
+import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.swt.graphics.Point;
+
+public class TemplateEngine {
+
+       private static final String $_LINE_SELECTION = "${" + GlobalTemplateVariables.LineSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String $_WORD_SELECTION = "${" + GlobalTemplateVariables.WordSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+
+       /** The context type. */
+       private TemplateContextType fContextType;
+
+       /** The result proposals. */
+       private ArrayList fProposals = new ArrayList();
+
+       /**
+        * Creates the template engine for a particular context type. See
+        * <code>TemplateContext</code> for supported context types.
+        */
+       public TemplateEngine(TemplateContextType contextType) {
+               Assert.isNotNull(contextType);
+               fContextType = contextType;
+       }
+
+       /**
+        * Empties the collector.
+        */
+       public void reset() {
+               fProposals.clear();
+       }
+
+       /**
+        * Returns the array of matching templates.
+        */
+       public TemplateProposal[] getResults() {
+               return (TemplateProposal[]) fProposals
+                               .toArray(new TemplateProposal[fProposals.size()]);
+       }
+
+       /**
+        * Inspects the context of the compilation unit around
+        * <code>completionPosition</code> and feeds the collector with proposals.
+        * 
+        * @param viewer
+        *            the text viewer
+        * @param completionPosition
+        *            the context position in the document of the text viewer
+        * @param compilationUnit
+        *            the compilation unit (may be <code>null</code>)
+        */
+       public void complete(ITextViewer viewer, int completionPosition,
+                       ICompilationUnit compilationUnit) {
+               IDocument document = viewer.getDocument();
+
+               if (!(fContextType instanceof CompilationUnitContextType))
+                       return;
+
+               Point selection = viewer.getSelectedRange();
+
+               // remember selected text
+               String selectedText = null;
+               if (selection.y != 0) {
+                       try {
+                               selectedText = document.get(selection.x, selection.y);
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               CompilationUnitContext context = ((CompilationUnitContextType) fContextType)
+                               .createContext(document, completionPosition, selection.y,
+                                               compilationUnit);
+               context.setVariable("selection", selectedText); //$NON-NLS-1$
+               int start = context.getStart();
+               int end = context.getEnd();
+               IRegion region = new Region(start, end - start);
+
+               Template[] templates = WebUI.getDefault().getTemplateStore()
+                               .getTemplates();
+
+               if (selection.y == 0) {
+                       for (int i = 0; i != templates.length; i++)
+                               if (context.canEvaluate(templates[i]))
+                                       fProposals.add(new TemplateProposal(templates[i], context,
+                                                       region, PHPUiImages
+                                                                       .get(PHPUiImages.IMG_OBJS_TEMPLATE)));
+
+               } else {
+
+                       if (context.getKey().length() == 0)
+                               context.setForceEvaluation(true);
+
+                       boolean multipleLinesSelected = areMultipleLinesSelected(viewer);
+
+                       for (int i = 0; i != templates.length; i++) {
+                               Template template = templates[i];
+                               if (context.canEvaluate(template)
+                                               && template.getContextTypeId().equals(
+                                                               context.getContextType().getId())
+                                               && (!multipleLinesSelected
+                                                               && template.getPattern().indexOf(
+                                                                               $_WORD_SELECTION) != -1 || (multipleLinesSelected && template
+                                                               .getPattern().indexOf($_LINE_SELECTION) != -1))) {
+                                       fProposals.add(new TemplateProposal(templates[i], context,
+                                                       region, PHPUiImages
+                                                                       .get(PHPUiImages.IMG_OBJS_TEMPLATE)));
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Returns <code>true</code> if one line is completely selected or if
+        * multiple lines are selected. Being completely selected means that all
+        * characters except the new line characters are selected.
+        * 
+        * @return <code>true</code> if one or multiple lines are selected
+        * @since 2.1
+        */
+       private boolean areMultipleLinesSelected(ITextViewer viewer) {
+               if (viewer == null)
+                       return false;
+
+               Point s = viewer.getSelectedRange();
+               if (s.y == 0)
+                       return false;
+
+               try {
+
+                       IDocument document = viewer.getDocument();
+                       int startLine = document.getLineOfOffset(s.x);
+                       int endLine = document.getLineOfOffset(s.x + s.y);
+                       IRegion line = document.getLineInformation(startLine);
+                       return startLine != endLine
+                                       || (s.x == line.getOffset() && s.y == line.getLength());
+
+               } catch (BadLocationException x) {
+                       return false;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateInformationControlCreator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateInformationControlCreator.java
new file mode 100644 (file)
index 0000000..522ac13
--- /dev/null
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import net.sourceforge.phpdt.internal.ui.text.java.hover.SourceViewerInformationControl;
+
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IInformationControlCreatorExtension;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Shell;
+
+final public class TemplateInformationControlCreator implements
+               IInformationControlCreator, IInformationControlCreatorExtension {
+
+       private SourceViewerInformationControl fControl;
+
+       public TemplateInformationControlCreator() {
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell)
+        */
+       public IInformationControl createInformationControl(Shell parent) {
+               fControl = new SourceViewerInformationControl(parent);
+               fControl.addDisposeListener(new DisposeListener() {
+                       public void widgetDisposed(DisposeEvent e) {
+                               fControl = null;
+                       }
+               });
+               return fControl;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReuse(org.eclipse.jface.text.IInformationControl)
+        */
+       public boolean canReuse(IInformationControl control) {
+               return fControl == control && fControl != null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReplace(org.eclipse.jface.text.IInformationControlCreator)
+        */
+       public boolean canReplace(IInformationControlCreator creator) {
+               return (creator != null && getClass() == creator.getClass());
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/TemplateProposal.java
new file mode 100644 (file)
index 0000000..01366dd
--- /dev/null
@@ -0,0 +1,477 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContext;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.EditorHighlightingSynchronizer;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension3;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.link.ILinkedModeListener;
+import org.eclipse.jface.text.link.LinkedModeModel;
+import org.eclipse.jface.text.link.LinkedModeUI;
+import org.eclipse.jface.text.link.LinkedPosition;
+import org.eclipse.jface.text.link.LinkedPositionGroup;
+import org.eclipse.jface.text.link.ProposalPosition;
+import org.eclipse.jface.text.templates.DocumentTemplateContext;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.texteditor.link.EditorLinkedModeUI;
+
+/**
+ * A template proposal.
+ */
+public class TemplateProposal implements IPHPCompletionProposal,
+               ICompletionProposalExtension2, ICompletionProposalExtension3 {
+
+       private final Template fTemplate;
+
+       private final TemplateContext fContext;
+
+       private final Image fImage;
+
+       private IRegion fRegion;
+
+       private int fRelevance;
+
+       private IRegion fSelectedRegion; // initialized by apply()
+
+       private String fDisplayString;
+
+       /**
+        * Creates a template proposal with a template and its context.
+        * 
+        * @param template
+        *            the template
+        * @param context
+        *            the context in which the template was requested
+        * @param region
+        *            the region this proposal applies to
+        * @param image
+        *            the icon of the proposal
+        */
+       public TemplateProposal(Template template, TemplateContext context,
+                       IRegion region, Image image) {
+               Assert.isNotNull(template);
+               Assert.isNotNull(context);
+               Assert.isNotNull(region);
+
+               fTemplate = template;
+               fContext = context;
+               fImage = image;
+               fRegion = region;
+
+               fDisplayString = null;
+
+               if (context instanceof JavaContext) {
+                       switch (((JavaContext) context).getCharacterBeforeStart()) {
+                       // high relevance after whitespace
+                       case ' ':
+                       case '\r':
+                       case '\n':
+                       case '\t':
+                               fRelevance = 90;
+                               break;
+                       default:
+                               fRelevance = 0;
+                       }
+               } else {
+                       fRelevance = 90;
+               }
+       }
+
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public final void apply(IDocument document) {
+               // not called anymore
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer,
+        *      char, int, int)
+        */
+       public void apply(ITextViewer viewer, char trigger, int stateMask,
+                       int offset) {
+
+               try {
+
+                       fContext.setReadOnly(false);
+                       TemplateBuffer templateBuffer;
+                       try {
+                               templateBuffer = fContext.evaluate(fTemplate);
+                       } catch (TemplateException e1) {
+                               fSelectedRegion = fRegion;
+                               return;
+                       }
+
+                       int start = getReplaceOffset();
+                       int end = getReplaceEndOffset();
+                       end = Math.max(end, offset);
+
+                       // insert template string
+                       IDocument document = viewer.getDocument();
+                       String templateString = templateBuffer.getString();
+                       document.replace(start, end - start, templateString);
+
+                       // translate positions
+                       LinkedModeModel model = new LinkedModeModel();
+                       TemplateVariable[] variables = templateBuffer.getVariables();
+
+                       MultiVariableGuess guess = fContext instanceof CompilationUnitContext ? ((CompilationUnitContext) fContext)
+                                       .getMultiVariableGuess()
+                                       : null;
+
+                       boolean hasPositions = false;
+                       for (int i = 0; i != variables.length; i++) {
+                               TemplateVariable variable = variables[i];
+
+                               if (variable.isUnambiguous())
+                                       continue;
+
+                               LinkedPositionGroup group = new LinkedPositionGroup();
+
+                               int[] offsets = variable.getOffsets();
+                               int length = variable.getLength();
+
+                               LinkedPosition first;
+                               if (guess != null && variable instanceof MultiVariable) {
+                                       first = new VariablePosition(document, offsets[0] + start,
+                                                       length, guess, (MultiVariable) variable);
+                                       guess.addSlave((VariablePosition) first);
+                               } else {
+                                       String[] values = variable.getValues();
+                                       ICompletionProposal[] proposals = new ICompletionProposal[values.length];
+                                       for (int j = 0; j < values.length; j++) {
+                                               ensurePositionCategoryInstalled(document, model);
+                                               Position pos = new Position(offsets[0] + start, length);
+                                               document.addPosition(getCategory(), pos);
+                                               proposals[j] = new PositionBasedCompletionProposal(
+                                                               values[j], pos, length);
+                                       }
+
+                                       if (proposals.length > 1)
+                                               first = new ProposalPosition(document, offsets[0]
+                                                               + start, length, proposals);
+                                       else
+                                               first = new LinkedPosition(document,
+                                                               offsets[0] + start, length);
+                               }
+
+                               for (int j = 0; j != offsets.length; j++)
+                                       if (j == 0)
+                                               group.addPosition(first);
+                                       else
+                                               group.addPosition(new LinkedPosition(document,
+                                                               offsets[j] + start, length));
+
+                               model.addGroup(group);
+                               hasPositions = true;
+                       }
+
+                       if (hasPositions) {
+                               model.forceInstall();
+                               PHPEditor editor = getJavaEditor();
+                               if (editor != null) {
+                                       model
+                                                       .addLinkingListener(new EditorHighlightingSynchronizer(
+                                                                       editor));
+                               }
+
+                               LinkedModeUI ui = new EditorLinkedModeUI(model, viewer);
+                               ui.setExitPosition(viewer, getCaretOffset(templateBuffer)
+                                               + start, 0, Integer.MAX_VALUE);
+                               ui.enter();
+
+                               fSelectedRegion = ui.getSelectedRegion();
+                       } else
+                               fSelectedRegion = new Region(getCaretOffset(templateBuffer)
+                                               + start, 0);
+
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+                       openErrorDialog(viewer.getTextWidget().getShell(), e);
+                       fSelectedRegion = fRegion;
+               } catch (BadPositionCategoryException e) {
+                       WebUI.log(e);
+                       openErrorDialog(viewer.getTextWidget().getShell(), e);
+                       fSelectedRegion = fRegion;
+               }
+
+       }
+
+       /**
+        * Returns the currently active java editor, or <code>null</code> if it
+        * cannot be determined.
+        * 
+        * @return the currently active java editor, or <code>null</code>
+        */
+       private PHPEditor getJavaEditor() {
+               IEditorPart part = WebUI.getActivePage().getActiveEditor();
+               if (part instanceof PHPEditor)
+                       return (PHPEditor) part;
+               else
+                       return null;
+       }
+
+       /**
+        * Returns the offset of the range in the document that will be replaced by
+        * applying this template.
+        * 
+        * @return the offset of the range in the document that will be replaced by
+        *         applying this template
+        */
+       private int getReplaceOffset() {
+               int start;
+               if (fContext instanceof DocumentTemplateContext) {
+                       DocumentTemplateContext docContext = (DocumentTemplateContext) fContext;
+                       start = docContext.getStart();
+               } else {
+                       start = fRegion.getOffset();
+               }
+               return start;
+       }
+
+       /**
+        * Returns the end offset of the range in the document that will be replaced
+        * by applying this template.
+        * 
+        * @return the end offset of the range in the document that will be replaced
+        *         by applying this template
+        */
+       private int getReplaceEndOffset() {
+               int end;
+               if (fContext instanceof DocumentTemplateContext) {
+                       DocumentTemplateContext docContext = (DocumentTemplateContext) fContext;
+                       end = docContext.getEnd();
+               } else {
+                       end = fRegion.getOffset() + fRegion.getLength();
+               }
+               return end;
+       }
+
+       private void ensurePositionCategoryInstalled(final IDocument document,
+                       LinkedModeModel model) {
+               if (!document.containsPositionCategory(getCategory())) {
+                       document.addPositionCategory(getCategory());
+                       final InclusivePositionUpdater updater = new InclusivePositionUpdater(
+                                       getCategory());
+                       document.addPositionUpdater(updater);
+
+                       model.addLinkingListener(new ILinkedModeListener() {
+
+                               /*
+                                * @see org.eclipse.jface.text.link.ILinkedModeListener#left(org.eclipse.jface.text.link.LinkedModeModel,
+                                *      int)
+                                */
+                               public void left(LinkedModeModel environment, int flags) {
+                                       try {
+                                               document.removePositionCategory(getCategory());
+                                       } catch (BadPositionCategoryException e) {
+                                               // ignore
+                                       }
+                                       document.removePositionUpdater(updater);
+                               }
+
+                               public void suspend(LinkedModeModel environment) {
+                               }
+
+                               public void resume(LinkedModeModel environment, int flags) {
+                               }
+                       });
+               }
+       }
+
+       private String getCategory() {
+               return "TemplateProposalCategory_" + toString(); //$NON-NLS-1$
+       }
+
+       private int getCaretOffset(TemplateBuffer buffer) {
+
+               TemplateVariable[] variables = buffer.getVariables();
+               for (int i = 0; i != variables.length; i++) {
+                       TemplateVariable variable = variables[i];
+                       if (variable.getType().equals(GlobalTemplateVariables.Cursor.NAME))
+                               return variable.getOffsets()[0];
+               }
+
+               return buffer.getString().length();
+       }
+
+       /*
+        * @see ICompletionProposal#getSelection(IDocument)
+        */
+       public Point getSelection(IDocument document) {
+               return new Point(fSelectedRegion.getOffset(), fSelectedRegion
+                               .getLength());
+       }
+
+       /*
+        * @see ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               try {
+                       fContext.setReadOnly(true);
+                       TemplateBuffer templateBuffer;
+                       try {
+                               templateBuffer = fContext.evaluate(fTemplate);
+                       } catch (TemplateException e1) {
+                               return null;
+                       }
+
+                       return templateBuffer.getString();
+
+               } catch (BadLocationException e) {
+                       handleException(WebUI.getActiveWorkbenchShell(),
+                                       new CoreException(new Status(IStatus.ERROR,
+                                                       WebUI.getPluginId(), IStatus.OK, "", e))); //$NON-NLS-1$
+                       return null;
+               }
+       }
+
+       /*
+        * @see ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               if (fDisplayString == null) {
+                       fDisplayString = fTemplate.getName()
+                                       + TemplateContentAssistMessages
+                                                       .getString("TemplateProposal.delimiter") + fTemplate.getDescription(); //$NON-NLS-1$
+               }
+               return fDisplayString;
+       }
+
+       public void setDisplayString(String displayString) {
+               fDisplayString = displayString;
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return fImage;
+       }
+
+       /*
+        * @see ICompletionProposal#getContextInformation()
+        */
+       public IContextInformation getContextInformation() {
+               return null;
+       }
+
+       private void openErrorDialog(Shell shell, Exception e) {
+               MessageDialog.openError(shell, TemplateContentAssistMessages
+                               .getString("TemplateEvaluator.error.title"), e.getMessage()); //$NON-NLS-1$
+       }
+
+       private void handleException(Shell shell, CoreException e) {
+               ExceptionHandler.handle(e, shell, TemplateContentAssistMessages
+                               .getString("TemplateEvaluator.error.title"), null); //$NON-NLS-1$
+       }
+
+       /*
+        * @see IJavaCompletionProposal#getRelevance()
+        */
+       public int getRelevance() {
+               return fRelevance;
+       }
+
+       public void setRelevance(int relevance) {
+               fRelevance = relevance;
+       }
+
+       public Template getTemplate() {
+               return fTemplate;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getInformationControlCreator()
+        */
+       public IInformationControlCreator getInformationControlCreator() {
+               return new TemplateInformationControlCreator();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(org.eclipse.jface.text.ITextViewer,
+        *      boolean)
+        */
+       public void selected(ITextViewer viewer, boolean smartToggle) {
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(org.eclipse.jface.text.ITextViewer)
+        */
+       public void unselected(ITextViewer viewer) {
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument,
+        *      int, org.eclipse.jface.text.DocumentEvent)
+        */
+       public boolean validate(IDocument document, int offset, DocumentEvent event) {
+               try {
+                       int replaceOffset = getReplaceOffset();
+                       if (offset >= replaceOffset) {
+                               String content = document.get(replaceOffset, offset
+                                               - replaceOffset);
+                               return fTemplate.getName().startsWith(content);
+                       }
+               } catch (BadLocationException e) {
+                       // concurrent modification - ignore
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getReplacementString()
+        */
+       public CharSequence getPrefixCompletionText(IDocument document,
+                       int completionOffset) {
+               return fTemplate.getName();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getReplacementOffset()
+        */
+       public int getPrefixCompletionStart(IDocument document, int completionOffset) {
+               return getReplaceOffset();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/VariablePosition.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/contentassist/VariablePosition.java
new file mode 100644 (file)
index 0000000..6bf87f2
--- /dev/null
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.contentassist;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.link.LinkedPositionGroup;
+import org.eclipse.jface.text.link.ProposalPosition;
+
+/**
+ * 
+ */
+public class VariablePosition extends ProposalPosition {
+
+       private MultiVariableGuess fGuess;
+
+       private MultiVariable fVariable;
+
+       public VariablePosition(IDocument document, int offset, int length,
+                       MultiVariableGuess guess, MultiVariable variable) {
+               this(document, offset, length, LinkedPositionGroup.NO_STOP, guess,
+                               variable);
+       }
+
+       public VariablePosition(IDocument document, int offset, int length,
+                       int sequence, MultiVariableGuess guess, MultiVariable variable) {
+               super(document, offset, length, sequence, null);
+               Assert.isNotNull(guess);
+               Assert.isNotNull(variable);
+               fVariable = variable;
+               fGuess = guess;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.link.ProposalPosition#equals(java.lang.Object)
+        */
+       public boolean equals(Object o) {
+               if (o instanceof VariablePosition && super.equals(o)) {
+                       return fGuess.equals(((VariablePosition) o).fGuess);
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.link.ProposalPosition#hashCode()
+        */
+       public int hashCode() {
+               return super.hashCode() | fGuess.hashCode();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.link.ProposalPosition#getChoices()
+        */
+       public ICompletionProposal[] getChoices() {
+               return fGuess.getProposals(fVariable, offset, length);
+       }
+
+       /**
+        * @return
+        */
+       public MultiVariable getVariable() {
+               return fVariable;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplatePreferencesMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplatePreferencesMessages.java
new file mode 100644 (file)
index 0000000..29a9740
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.preferences;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+class TemplatePreferencesMessages {
+
+       private static final String RESOURCE_BUNDLE = TemplatePreferencesMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private TemplatePreferencesMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplatePreferencesMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplatePreferencesMessages.properties
new file mode 100644 (file)
index 0000000..4cfe7bd
--- /dev/null
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+TemplateVariableProposal.error.title=Error applying template variable proposal
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplateVariableProcessor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplateVariableProcessor.java
new file mode 100644 (file)
index 0000000..ea9665c
--- /dev/null
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.preferences;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+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;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+
+public class TemplateVariableProcessor implements IContentAssistProcessor {
+
+       private static Comparator fgTemplateVariableProposalComparator = new Comparator() {
+               public int compare(Object arg0, Object arg1) {
+                       TemplateVariableProposal proposal0 = (TemplateVariableProposal) arg0;
+                       TemplateVariableProposal proposal1 = (TemplateVariableProposal) arg1;
+
+                       return proposal0.getDisplayString().compareTo(
+                                       proposal1.getDisplayString());
+               }
+
+               public boolean equals(Object arg0) {
+                       return false;
+               }
+       };
+
+       /** the context type */
+       private TemplateContextType fContextType;
+
+       /**
+        * Sets the context type.
+        */
+       public void setContextType(TemplateContextType contextType) {
+               fContextType = contextType;
+       }
+
+       /**
+        * Gets the context type.
+        */
+       public TemplateContextType getContextType() {
+               return fContextType;
+       }
+
+       /*
+        * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
+        */
+       public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
+                       int documentOffset) {
+
+               if (fContextType == null)
+                       return null;
+
+               List proposals = new ArrayList();
+
+               String text = viewer.getDocument().get();
+               int start = getStart(text, documentOffset);
+               int end = documentOffset;
+
+               String string = text.substring(start, end);
+               String prefix = (string.length() >= 2) ? string.substring(2) : null;
+
+               int offset = start;
+               int length = end - start;
+
+               for (Iterator iterator = fContextType.resolvers(); iterator.hasNext();) {
+                       TemplateVariableResolver variable = (TemplateVariableResolver) iterator
+                                       .next();
+
+                       if (prefix == null || variable.getType().startsWith(prefix))
+                               proposals.add(new TemplateVariableProposal(variable, offset,
+                                               length, viewer));
+               }
+
+               Collections.sort(proposals, fgTemplateVariableProposalComparator);
+               return (ICompletionProposal[]) proposals
+                               .toArray(new ICompletionProposal[proposals.size()]);
+       }
+
+       /* Guesses the start position of the completion */
+       private int getStart(String string, int end) {
+               int start = end;
+
+               if (start >= 1 && string.charAt(start - 1) == '$')
+                       return start - 1;
+
+               while ((start != 0)
+                               && Character.isUnicodeIdentifierPart(string.charAt(start - 1)))
+                       start--;
+
+               if (start >= 2 && string.charAt(start - 1) == '{'
+                               && string.charAt(start - 2) == '$')
+                       return start - 2;
+
+               return end;
+       }
+
+       /*
+        * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+        */
+       public IContextInformation[] computeContextInformation(ITextViewer viewer,
+                       int documentOffset) {
+               return null;
+       }
+
+       /*
+        * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+        */
+       public char[] getCompletionProposalAutoActivationCharacters() {
+               return new char[] { '$' };
+       }
+
+       /*
+        * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+        */
+       public char[] getContextInformationAutoActivationCharacters() {
+               return null;
+       }
+
+       /*
+        * @see IContentAssistProcessor#getErrorMessage()
+        */
+       public String getErrorMessage() {
+               return null;
+       }
+
+       /*
+        * @see IContentAssistProcessor#getContextInformationValidator()
+        */
+       public IContextInformationValidator getContextInformationValidator() {
+               return null;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplateVariableProposal.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/template/preferences/TemplateVariableProposal.java
new file mode 100644 (file)
index 0000000..54ec6b3
--- /dev/null
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.template.preferences;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A proposal for insertion of template variables.
+ */
+public class TemplateVariableProposal implements ICompletionProposal {
+
+       private TemplateVariableResolver fVariable;
+
+       private int fOffset;
+
+       private int fLength;
+
+       private ITextViewer fViewer;
+
+       private Point fSelection;
+
+       /**
+        * Creates a template variable proposal.
+        * 
+        * @param variable
+        *            the template variable
+        * @param offset
+        *            the offset to replace
+        * @param length
+        *            the length to replace
+        * @param viewer
+        *            the viewer
+        */
+       public TemplateVariableProposal(TemplateVariableResolver variable,
+                       int offset, int length, ITextViewer viewer) {
+               fVariable = variable;
+               fOffset = offset;
+               fLength = length;
+               fViewer = viewer;
+       }
+
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public void apply(IDocument document) {
+
+               try {
+                       String variable = fVariable.getType().equals("dollar") ? "$$" : "${" + fVariable.getType() + '}'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                       document.replace(fOffset, fLength, variable);
+                       fSelection = new Point(fOffset + variable.length(), 0);
+
+               } catch (BadLocationException e) {
+                       WebUI.log(e);
+
+                       Shell shell = fViewer.getTextWidget().getShell();
+                       MessageDialog
+                                       .openError(
+                                                       shell,
+                                                       TemplatePreferencesMessages
+                                                                       .getString("TemplateVariableProposal.error.title"), e.getMessage()); //$NON-NLS-1$
+               }
+       }
+
+       /*
+        * @see ICompletionProposal#getSelection(IDocument)
+        */
+       public Point getSelection(IDocument document) {
+               return fSelection;
+       }
+
+       /*
+        * @see ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               return null;
+       }
+
+       /*
+        * @see ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return fVariable.getType() + " - " + fVariable.getDescription(); //$NON-NLS-1$
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return null;
+       }
+
+       /*
+        * @see ICompletionProposal#getContextInformation()
+        */
+       public IContextInformation getContextInformation() {
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/DirectorySelector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/DirectorySelector.java
new file mode 100644 (file)
index 0000000..8a686f7
--- /dev/null
@@ -0,0 +1,38 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.io.File;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+
+public class DirectorySelector extends ResourceSelector {
+
+       public DirectorySelector(Composite parent) {
+               super(parent);
+       }
+
+       protected void handleBrowseSelected() {
+               DirectoryDialog dialog = new DirectoryDialog(getShell());
+               dialog.setMessage(browseDialogMessage);
+               String currentWorkingDir = textField.getText();
+               if (!currentWorkingDir.trim().equals("")) {
+                       File path = new File(currentWorkingDir);
+                       if (path.exists()) {
+                               dialog.setFilterPath(currentWorkingDir);
+                       }
+               }
+
+               String selectedDirectory = dialog.open();
+               if (selectedDirectory != null) {
+                       textField.setText(selectedDirectory);
+               }
+       }
+
+       protected String validateResourceSelection() {
+               String directory = textField.getText();
+               File directoryFile = new File(directory);
+               if (directoryFile.exists() && directoryFile.isDirectory())
+                       return directory;
+               return EMPTY_STRING;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/ExceptionHandler.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/ExceptionHandler.java
new file mode 100644 (file)
index 0000000..a5807a9
--- /dev/null
@@ -0,0 +1,86 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+
+public class ExceptionHandler {
+       private static ExceptionHandler fgInstance = new ExceptionHandler();
+
+       public static void log(Throwable t, String message) {
+               WebUI.getDefault().getLog().log(
+                               new Status(IStatus.ERROR, WebUI.PLUGIN_ID,
+                                               IStatus.ERROR, message, t));
+       }
+
+       public static void handle(CoreException e, String title, String message) {
+               handle(e, WebUI.getActiveWorkbenchShell(), title, message);
+       }
+
+       public static void handle(CoreException e, Shell parent, String title,
+                       String message) {
+               fgInstance.perform(e, parent, title, message);
+       }
+
+       public static void handle(InvocationTargetException e, String title,
+                       String message) {
+               handle(e, WebUI.getActiveWorkbenchShell(), title, message);
+       }
+
+       public static void handle(InvocationTargetException e, Shell parent,
+                       String title, String message) {
+               fgInstance.perform(e, parent, title, message);
+       }
+
+       protected void perform(CoreException e, Shell shell, String title,
+                       String message) {
+               WebUI.log(e);
+               IStatus status = e.getStatus();
+               if (status != null) {
+                       ErrorDialog.openError(shell, title, message, status);
+               } else {
+                       displayMessageDialog(e, e.getMessage(), shell, title, message);
+               }
+       }
+
+       protected void perform(InvocationTargetException e, Shell shell,
+                       String title, String message) {
+               Throwable target = e.getTargetException();
+               if (target instanceof CoreException) {
+                       perform((CoreException) target, shell, title, message);
+               } else {
+                       WebUI.log(e);
+                       if (e.getMessage() != null && e.getMessage().length() > 0) {
+                               displayMessageDialog(e, e.getMessage(), shell, title, message);
+                       } else {
+                               displayMessageDialog(e, target.getMessage(), shell, title,
+                                               message);
+                       }
+               }
+       }
+
+       private void displayMessageDialog(Throwable t, String exceptionMessage,
+                       Shell shell, String title, String message) {
+               StringWriter msg = new StringWriter();
+               if (message != null) {
+                       msg.write(message);
+                       msg.write("\n\n");
+               }
+               if (exceptionMessage == null || exceptionMessage.length() == 0)
+                       msg.write(PHPUIMessages
+                                       .getString("ExceptionDialog.seeErrorLogMessage"));
+               else
+                       msg.write(exceptionMessage);
+               MessageDialog.openError(shell, title, msg.toString());
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/FilteredList.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/FilteredList.java
new file mode 100644 (file)
index 0000000..65b17f6
--- /dev/null
@@ -0,0 +1,504 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * A composite widget which holds a list of elements for user selection. The
+ * elements are sorted alphabetically. Optionally, the elements can be filtered
+ * and duplicate entries can be hidden (folding).
+ */
+public class FilteredList extends Composite {
+
+       public interface FilterMatcher {
+               /**
+                * Sets the filter.
+                * 
+                * @param pattern
+                *            the filter pattern.
+                * @param ignoreCase
+                *            a flag indicating whether pattern matching is case
+                *            insensitive or not.
+                * @param ignoreWildCards
+                *            a flag indicating whether wildcard characters are
+                *            interpreted or not.
+                */
+               void setFilter(String pattern, boolean ignoreCase,
+                               boolean ignoreWildCards);
+
+               /**
+                * Returns <code>true</code> if the object matches the pattern,
+                * <code>false</code> otherwise. <code>setFilter()</code> must have
+                * been called at least once prior to a call to this method.
+                */
+               boolean match(Object element);
+       }
+
+       private class DefaultFilterMatcher implements FilterMatcher {
+               private StringMatcher fMatcher;
+
+               public void setFilter(String pattern, boolean ignoreCase,
+                               boolean ignoreWildCards) {
+                       fMatcher = new StringMatcher(pattern + '*', ignoreCase,
+                                       ignoreWildCards);
+               }
+
+               public boolean match(Object element) {
+                       return fMatcher.match(fRenderer.getText(element));
+               }
+       }
+
+       private Table fList;
+
+       private ILabelProvider fRenderer;
+
+       private boolean fMatchEmtpyString = true;
+
+       private boolean fIgnoreCase;
+
+       private boolean fAllowDuplicates;
+
+       private String fFilter = ""; //$NON-NLS-1$
+
+       private TwoArrayQuickSorter fSorter;
+
+       private Object[] fElements = new Object[0];
+
+       private Label[] fLabels;
+
+       private Vector fImages = new Vector();
+
+       private int[] fFoldedIndices;
+
+       private int fFoldedCount;
+
+       private int[] fFilteredIndices;
+
+       private int fFilteredCount;
+
+       private FilterMatcher fFilterMatcher = new DefaultFilterMatcher();
+
+       private Comparator fComparator;
+
+       private static class Label {
+               public final String string;
+
+               public final Image image;
+
+               public Label(String string, Image image) {
+                       this.string = string;
+                       this.image = image;
+               }
+
+               public boolean equals(Label label) {
+                       if (label == null)
+                               return false;
+
+                       return string.equals(label.string) && image.equals(label.image);
+               }
+       }
+
+       private final class LabelComparator implements Comparator {
+               private boolean fIgnoreCase;
+
+               LabelComparator(boolean ignoreCase) {
+                       fIgnoreCase = ignoreCase;
+               }
+
+               public int compare(Object left, Object right) {
+                       Label leftLabel = (Label) left;
+                       Label rightLabel = (Label) right;
+
+                       int value;
+
+                       if (fComparator == null) {
+                               value = fIgnoreCase ? leftLabel.string
+                                               .compareToIgnoreCase(rightLabel.string)
+                                               : leftLabel.string.compareTo(rightLabel.string);
+                       } else {
+                               value = fComparator
+                                               .compare(leftLabel.string, rightLabel.string);
+                       }
+
+                       if (value != 0)
+                               return value;
+
+                       // images are allowed to be null
+                       if (leftLabel.image == null) {
+                               return (rightLabel.image == null) ? 0 : -1;
+                       } else if (rightLabel.image == null) {
+                               return +1;
+                       } else {
+                               return fImages.indexOf(leftLabel.image)
+                                               - fImages.indexOf(rightLabel.image);
+                       }
+               }
+
+       }
+
+       /**
+        * Constructs a new instance of a filtered list.
+        * 
+        * @param parent
+        *            the parent composite.
+        * @param style
+        *            the widget style.
+        * @param renderer
+        *            the label renderer.
+        * @param ignoreCase
+        *            specifies whether sorting and folding is case sensitive.
+        * @param allowDuplicates
+        *            specifies whether folding of duplicates is desired.
+        * @param matchEmptyString
+        *            specifies whether empty filter strings should filter
+        *            everything or nothing.
+        */
+       public FilteredList(Composite parent, int style, ILabelProvider renderer,
+                       boolean ignoreCase, boolean allowDuplicates,
+                       boolean matchEmptyString) {
+               super(parent, SWT.NONE);
+
+               GridLayout layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               setLayout(layout);
+
+               fList = new Table(this, style);
+               fList.setLayoutData(new GridData(GridData.FILL_BOTH));
+               fList.addDisposeListener(new DisposeListener() {
+                       public void widgetDisposed(DisposeEvent e) {
+                               fRenderer.dispose();
+                       }
+               });
+
+               fRenderer = renderer;
+               fIgnoreCase = ignoreCase;
+               fSorter = new TwoArrayQuickSorter(new LabelComparator(ignoreCase));
+               fAllowDuplicates = allowDuplicates;
+               fMatchEmtpyString = matchEmptyString;
+       }
+
+       /**
+        * Sets the list of elements.
+        * 
+        * @param elements
+        *            the elements to be shown in the list.
+        */
+       public void setElements(Object[] elements) {
+               if (elements == null) {
+                       fElements = new Object[0];
+               } else {
+                       // copy list for sorting
+                       fElements = new Object[elements.length];
+                       System.arraycopy(elements, 0, fElements, 0, elements.length);
+               }
+
+               int length = fElements.length;
+
+               // fill labels
+               fLabels = new Label[length];
+               Set imageSet = new HashSet();
+               for (int i = 0; i != length; i++) {
+                       String text = fRenderer.getText(fElements[i]);
+                       Image image = fRenderer.getImage(fElements[i]);
+
+                       fLabels[i] = new Label(text, image);
+                       imageSet.add(image);
+               }
+               fImages.clear();
+               fImages.addAll(imageSet);
+
+               fSorter.sort(fLabels, fElements);
+
+               fFilteredIndices = new int[length];
+               fFilteredCount = filter();
+
+               fFoldedIndices = new int[length];
+               fFoldedCount = fold();
+
+               updateList();
+       }
+
+       /**
+        * Tests if the list (before folding and filtering) is empty.
+        * 
+        * @return returns <code>true</code> if the list is empty,
+        *         <code>false</code> otherwise.
+        */
+       public boolean isEmpty() {
+               return (fElements == null) || (fElements.length == 0);
+       }
+
+       /**
+        * Sets the filter matcher.
+        */
+       public void setFilterMatcher(FilterMatcher filterMatcher) {
+               Assert.isNotNull(filterMatcher);
+               fFilterMatcher = filterMatcher;
+       }
+
+       /**
+        * Sets a custom comparator for sorting the list.
+        */
+       public void setComparator(Comparator comparator) {
+               Assert.isNotNull(comparator);
+               fComparator = comparator;
+       }
+
+       /**
+        * Adds a selection listener to the list.
+        * 
+        * @param listener
+        *            the selection listener to be added.
+        */
+       public void addSelectionListener(SelectionListener listener) {
+               fList.addSelectionListener(listener);
+       }
+
+       /**
+        * Removes a selection listener from the list.
+        * 
+        * @param listener
+        *            the selection listener to be removed.
+        */
+       public void removeSelectionListener(SelectionListener listener) {
+               fList.removeSelectionListener(listener);
+       }
+
+       /**
+        * Sets the selection of the list.
+        * 
+        * @param selection
+        *            an array of indices specifying the selection.
+        */
+       public void setSelection(int[] selection) {
+               fList.setSelection(selection);
+       }
+
+       /**
+        * Returns the selection of the list.
+        * 
+        * @return returns an array of indices specifying the current selection.
+        */
+       public int[] getSelectionIndices() {
+               return fList.getSelectionIndices();
+       }
+
+       /**
+        * Returns the selection of the list. This is a convenience function for
+        * <code>getSelectionIndices()</code>.
+        * 
+        * @return returns the index of the selection, -1 for no selection.
+        */
+       public int getSelectionIndex() {
+               return fList.getSelectionIndex();
+       }
+
+       /**
+        * Sets the selection of the list.
+        * 
+        * @param elements
+        *            the array of elements to be selected.
+        */
+       public void setSelection(Object[] elements) {
+               if ((elements == null) || (fElements == null))
+                       return;
+
+               // fill indices
+               int[] indices = new int[elements.length];
+               for (int i = 0; i != elements.length; i++) {
+                       int j;
+                       for (j = 0; j != fFoldedCount; j++) {
+                               int max = (j == fFoldedCount - 1) ? fFilteredCount
+                                               : fFoldedIndices[j + 1];
+
+                               int l;
+                               for (l = fFoldedIndices[j]; l != max; l++) {
+                                       // found matching element?
+                                       if (fElements[fFilteredIndices[l]].equals(elements[i])) {
+                                               indices[i] = j;
+                                               break;
+                                       }
+                               }
+
+                               if (l != max)
+                                       break;
+                       }
+
+                       // not found
+                       if (j == fFoldedCount)
+                               indices[i] = 0;
+               }
+
+               fList.setSelection(indices);
+       }
+
+       /**
+        * Returns an array of the selected elements. The type of the elements
+        * returned in the list are the same as the ones passed with
+        * <code>setElements</code>. The array does not contain the rendered
+        * strings.
+        * 
+        * @return returns the array of selected elements.
+        */
+       public Object[] getSelection() {
+               if (fList.isDisposed() || (fList.getSelectionCount() == 0))
+                       return new Object[0];
+
+               int[] indices = fList.getSelectionIndices();
+               Object[] elements = new Object[indices.length];
+
+               for (int i = 0; i != indices.length; i++)
+                       elements[i] = fElements[fFilteredIndices[fFoldedIndices[indices[i]]]];
+
+               return elements;
+       }
+
+       /**
+        * Sets the filter pattern. Current only prefix filter patterns are
+        * supported.
+        * 
+        * @param filter
+        *            the filter pattern.
+        */
+       public void setFilter(String filter) {
+               fFilter = (filter == null) ? "" : filter; //$NON-NLS-1$
+
+               fFilteredCount = filter();
+               fFoldedCount = fold();
+               updateList();
+       }
+
+       /**
+        * Returns the filter pattern.
+        * 
+        * @return returns the filter pattern.
+        */
+       public String getFilter() {
+               return fFilter;
+       }
+
+       /**
+        * Returns all elements which are folded together to one entry in the list.
+        * 
+        * @param index
+        *            the index selecting the entry in the list.
+        * @return returns an array of elements folded together, <code>null</code>
+        *         if index is out of range.
+        */
+       public Object[] getFoldedElements(int index) {
+               if ((index < 0) || (index >= fFoldedCount))
+                       return null;
+
+               int start = fFoldedIndices[index];
+               int count = (index == fFoldedCount - 1) ? fFilteredCount - start
+                               : fFoldedIndices[index + 1] - start;
+
+               Object[] elements = new Object[count];
+               for (int i = 0; i != count; i++)
+                       elements[i] = fElements[fFilteredIndices[start + i]];
+
+               return elements;
+       }
+
+       /*
+        * Folds duplicate entries. Two elements are considered as a pair of
+        * duplicates if they coiincide in the rendered string and image. @return
+        * returns the number of elements after folding.
+        */
+       private int fold() {
+               if (fAllowDuplicates) {
+                       for (int i = 0; i != fFilteredCount; i++)
+                               fFoldedIndices[i] = i; // identity mapping
+
+                       return fFilteredCount;
+
+               } else {
+                       int k = 0;
+                       Label last = null;
+                       for (int i = 0; i != fFilteredCount; i++) {
+                               int j = fFilteredIndices[i];
+
+                               Label current = fLabels[j];
+                               if (!current.equals(last)) {
+                                       fFoldedIndices[k] = i;
+                                       k++;
+                                       last = current;
+                               }
+                       }
+                       return k;
+               }
+       }
+
+       /*
+        * Filters the list with the filter pattern. @return returns the number of
+        * elements after filtering.
+        */
+       private int filter() {
+               if (((fFilter == null) || (fFilter.length() == 0))
+                               && !fMatchEmtpyString)
+                       return 0;
+
+               fFilterMatcher.setFilter(fFilter.trim(), fIgnoreCase, false);
+
+               int k = 0;
+               for (int i = 0; i != fElements.length; i++) {
+                       if (fFilterMatcher.match(fElements[i]))
+                               fFilteredIndices[k++] = i;
+               }
+
+               return k;
+       }
+
+       /*
+        * Updates the list widget.
+        */
+       private void updateList() {
+               if (fList.isDisposed())
+                       return;
+
+               fList.setRedraw(false);
+
+               // resize table
+               int itemCount = fList.getItemCount();
+               if (fFoldedCount < itemCount)
+                       fList.remove(0, itemCount - fFoldedCount - 1);
+               else if (fFoldedCount > itemCount)
+                       for (int i = 0; i != fFoldedCount - itemCount; i++)
+                               new TableItem(fList, SWT.NONE);
+
+               // fill table
+               TableItem[] items = fList.getItems();
+               for (int i = 0; i != fFoldedCount; i++) {
+                       TableItem item = items[i];
+                       Label label = fLabels[fFilteredIndices[fFoldedIndices[i]]];
+
+                       item.setText(label.string);
+                       item.setImage(label.image);
+               }
+
+               // select first item if any
+               if (fList.getItemCount() > 0)
+                       fList.setSelection(0);
+
+               fList.setRedraw(true);
+               fList.notifyListeners(SWT.Selection, new Event());
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPElementVisitor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPElementVisitor.java
new file mode 100644 (file)
index 0000000..275bd57
--- /dev/null
@@ -0,0 +1,41 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+
+public class PHPElementVisitor implements IResourceVisitor {
+       protected List phpFiles = new ArrayList();
+
+       public PHPElementVisitor() {
+               super();
+       }
+
+       public boolean visit(IResource resource) throws CoreException {
+               switch (resource.getType()) {
+               case IResource.PROJECT:
+                       return true;
+
+               case IResource.FOLDER:
+                       return true;
+
+               case IResource.FILE:
+                       IFile fileResource = (IFile) resource;
+                       if (PHPFileUtil.isPHPFile(fileResource)) {
+                               phpFiles.add(fileResource);
+                               return true;
+                       }
+
+               default:
+                       return false;
+               }
+       }
+
+       public Object[] getCollectedPHPFiles() {
+               return phpFiles.toArray();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPFileSelector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPFileSelector.java
new file mode 100644 (file)
index 0000000..84dbafd
--- /dev/null
@@ -0,0 +1,114 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+
+public class PHPFileSelector extends ResourceSelector {
+       static class FileLabelProvider extends LabelProvider {
+               /**
+                * Returns the implementation of IWorkbenchAdapter for the given object.
+                * 
+                * @param o
+                *            the object to look up.
+                * @return IWorkbenchAdapter or <code>null</code> if the adapter is
+                *         not defined or the object is not adaptable.
+                */
+               protected final IWorkbenchAdapter getAdapter(Object o) {
+                       if (!(o instanceof IAdaptable)) {
+                               return null;
+                       }
+                       return (IWorkbenchAdapter) ((IAdaptable) o)
+                                       .getAdapter(IWorkbenchAdapter.class);
+               }
+
+               /*
+                * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+                */
+               public String getText(Object element) {
+                       if (element instanceof IFile) {
+                               // query the element for its label
+                               IWorkbenchAdapter adapter = getAdapter(element);
+                               if (adapter == null) {
+                                       return ""; //$NON-NLS-1$
+                               }
+                               String filename = adapter.getLabel(element);
+                               IPath path = ((IFile) element).getFullPath();
+                               String filePathname = path != null ? path.toString() : ""; //$NON-NLS-1$
+                               return filename + " (" + filePathname + ")";
+                       }
+                       return super.getText(element);
+               }
+       }
+
+       protected PHPProjectSelector phpProjectSelector;
+
+       public PHPFileSelector(Composite parent, PHPProjectSelector aProjectSelector) {
+               super(parent);
+               Assert.isNotNull(aProjectSelector);
+               phpProjectSelector = aProjectSelector;
+
+               browseDialogTitle = "File Selection";
+       }
+
+       protected Object[] getPHPFiles() {
+               IProject phpProject = phpProjectSelector.getSelection();
+               if (phpProject == null)
+                       return new Object[0];
+
+               PHPElementVisitor visitor = new PHPElementVisitor();
+               try {
+                       phpProject.accept(visitor);
+               } catch (CoreException e) {
+                       WebUI.log(e);
+               }
+               return visitor.getCollectedPHPFiles();
+       }
+
+       public IFile getSelection() {
+               String fileName = getSelectionText();
+               if (fileName != null && !fileName.equals("")) {
+                       IPath filePath = new Path(fileName);
+                       IProject project = phpProjectSelector.getSelection();
+                       if (project != null && project.exists(filePath))
+                               return project.getFile(filePath);
+               }
+
+               return null;
+       }
+
+       protected void handleBrowseSelected() {
+               // ElementListSelectionDialog dialog = new
+               // ElementListSelectionDialog(getShell(), new WorkbenchLabelProvider());
+               ElementListSelectionDialog dialog = new ElementListSelectionDialog(
+                               getShell(), new FileLabelProvider());
+
+               dialog.setTitle(browseDialogTitle);
+               dialog.setMessage(browseDialogMessage);
+               dialog.setElements(getPHPFiles());
+
+               if (dialog.open() == ElementListSelectionDialog.OK) {
+                       textField.setText(((IResource) dialog.getFirstResult())
+                                       .getProjectRelativePath().toString());
+               }
+       }
+
+       protected String validateResourceSelection() {
+               IFile selection = getSelection();
+               return selection == null ? EMPTY_STRING : selection
+                               .getProjectRelativePath().toString();
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPFileUtil.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPFileUtil.java
new file mode 100644 (file)
index 0000000..b9f3421
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Created on 09.08.2003
+ *
+ */
+
+/*duplicated incastrix*/
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.io.File;
+import java.util.List;
+
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+public class PHPFileUtil {
+       // private static String[] PHP_EXTENSIONS = null;
+
+       public final static String[] SMARTY_EXTENSIONS = { "tpl" };
+
+       public static boolean isPHPFile(IFile file) {
+                return isPHPFileName(file.getFullPath().toString());
+        }
+
+       // public final static String getFileExtension(String name) {
+       // int index = name.lastIndexOf('.');
+       // if (index == -1)
+       // return null;
+       // if (index == (name.length() - 1))
+       // return null; //$NON-NLS-1$
+       // return name.substring(index + 1);
+       // }
+
+       /**
+        * Returns true iff str.toLowerCase().endsWith(".php") implementation is not
+        * creating extra strings.
+        */
+       public final static boolean isPHPFileName(String name) {
+
+               // avoid handling a file without base name, e.g. ".php", which is a
+               // valid
+               // Eclipse resource name
+               File file = new File(name);
+               if (file.getName().startsWith(".")) {
+                       return false;
+               }
+               IWorkbench workbench = PlatformUI.getWorkbench();
+               IEditorRegistry registry = workbench.getEditorRegistry();
+               IEditorDescriptor[] descriptors = registry.getEditors(name);
+
+               for (int i = 0; i < descriptors.length; i++) {
+                       if (descriptors[i].getId().equals(WebUI.EDITOR_ID)) {
+                               return true;
+                       }
+               }
+               // String extension = getFileExtension(name);
+               // if (extension == null) {
+               // return false;
+               // }
+               // extension = extension.toLowerCase();
+               // PHP_EXTENSIONS = getExtensions();
+               // if (PHP_EXTENSIONS == null) {
+               // return false;
+               // }
+               // for (int i = 0; i < PHP_EXTENSIONS.length; i++) {
+               // if (extension.equals(PHP_EXTENSIONS[i])) {
+               // return true;
+               // }
+               // }
+               return false;
+       }
+
+       /**
+        * Returns true iff the file extension is a valid PHP Unit name
+        * implementation is not creating extra strings.
+        */
+       public final static boolean isValidPHPUnitName(String filename) {
+               return PHPFileUtil.isPHPFileName(filename);
+       }
+
+       /**
+        * @return Returns the PHP extensions.
+        */
+       // public static String[] getExtensions() {
+       // if (PHP_EXTENSIONS == null) {
+       // ArrayList list = new ArrayList();
+       // final IPreferenceStore store =
+       // PHPeclipsePlugin.getDefault().getPreferenceStore();
+       // String extensions =
+       // store.getString(PHPeclipsePlugin.PHP_EXTENSION_PREFS);
+       // extensions = extensions.trim();
+       // if (extensions.length() != 0) {
+       // StringTokenizer tokenizer = new StringTokenizer(extensions, " ,;:/-|");
+       // String token;
+       // while (tokenizer.hasMoreTokens()) {
+       // token = tokenizer.nextToken();
+       // if (token != null && token.length() >= 1) {
+       // list.add(token);
+       // }
+       // }
+       // if (list.size() != 0) {
+       // PHP_EXTENSIONS = new String[list.size()];
+       // for (int i = 0; i < list.size(); i++) {
+       // PHP_EXTENSIONS[i] = (String) list.get(i);
+       // }
+       // }
+       // }
+       // }
+       // return PHP_EXTENSIONS;
+       // }
+       /**
+        * @param php_extensions
+        *            The PHP extensions to set.
+        */
+       // public static void setExtensions(String[] php_extensions) {
+       // PHP_EXTENSIONS = php_extensions;
+       // }
+       /**
+        * Creata the file for the given absolute file path
+        * 
+        * @param absoluteFilePath
+        * @param project
+        * @return the file for the given absolute file path or <code>null</code>
+        *         if no existing file can be found
+        */
+       public static IFile createFile(IPath absoluteFilePath, IProject project) {
+               if (absoluteFilePath == null || project == null) {
+                       return null;
+               }
+
+               String projectPath = project.getFullPath().toString();
+               String filePath = absoluteFilePath.toString().substring(
+                               projectPath.length() + 1);
+               return project.getFile(filePath);
+
+       }
+
+       /**
+        * Determine the path of an include name string
+        * 
+        * @param includeNameString
+        * @param resource
+        * @param project
+        * @return the path for the given include filename or <code>null</code> if
+        *         no existing file can be found
+        */
+       public static IPath determineFilePath(String includeNameString,
+                       IResource resource, IProject project) {
+               IPath documentRootPath = ProjectPrefUtil.getDocumentRoot(project);
+               IPath resourcePath = resource.getProjectRelativePath();
+
+               IPath path = null;
+               
+               // script location based
+               path = project.getFullPath().append(resourcePath.removeLastSegments(1))
+                               .append(includeNameString);
+               //path = 
+               if (fileExists(path, false)) {
+                       return path;
+               }
+               // project root based
+               path = project.getFullPath().append(includeNameString);
+               if (fileExists(path, false)) {
+                       return path;
+               }
+               
+               // DocumentRoot (absolute path) based
+               path = documentRootPath.append(includeNameString);
+               if (fileExists(path, true)) {
+                       return path;
+               }
+
+               // IncludePaths settings (absolute path) based
+               List includePaths = ProjectPrefUtil.getIncludePaths(project);
+               if (includePaths.size() > 0) {
+                       for (int i = 0; i < includePaths.size(); i++) {
+                               path = new Path(includePaths.get(i).toString())
+                                               .append(includeNameString);
+                               if (fileExists(path, true)) {
+                                       return path;
+                               }
+                       }
+               }
+               return null;
+       }
+
+       private static boolean fileExists(IPath path, boolean absolute) {
+               File file = path.toFile();
+               if (file.exists()) {
+                       return true;
+               }
+               if (!absolute) {
+                       IFile ifile = FileBuffers.getWorkspaceFileAtLocation(path);
+                       if (ifile != null) {
+                           IResource resource = ifile;
+                if (resource.exists()) {
+                    return true;
+                }
+                       }
+               }
+               return false;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPProjectSelector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PHPProjectSelector.java
new file mode 100644 (file)
index 0000000..034d691
--- /dev/null
@@ -0,0 +1,45 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+public class PHPProjectSelector extends ResourceSelector {
+
+       public PHPProjectSelector(Composite parent) {
+               super(parent);
+
+               browseDialogTitle = "Project Selection";
+       }
+
+       public IProject getSelection() {
+               String projectName = getSelectionText();
+               if (projectName != null && !projectName.equals(""))
+                       return WebUI.getWorkspace().getRoot().getProject(
+                                       projectName);
+
+               return null;
+       }
+
+       protected void handleBrowseSelected() {
+               ElementListSelectionDialog dialog = new ElementListSelectionDialog(
+                               getShell(), new WorkbenchLabelProvider());
+               dialog.setTitle(browseDialogTitle);
+               dialog.setMessage(browseDialogMessage);
+               dialog.setElements(JavaCore.getPHPProjects());
+
+               if (dialog.open() == ElementListSelectionDialog.OK) {
+                       textField.setText(((IProject) dialog.getFirstResult()).getName());
+               }
+       }
+
+       protected String validateResourceSelection() {
+               IProject project = getSelection();
+               return project == null ? EMPTY_STRING : project.getName();
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PixelConverter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/PixelConverter.java
new file mode 100644 (file)
index 0000000..46ace94
--- /dev/null
@@ -0,0 +1,49 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+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();
+       }
+
+       private FontMetrics fgFontMetrics;
+
+       /**
+        * @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/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/ResourceSelector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/ResourceSelector.java
new file mode 100644 (file)
index 0000000..42e78de
--- /dev/null
@@ -0,0 +1,96 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public abstract class ResourceSelector {
+       protected final static String EMPTY_STRING = "";
+
+       protected Composite composite;
+
+       protected Button browseButton;
+
+       protected Text textField;
+
+       protected String browseDialogMessage = EMPTY_STRING;
+
+       protected String browseDialogTitle = EMPTY_STRING;
+
+       protected String validatedSelectionText = EMPTY_STRING;
+
+       public ResourceSelector(Composite parent) {
+               composite = new Composite(parent, SWT.NONE);
+               GridLayout compositeLayout = new GridLayout();
+               compositeLayout.marginWidth = 0;
+               compositeLayout.marginHeight = 0;
+               compositeLayout.numColumns = 2;
+               composite.setLayout(compositeLayout);
+
+               textField = new Text(composite, SWT.SINGLE | SWT.BORDER);
+               textField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               textField.addModifyListener(new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               validatedSelectionText = validateResourceSelection();
+                       }
+               });
+
+               browseButton = new Button(composite, SWT.PUSH);
+               browseButton.setText("Browse...");
+               browseButton.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               handleBrowseSelected();
+                       }
+               });
+       }
+
+       protected abstract void handleBrowseSelected();
+
+       protected abstract String validateResourceSelection();
+
+       protected Shell getShell() {
+               return composite.getShell();
+       }
+
+       public void setLayoutData(Object layoutData) {
+               composite.setLayoutData(layoutData);
+       }
+
+       public void addModifyListener(ModifyListener aListener) {
+               textField.addModifyListener(aListener);
+       }
+
+       public void setBrowseDialogMessage(String aMessage) {
+               browseDialogMessage = aMessage;
+       }
+
+       public void setBrowseDialogTitle(String aTitle) {
+               browseDialogTitle = aTitle;
+       }
+
+       public void setEnabled(boolean enabled) {
+               composite.setEnabled(enabled);
+               textField.setEnabled(enabled);
+               browseButton.setEnabled(enabled);
+       }
+
+       public String getSelectionText() {
+               return textField.getText();
+       }
+
+       public String getValidatedSelectionText() {
+               return validatedSelectionText;
+       }
+
+       public void setSelectionText(String newText) {
+               textField.setText(newText);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/SWTUtil.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/SWTUtil.java
new file mode 100644 (file)
index 0000000..979463c
--- /dev/null
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.util;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.Assert;
+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 disaply. 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);
+       }
+
+       /**
+        * Returns a height hint for a button control.
+        */
+       public static int getButtonHeightHint(Button button) {
+               button.setFont(JFaceResources.getDialogFont());
+               PixelConverter converter = new PixelConverter(button);
+               return converter
+                               .convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
+       }
+
+       /**
+        * 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).heightHint = getButtonHeightHint(button);
+                       ((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/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/StreamUtil.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/StreamUtil.java
new file mode 100644 (file)
index 0000000..5cdf1b9
--- /dev/null
@@ -0,0 +1,29 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class StreamUtil {
+       public static void transferStreams(InputStream source,
+                       OutputStream destination) throws IOException {
+               try {
+                       byte[] buffer = new byte[8192];
+                       while (true) {
+                               int bytesRead = source.read(buffer);
+                               if (bytesRead == -1)
+                                       break;
+                               destination.write(buffer, 0, bytesRead);
+                       }
+               } finally {
+                       try {
+                               source.close();
+                       } catch (IOException e) {
+                       }
+                       try {
+                               destination.close();
+                       } catch (IOException e) {
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/StringMatcher.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/StringMatcher.java
new file mode 100644 (file)
index 0000000..756f28e
--- /dev/null
@@ -0,0 +1,440 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.Vector;
+
+/**
+ * A string pattern matcher, suppporting * and ? wildcards.
+ */
+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 which 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 <code>text</code>, the String object to search in 
+        * @param <code>start</code>, the starting index of the search range, inclusive
+        * @param <code>end</code>, 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 <code>text</code>, 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 String
+        *            <code>text</code>, a String object that contains the
+        *            substring to match
+        * @param int
+        *            <code>start<code> marks the starting position (inclusive) of the substring
+        * @param int <code>end<code> 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;
+                       }
+               }
+
+               /* 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.
+        * 
+        * @param p,
+        *            a String object that is a simple regular expression with ï¿½*�
+        *            and/or ï¿½?�
+        */
+       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 <code>text</code>, a string which contains no wildcard
+        * @param <code>start</code>, the starting index in the text for search,
+        *            inclusive
+        * @param <code>end</code>, 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 <code>text</code>, a simple regular expression that may only
+        *            contain '?'(s)
+        * @param <code>start</code>, the starting index in the text for search,
+        *            inclusive
+        * @param <code>end</code>, the stopping point of search, exclusive
+        * @param <code>p</code>, a simple regular expression that may contains '?'
+        * @param <code>caseIgnored</code>, wether the pattern is not casesensitive
+        * @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;
+       }
+
+       /**
+        * 
+        * @return boolean
+        * @param <code>text</code>, a String to match
+        * @param <code>start</code>, int that indicates the starting index of
+        *            match, inclusive
+        * @param <code>end</code> int that indicates the ending index of match,
+        *            exclusive
+        * @param <code>p</code>, String, String, a simple regular expression that
+        *            may contain '?'
+        * @param <code>ignoreCase</code>, boolean indicating wether code>p</code>
+        *            is case sensitive
+        */
+       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 <code>text</code>, the string to match
+        * @param <code>start</code>, the starting index in the text for search,
+        *            inclusive
+        * @param <code>end</code>, the stopping point of search, exclusive
+        * @param code>p
+        *            </code>, a string that has no wildcard
+        * @param <code>
+        *            ignoreCase</code>, boolean indicating wether code>p</code>
+        *            is case sensitive
+        * @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;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TabFolderLayout.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TabFolderLayout.java
new file mode 100644 (file)
index 0000000..7c2f0cb
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+package net.sourceforge.phpdt.internal.ui.util;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Layout;
+
+public class TabFolderLayout extends Layout {
+
+       protected Point computeSize(Composite composite, int wHint, int hHint,
+                       boolean flushCache) {
+               if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT)
+                       return new Point(wHint, hHint);
+
+               Control[] children = composite.getChildren();
+               int count = children.length;
+               int maxWidth = 0, maxHeight = 0;
+               for (int i = 0; i < count; i++) {
+                       Control child = children[i];
+                       Point pt = child.computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
+                       maxWidth = Math.max(maxWidth, pt.x);
+                       maxHeight = Math.max(maxHeight, pt.y);
+               }
+
+               if (wHint != SWT.DEFAULT)
+                       maxWidth = wHint;
+               if (hHint != SWT.DEFAULT)
+                       maxHeight = hHint;
+
+               return new Point(maxWidth, maxHeight);
+
+       }
+
+       protected void layout(Composite composite, boolean flushCache) {
+               Rectangle rect = composite.getClientArea();
+
+               Control[] children = composite.getChildren();
+               for (int i = 0; i < children.length; i++) {
+                       children[i].setBounds(rect);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TableLayoutComposite.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TableLayoutComposite.java
new file mode 100644 (file)
index 0000000..9f55883
--- /dev/null
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * A special composite to layout columns inside a table. The composite is needed
+ * since we have to layout the columns "before" the actual table gets layouted.
+ * Hence we can't use a normal layout manager.
+ */
+public class TableLayoutComposite extends Composite {
+
+       private List columns = new ArrayList();
+
+       /**
+        * Creates a new <code>TableLayoutComposite</code>.
+        */
+       public TableLayoutComposite(Composite parent, int style) {
+               super(parent, style);
+               addControlListener(new ControlAdapter() {
+                       public void controlResized(ControlEvent e) {
+                               Rectangle area = getClientArea();
+                               Table table = (Table) getChildren()[0];
+                               Point preferredSize = computeTableSize(table);
+                               int width = area.width - 2 * table.getBorderWidth();
+                               if (preferredSize.y > area.height) {
+                                       // Subtract the scrollbar width from the total column width
+                                       // if a vertical scrollbar will be required
+                                       Point vBarSize = table.getVerticalBar().getSize();
+                                       width -= vBarSize.x;
+                               }
+                               layoutTable(table, width, area, table.getSize().x < area.width);
+                       }
+               });
+       }
+
+       /**
+        * Adds a new column of data to this table layout.
+        * 
+        * @param data
+        *            the column layout data
+        */
+       public void addColumnData(ColumnLayoutData data) {
+               columns.add(data);
+       }
+
+       // ---- Helpers
+       // -------------------------------------------------------------------------------------
+
+       private Point computeTableSize(Table table) {
+               Point result = table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+               int width = 0;
+               int size = columns.size();
+               for (int i = 0; i < size; ++i) {
+                       ColumnLayoutData layoutData = (ColumnLayoutData) columns.get(i);
+                       if (layoutData instanceof ColumnPixelData) {
+                               ColumnPixelData col = (ColumnPixelData) layoutData;
+                               width += col.width;
+                       } else if (layoutData instanceof ColumnWeightData) {
+                               ColumnWeightData col = (ColumnWeightData) layoutData;
+                               width += col.minimumWidth;
+                       } else {
+                               Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
+                       }
+               }
+               if (width > result.x)
+                       result.x = width;
+               return result;
+       }
+
+       private void layoutTable(Table table, int width, Rectangle area,
+                       boolean increase) {
+               // XXX: Layout is being called with an invalid value the first time
+               // it is being called on Linux. This method resets the
+               // Layout to null so we make sure we run it only when
+               // the value is OK.
+               if (width <= 1)
+                       return;
+
+               TableColumn[] tableColumns = table.getColumns();
+               int size = Math.min(columns.size(), tableColumns.length);
+               int[] widths = new int[size];
+               int fixedWidth = 0;
+               int numberOfWeightColumns = 0;
+               int totalWeight = 0;
+
+               // First calc space occupied by fixed columns
+               for (int i = 0; i < size; i++) {
+                       ColumnLayoutData col = (ColumnLayoutData) columns.get(i);
+                       if (col instanceof ColumnPixelData) {
+                               int pixels = ((ColumnPixelData) col).width;
+                               widths[i] = pixels;
+                               fixedWidth += pixels;
+                       } else if (col instanceof ColumnWeightData) {
+                               ColumnWeightData cw = (ColumnWeightData) col;
+                               numberOfWeightColumns++;
+                               // first time, use the weight specified by the column data,
+                               // otherwise use the actual width as the weight
+                               // int weight = firstTime ? cw.weight :
+                               // tableColumns[i].getWidth();
+                               int weight = cw.weight;
+                               totalWeight += weight;
+                       } else {
+                               Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
+                       }
+               }
+
+               // Do we have columns that have a weight
+               if (numberOfWeightColumns > 0) {
+                       // Now distribute the rest to the columns with weight.
+                       int rest = width - fixedWidth;
+                       int totalDistributed = 0;
+                       for (int i = 0; i < size; ++i) {
+                               ColumnLayoutData col = (ColumnLayoutData) columns.get(i);
+                               if (col instanceof ColumnWeightData) {
+                                       ColumnWeightData cw = (ColumnWeightData) col;
+                                       // calculate weight as above
+                                       // int weight = firstTime ? cw.weight :
+                                       // tableColumns[i].getWidth();
+                                       int weight = cw.weight;
+                                       int pixels = totalWeight == 0 ? 0 : weight * rest
+                                                       / totalWeight;
+                                       if (pixels < cw.minimumWidth)
+                                               pixels = cw.minimumWidth;
+                                       totalDistributed += pixels;
+                                       widths[i] = pixels;
+                               }
+                       }
+
+                       // Distribute any remaining pixels to columns with weight.
+                       int diff = rest - totalDistributed;
+                       for (int i = 0; diff > 0; ++i) {
+                               if (i == size)
+                                       i = 0;
+                               ColumnLayoutData col = (ColumnLayoutData) columns.get(i);
+                               if (col instanceof ColumnWeightData) {
+                                       ++widths[i];
+                                       --diff;
+                               }
+                       }
+               }
+
+               if (increase) {
+                       table.setSize(area.width, area.height);
+               }
+               for (int i = 0; i < size; i++) {
+                       tableColumns[i].setWidth(widths[i]);
+               }
+               if (!increase) {
+                       table.setSize(area.width, area.height);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TwoArrayQuickSorter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/util/TwoArrayQuickSorter.java
new file mode 100644 (file)
index 0000000..86db922
--- /dev/null
@@ -0,0 +1,111 @@
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.Comparator;
+
+import org.eclipse.jface.util.Assert;
+
+/**
+ * Quick sort to sort key-value pairs. The keys and arrays are specified in
+ * separate arrays.
+ */
+public class TwoArrayQuickSorter {
+
+       private Comparator fComparator;
+
+       /**
+        * Default comparator.
+        */
+       public static final class StringComparator implements Comparator {
+               private boolean fIgnoreCase;
+
+               StringComparator(boolean ignoreCase) {
+                       fIgnoreCase = ignoreCase;
+               }
+
+               public int compare(Object left, Object right) {
+                       return fIgnoreCase ? ((String) left)
+                                       .compareToIgnoreCase((String) right) : ((String) left)
+                                       .compareTo((String) right);
+               }
+       }
+
+       /**
+        * Creates a sorter with default string comparator. The keys are assumed to
+        * be strings.
+        * 
+        * @param ignoreCase
+        *            specifies whether sorting is case sensitive or not.
+        */
+       public TwoArrayQuickSorter(boolean ignoreCase) {
+               fComparator = new StringComparator(ignoreCase);
+       }
+
+       /**
+        * Creates a sorter with a comparator.
+        * 
+        * @param comparator
+        *            the comparator to order the elements. The comparator must not
+        *            be <code>null</code>.
+        */
+       public TwoArrayQuickSorter(Comparator comparator) {
+               fComparator = comparator;
+       }
+
+       /**
+        * Sorts keys and values in parallel.
+        * 
+        * @param keys
+        *            the keys to use for sorting.
+        * @param values
+        *            the values associated with the keys.
+        */
+       public void sort(Object[] keys, Object[] values) {
+               if ((keys == null) || (values == null)) {
+                       Assert.isTrue(false, "Either keys or values in null"); //$NON-NLS-1$
+                       return;
+               }
+
+               if (keys.length <= 1)
+                       return;
+
+               internalSort(keys, values, 0, keys.length - 1);
+       }
+
+       private void internalSort(Object[] keys, Object[] values, int left,
+                       int right) {
+               int original_left = left;
+               int original_right = right;
+
+               Object mid = keys[(left + right) / 2];
+               do {
+                       while (fComparator.compare(keys[left], mid) < 0)
+                               left++;
+
+                       while (fComparator.compare(mid, keys[right]) < 0)
+                               right--;
+
+                       if (left <= right) {
+                               swap(keys, left, right);
+                               swap(values, left, right);
+                               left++;
+                               right--;
+                       }
+               } while (left <= right);
+
+               if (original_left < right)
+                       internalSort(keys, values, original_left, right);
+
+               if (left < original_right)
+                       internalSort(keys, values, left, original_right);
+       }
+
+       /*
+        * Swaps x[a] with x[b].
+        */
+       private static final void swap(Object x[], int a, int b) {
+               Object t = x[a];
+               x[a] = x[b];
+               x[b] = t;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/AppearanceAwareLabelProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/AppearanceAwareLabelProvider.java
new file mode 100644 (file)
index 0000000..bbed6ac
--- /dev/null
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+
+/**
+ * JavaUILabelProvider that respects settings from the Appearance preference
+ * page. Triggers a viewer update when a preference changes.
+ */
+public class AppearanceAwareLabelProvider extends JavaUILabelProvider implements
+               IPropertyChangeListener {
+
+       public final static int DEFAULT_TEXTFLAGS = JavaElementLabels.ROOT_VARIABLE
+                       | JavaElementLabels.M_PARAMETER_TYPES
+                       | JavaElementLabels.M_APP_RETURNTYPE
+                       | JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED;
+
+       public final static int DEFAULT_IMAGEFLAGS = JavaElementImageProvider.OVERLAY_ICONS;
+
+       private int fTextFlagMask;
+
+       private int fImageFlagMask;
+
+       /**
+        * Constructor for AppearanceAwareLabelProvider.
+        */
+       public AppearanceAwareLabelProvider(int textFlags, int imageFlags) {
+               super(textFlags, imageFlags);
+               initMasks();
+               PreferenceConstants.getPreferenceStore()
+                               .addPropertyChangeListener(this);
+       }
+
+       /**
+        * Creates a labelProvider with DEFAULT_TEXTFLAGS and DEFAULT_IMAGEFLAGS
+        */
+       public AppearanceAwareLabelProvider() {
+               this(DEFAULT_TEXTFLAGS, DEFAULT_IMAGEFLAGS);
+       }
+
+       private void initMasks() {
+               IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+               fTextFlagMask = -1;
+               if (!store.getBoolean(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE)) {
+                       fTextFlagMask ^= JavaElementLabels.M_APP_RETURNTYPE;
+               }
+               if (!store
+                               .getBoolean(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)) {
+                       fTextFlagMask ^= JavaElementLabels.P_COMPRESSED;
+               }
+
+               fImageFlagMask = -1;
+       }
+
+       /*
+        * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+        */
+       public void propertyChange(PropertyChangeEvent event) {
+               String property = event.getProperty();
+               if (property.equals(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE)
+                               || property
+                                               .equals(PreferenceConstants.APPEARANCE_PKG_NAME_PATTERN_FOR_PKG_VIEW)
+                               || property
+                                               .equals(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)) {
+                       initMasks();
+                       LabelProviderChangedEvent lpEvent = new LabelProviderChangedEvent(
+                                       this, null); // refresh all
+                       fireLabelProviderChanged(lpEvent);
+               }
+       }
+
+       /*
+        * @see IBaseLabelProvider#dispose()
+        */
+       public void dispose() {
+               PreferenceConstants.getPreferenceStore().removePropertyChangeListener(
+                               this);
+               super.dispose();
+       }
+
+       /*
+        * @see JavaUILabelProvider#evaluateImageFlags()
+        */
+       protected int evaluateImageFlags(Object element) {
+               return getImageFlags() & fImageFlagMask;
+       }
+
+       /*
+        * @see JavaUILabelProvider#evaluateTextFlags()
+        */
+       protected int evaluateTextFlags(Object element) {
+               return getTextFlags() & fTextFlagMask;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ContainerCheckedTreeViewer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ContainerCheckedTreeViewer.java
new file mode 100644 (file)
index 0000000..0bd7141
--- /dev/null
@@ -0,0 +1,181 @@
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * CheckboxTreeViewer with special behaviour of the checked / gray state on
+ * container (non-leaf) nodes: The grayed state is used to visualize the checked
+ * state of its children. Containers are checked and non-gary if all contained
+ * leafs are checked. The container is grayed if some but not all leafs are
+ * checked.
+ */
+public class ContainerCheckedTreeViewer extends CheckboxTreeViewer {
+
+       /**
+        * Constructor for ContainerCheckedTreeViewer.
+        * 
+        * @see CheckboxTreeViewer#CheckboxTreeViewer(Composite)
+        */
+       public ContainerCheckedTreeViewer(Composite parent) {
+               super(parent);
+               initViewer();
+       }
+
+       /**
+        * Constructor for ContainerCheckedTreeViewer.
+        * 
+        * @see CheckboxTreeViewer#CheckboxTreeViewer(Composite,int)
+        */
+       public ContainerCheckedTreeViewer(Composite parent, int style) {
+               super(parent, style);
+               initViewer();
+       }
+
+       /**
+        * Constructor for ContainerCheckedTreeViewer.
+        * 
+        * @see CheckboxTreeViewer#CheckboxTreeViewer(Tree)
+        */
+       public ContainerCheckedTreeViewer(Tree tree) {
+               super(tree);
+               initViewer();
+       }
+
+       private void initViewer() {
+               setUseHashlookup(true);
+               addCheckStateListener(new ICheckStateListener() {
+                       public void checkStateChanged(CheckStateChangedEvent event) {
+                               doCheckStateChanged(event.getElement());
+                       }
+               });
+               addTreeListener(new ITreeViewerListener() {
+                       public void treeCollapsed(TreeExpansionEvent event) {
+                       }
+
+                       public void treeExpanded(TreeExpansionEvent event) {
+                               Widget item = findItem(event.getElement());
+                               if (item instanceof TreeItem) {
+                                       initializeItem((TreeItem) item);
+                               }
+                       }
+               });
+       }
+
+       protected void doCheckStateChanged(Object element) {
+               Widget item = findItem(element);
+               if (item instanceof TreeItem) {
+                       TreeItem treeItem = (TreeItem) item;
+                       treeItem.setGrayed(false);
+                       updateChildrenItems(treeItem);
+                       updateParentItems(treeItem.getParentItem());
+               }
+       }
+
+       /**
+        * The item has expanded. Updates the checked state of its children.
+        */
+       private void initializeItem(TreeItem item) {
+               if (item.getChecked() && !item.getGrayed()) {
+                       updateChildrenItems((TreeItem) item);
+               }
+       }
+
+       /**
+        * Updates the check state of all created children
+        */
+       private void updateChildrenItems(TreeItem parent) {
+               Item[] children = getChildren(parent);
+               boolean state = parent.getChecked();
+               for (int i = 0; i < children.length; i++) {
+                       TreeItem curr = (TreeItem) children[i];
+                       if (curr.getData() != null
+                                       && ((curr.getChecked() != state) || curr.getGrayed())) {
+                               curr.setChecked(state);
+                               curr.setGrayed(false);
+                               updateChildrenItems(curr);
+                       }
+               }
+       }
+
+       /**
+        * Updates the check / gray state of all parent items
+        */
+       private void updateParentItems(TreeItem item) {
+               if (item != null) {
+                       Item[] children = getChildren(item);
+                       boolean containsChecked = false;
+                       boolean containsUnchecked = false;
+                       for (int i = 0; i < children.length; i++) {
+                               TreeItem curr = (TreeItem) children[i];
+                               containsChecked |= curr.getChecked();
+                               containsUnchecked |= (!curr.getChecked() || curr.getGrayed());
+                       }
+                       item.setChecked(containsChecked);
+                       item.setGrayed(containsChecked && containsUnchecked);
+                       updateParentItems(item.getParentItem());
+               }
+       }
+
+       public boolean setChecked(Object element, boolean state) {
+               if (super.setChecked(element, state)) {
+                       doCheckStateChanged(element);
+                       return true;
+               }
+               return false;
+       }
+
+       public void setCheckedElements(Object[] elements) {
+               super.setCheckedElements(elements);
+               for (int i = 0; i < elements.length; i++) {
+                       doCheckStateChanged(elements[i]);
+               }
+       }
+
+       protected void setExpanded(Item item, boolean expand) {
+               super.setExpanded(item, expand);
+               if (expand && item instanceof TreeItem) {
+                       initializeItem((TreeItem) item);
+               }
+       }
+
+       public Object[] getCheckedElements() {
+               Object[] checked = super.getCheckedElements();
+               // add all items that are children of a checked node but not created yet
+               ArrayList result = new ArrayList();
+               for (int i = 0; i < checked.length; i++) {
+                       Object curr = checked[i];
+                       result.add(curr);
+                       Widget item = findItem(curr);
+                       if (item != null) {
+                               Item[] children = getChildren(item);
+                               // check if contains the dummy node
+                               if (children.length == 1 && children[0].getData() == null) {
+                                       // not yet created
+                                       collectChildren(curr, result);
+                               }
+                       }
+               }
+               return result.toArray();
+       }
+
+       private void collectChildren(Object element, ArrayList result) {
+               Object[] filteredChildren = getFilteredChildren(element);
+               for (int i = 0; i < filteredChildren.length; i++) {
+                       Object curr = filteredChildren[i];
+                       result.add(curr);
+                       collectChildren(curr, result);
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/DecoratingJavaLabelProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/DecoratingJavaLabelProvider.java
new file mode 100644 (file)
index 0000000..268cfaf
--- /dev/null
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import net.sourceforge.phpdt.ui.OverrideIndicatorLabelDecorator;
+import net.sourceforge.phpdt.ui.ProblemsLabelDecorator;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Decorator prepared for the switch to use lightweight label decorators:
+ * uncomment the lbale decorator entries in plugin.xml and change
+ * USE_LIGHTWEIGHT to true. Certain views don't want problems or override
+ * indicators, so they signal this in the constructor. So on each getImage the
+ * corrsponding decorators are turned off and on again.
+ */
+public class DecoratingJavaLabelProvider extends DecoratingLabelProvider {
+
+       private static final boolean USE_LIGHTWEIGHT = false;
+
+       private static final String PROBLEM_DECORATOR_ID = "net.sourceforge.phpdt.ui.problem.decorator"; //$NON-NLS-1$
+
+       private static final String OVERRIDE_DECORATOR_ID = "net.sourceforge.phpdt.ui.override.decorator"; //$NON-NLS-1$
+
+       private boolean fUseErrorTick;
+
+       private boolean fUseOverride;
+
+       /**
+        * Decorating label provider for Java. Combines a JavaUILabelProvider with
+        * problem and override indicuator with the workbench decorator (label
+        * decorator extension point).
+        */
+       public DecoratingJavaLabelProvider(JavaUILabelProvider labelProvider) {
+               this(labelProvider, true, true);
+       }
+
+       /**
+        * Decorating label provider for Java. Combines a JavaUILabelProvider (if
+        * enabled with problem and override indicator) with the workbench decorator
+        * (label decorator extension point).
+        */
+       public DecoratingJavaLabelProvider(JavaUILabelProvider labelProvider,
+                       boolean errorTick, boolean override) {
+               super(labelProvider, PlatformUI.getWorkbench().getDecoratorManager()
+                               .getLabelDecorator());
+               fUseErrorTick = errorTick;
+               fUseOverride = override;
+               if (!USE_LIGHTWEIGHT) {
+                       if (errorTick) {
+                               labelProvider
+                                               .addLabelDecorator(new ProblemsLabelDecorator(null));
+                       }
+                       if (override) {
+                               labelProvider
+                                               .addLabelDecorator(new OverrideIndicatorLabelDecorator(
+                                                               null));
+                       }
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+        */
+       public Image getImage(Object element) {
+               if (USE_LIGHTWEIGHT) {
+                       IDecoratorManager manager = PlatformUI.getWorkbench()
+                                       .getDecoratorManager();
+
+                       boolean disableErrorTick = manager.getEnabled(PROBLEM_DECORATOR_ID)
+                                       && !fUseErrorTick;
+                       boolean disableOverride = manager.getEnabled(OVERRIDE_DECORATOR_ID)
+                                       && !fUseOverride;
+                       try {
+                               if (disableErrorTick) {
+                                       manager.setEnabled(PROBLEM_DECORATOR_ID, false);
+                               }
+                               if (disableOverride) {
+                                       manager.setEnabled(OVERRIDE_DECORATOR_ID, false);
+                               }
+                               Image image = super.getImage(element);
+                               if (disableErrorTick) {
+                                       manager.setEnabled(PROBLEM_DECORATOR_ID, true);
+                               }
+                               if (disableOverride) {
+                                       manager.setEnabled(OVERRIDE_DECORATOR_ID, true);
+                               }
+                               return image;
+                       } catch (CoreException e) {
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+               return super.getImage(element);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+        */
+       public String getText(Object element) {
+               if (USE_LIGHTWEIGHT) {
+                       IDecoratorManager manager = PlatformUI.getWorkbench()
+                                       .getDecoratorManager();
+
+                       boolean disableErrorTick = manager.getEnabled(PROBLEM_DECORATOR_ID)
+                                       && !fUseErrorTick;
+                       boolean disableOverride = manager.getEnabled(OVERRIDE_DECORATOR_ID)
+                                       && !fUseOverride;
+                       try {
+                               if (disableErrorTick) {
+                                       manager.setEnabled(PROBLEM_DECORATOR_ID, false);
+                               }
+                               if (disableOverride) {
+                                       manager.setEnabled(OVERRIDE_DECORATOR_ID, false);
+                               }
+                               String text = super.getText(element);
+                               if (disableErrorTick) {
+                                       manager.setEnabled(PROBLEM_DECORATOR_ID, true);
+                               }
+                               if (disableOverride) {
+                                       manager.setEnabled(OVERRIDE_DECORATOR_ID, true);
+                               }
+                               return text;
+                       } catch (CoreException e) {
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+               return super.getText(element);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/FilterUpdater.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/FilterUpdater.java
new file mode 100644 (file)
index 0000000..f115b51
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.widgets.Control;
+
+public class FilterUpdater implements IResourceChangeListener {
+
+       private StructuredViewer fViewer;
+
+       public FilterUpdater(StructuredViewer viewer) {
+               Assert.isNotNull(viewer);
+               fViewer = viewer;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+        */
+       public void resourceChanged(IResourceChangeEvent event) {
+               IResourceDelta delta = event.getDelta();
+               if (delta == null)
+                       return;
+
+               IResourceDelta[] projDeltas = delta
+                               .getAffectedChildren(IResourceDelta.CHANGED);
+               for (int i = 0; i < projDeltas.length; i++) {
+                       IResourceDelta pDelta = projDeltas[i];
+                       if ((pDelta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
+                               final Control ctrl = fViewer.getControl();
+                               if (ctrl != null && !ctrl.isDisposed()) {
+                                       // async is needed due to bug 33783
+                                       ctrl.getDisplay().asyncExec(new Runnable() {
+                                               public void run() {
+                                                       if (!ctrl.isDisposed())
+                                                               fViewer.refresh(false);
+                                               }
+                                       });
+                               }
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/IProblemChangedListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/IProblemChangedListener.java
new file mode 100644 (file)
index 0000000..948ba8c
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ * Can be added to a ProblemMarkerManager to get notified about problem marker
+ * changes. Used to update error ticks.
+ */
+public interface IProblemChangedListener {
+
+       /**
+        * Called when problems changed. This call is posted in an aynch exec,
+        * therefore passed resources must not exist.
+        * 
+        * @param changedElements
+        *            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/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ISelectionListenerWithAST.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ISelectionListenerWithAST.java
new file mode 100644 (file)
index 0000000..4bd1312
--- /dev/null
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Listener to be informed on text selection changes in an editor (post
+ * selection), including the corresponding AST. The AST is shared and must not
+ * be modified. Listeners can be registered in a
+ * <code>SelectionListenerWithASTManager</code>.
+ */
+public interface ISelectionListenerWithAST {
+
+       /**
+        * Called when a selection has changed. The method is called in a post
+        * selection event in an background thread.
+        * 
+        * @param part
+        *            The editor part in which the selection change has occured.
+        * @param selection
+        *            The new text selection
+        * @param astRoot
+        *            The AST tree corresponding to the editor's input. This AST is
+        *            shared and must not be modified.
+        */
+       void selectionChanged(IEditorPart part, ITextSelection selection);
+       // void selectionChanged(IEditorPart part, ITextSelection selection,
+       // CompilationUnit astRoot);
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/IViewPartInputProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/IViewPartInputProvider.java
new file mode 100644 (file)
index 0000000..137cd08
--- /dev/null
@@ -0,0 +1,15 @@
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+/**
+ * Interface common to all view parts that provide an input.
+ */
+public interface IViewPartInputProvider {
+
+       /**
+        * Returns the input.
+        * 
+        * @return the input object
+        */
+       public Object getViewPartInput();
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageDescriptorRegistry.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageDescriptorRegistry.java
new file mode 100644 (file)
index 0000000..5e1d19d
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.Assert;
+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 fRegistry = new HashMap(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 diaplay
+        *            the display the images managed by this registry are allocated
+        *            for
+        */
+       public ImageDescriptorRegistry(Display display) {
+               fDisplay = display;
+               Assert.isNotNull(fDisplay);
+               hookDisplay();
+       }
+
+       /**
+        * Returns the image assiciated 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 (Iterator iter = fRegistry.values().iterator(); iter.hasNext();) {
+                       Image image = (Image) iter.next();
+                       image.dispose();
+               }
+               fRegistry.clear();
+       }
+
+       private void hookDisplay() {
+               fDisplay.disposeExec(new Runnable() {
+                       public void run() {
+                               dispose();
+                       }
+               });
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageImageDescriptor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ImageImageDescriptor.java
new file mode 100644 (file)
index 0000000..f49ca9f
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+
+/**
+ */
+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/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementImageProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementImageProvider.java
new file mode 100644 (file)
index 0000000..f0b4ca1
--- /dev/null
@@ -0,0 +1,460 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IField;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.ui.JavaElementImageDescriptor;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.ide.IDE.SharedImages;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+
+/**
+ * Default strategy of the Java plugin for the construction of Java element
+ * icons.
+ */
+public class JavaElementImageProvider {
+
+       /**
+        * Flags for the JavaImageLabelProvider: Generate images with overlays.
+        */
+       public final static int OVERLAY_ICONS = 0x1;
+
+       /**
+        * Generate small sized images.
+        */
+       public final static int SMALL_ICONS = 0x2;
+
+       /**
+        * Use the 'light' style for rendering types.
+        */
+       public final static int LIGHT_TYPE_ICONS = 0x4;
+
+       public static final Point SMALL_SIZE = new Point(16, 16);
+
+       public static final Point BIG_SIZE = new Point(22, 16);
+
+       private static ImageDescriptor DESC_OBJ_PROJECT_CLOSED;
+
+       private static ImageDescriptor DESC_OBJ_PROJECT;
+
+       private static ImageDescriptor DESC_OBJ_FOLDER;
+       {
+               ISharedImages images = WebUI.getDefault().getWorkbench()
+                               .getSharedImages();
+               DESC_OBJ_PROJECT_CLOSED = images
+                               .getImageDescriptor(SharedImages.IMG_OBJ_PROJECT_CLOSED);
+               DESC_OBJ_PROJECT = images
+                               .getImageDescriptor(SharedImages.IMG_OBJ_PROJECT);
+               DESC_OBJ_FOLDER = images
+                               .getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);
+       }
+
+       private ImageDescriptorRegistry fRegistry;
+
+       public JavaElementImageProvider() {
+               fRegistry = null; // lazy initialization
+       }
+
+       /**
+        * Returns the icon for a given element. The icon depends on the element
+        * type and element properties. If configured, overlay icons are constructed
+        * for <code>ISourceReference</code>s.
+        * 
+        * @param flags
+        *            Flags as defined by the JavaImageLabelProvider
+        */
+       public Image getImageLabel(Object element, int flags) {
+               return getImageLabel(computeDescriptor(element, flags));
+       }
+
+       private Image getImageLabel(ImageDescriptor descriptor) {
+               if (descriptor == null)
+                       return null;
+               return getRegistry().get(descriptor);
+       }
+
+       private ImageDescriptorRegistry getRegistry() {
+               if (fRegistry == null) {
+                       fRegistry = WebUI.getImageDescriptorRegistry();
+               }
+               return fRegistry;
+       }
+
+       private ImageDescriptor computeDescriptor(Object element, int flags) {
+               if (element instanceof IJavaElement) {
+                       return getJavaImageDescriptor((IJavaElement) element, flags);
+               } else if (element instanceof IFile) {
+                       IFile file = (IFile) element;
+                       if ("java".equals(file.getFileExtension())) { //$NON-NLS-1$
+                               return getCUResourceImageDescriptor(file, flags); // image for
+                                                                                                                                       // a CU not
+                                                                                                                                       // on the
+                                                                                                                                       // build
+                                                                                                                                       // path
+                       }
+                       return getWorkbenchImageDescriptor(file, flags);
+               } else if (element instanceof IAdaptable) {
+                       return getWorkbenchImageDescriptor((IAdaptable) element, flags);
+               }
+               return null;
+       }
+
+       private static boolean showOverlayIcons(int flags) {
+               return (flags & OVERLAY_ICONS) != 0;
+       }
+
+       private static boolean useSmallSize(int flags) {
+               return (flags & SMALL_ICONS) != 0;
+       }
+
+       private static boolean useLightIcons(int flags) {
+               return (flags & LIGHT_TYPE_ICONS) != 0;
+       }
+
+       /**
+        * Returns an image descriptor for a compilatio unit not on the class path.
+        * The descriptor includes overlays, if specified.
+        */
+       public ImageDescriptor getCUResourceImageDescriptor(IFile file, int flags) {
+               Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE;
+               return new JavaElementImageDescriptor(
+                               PHPUiImages.DESC_OBJS_CUNIT_RESOURCE, 0, size);
+       }
+
+       /**
+        * Returns an image descriptor for a java element. The descriptor includes
+        * overlays, if specified.
+        */
+       public ImageDescriptor getJavaImageDescriptor(IJavaElement element,
+                       int flags) {
+               int adornmentFlags = computeJavaAdornmentFlags(element, flags);
+               Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE;
+               return new JavaElementImageDescriptor(getBaseImageDescriptor(element,
+                               flags), adornmentFlags, size);
+       }
+
+       /**
+        * Returns an image descriptor for a IAdaptable. The descriptor includes
+        * overlays, if specified (only error ticks apply). Returns
+        * <code>null</code> if no image could be found.
+        */
+       public ImageDescriptor getWorkbenchImageDescriptor(IAdaptable adaptable,
+                       int flags) {
+               IWorkbenchAdapter wbAdapter = (IWorkbenchAdapter) adaptable
+                               .getAdapter(IWorkbenchAdapter.class);
+               if (wbAdapter == null) {
+                       return null;
+               }
+               ImageDescriptor descriptor = wbAdapter.getImageDescriptor(adaptable);
+               if (descriptor == null) {
+                       return null;
+               }
+
+               Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE;
+               return new JavaElementImageDescriptor(descriptor, 0, size);
+       }
+
+       // ---- Computation of base image key
+       // -------------------------------------------------
+
+       /**
+        * Returns an image descriptor for a java element. This is the base image,
+        * no overlays.
+        */
+       public ImageDescriptor getBaseImageDescriptor(IJavaElement element,
+                       int renderFlags) {
+               IType type = null;
+               boolean isInterface = false;
+               try {
+                       switch (element.getElementType()) {
+                       case IJavaElement.INITIALIZER:
+                               return PHPUiImages.DESC_MISC_PRIVATE; // 23479
+                       case IJavaElement.METHOD:
+                               IMember member = (IMember) element;
+                               type = member.getDeclaringType();
+                               isInterface = (type != null)
+                                               && member.getDeclaringType().isInterface();
+                               return getMethodImageDescriptor(isInterface, member.getFlags());
+                       case IJavaElement.FIELD:
+                               IField field = (IField) element;
+                               return getFieldImageDescriptor(field.getDeclaringType()
+                                               .isInterface(), field.getFlags());
+
+                       case IJavaElement.PACKAGE_DECLARATION:
+                               return PHPUiImages.DESC_OBJS_PACKDECL;
+
+                       case IJavaElement.IMPORT_DECLARATION:
+                               return PHPUiImages.DESC_OBJS_IMPDECL;
+
+                       case IJavaElement.IMPORT_CONTAINER:
+                               return PHPUiImages.DESC_OBJS_IMPCONT;
+
+                       case IJavaElement.TYPE: {
+                               type = (IType) element;
+                               isInterface = type.isInterface();
+
+                               if (useLightIcons(renderFlags)) {
+                                       return isInterface ? PHPUiImages.DESC_OBJS_INTERFACEALT
+                                                       : PHPUiImages.DESC_OBJS_CLASSALT;
+                               }
+                               boolean isInner = type.getDeclaringType() != null;
+                               return getTypeImageDescriptor(isInterface, isInner, type
+                                               .getFlags());
+                       }
+
+                       case IJavaElement.PACKAGE_FRAGMENT_ROOT: {
+                               IPackageFragmentRoot root = (IPackageFragmentRoot) element;
+                               // if (root.isArchive()) {
+                               // IPath attach= root.getSourceAttachmentPath();
+                               // if (root.isExternal()) {
+                               // if (attach == null) {
+                               // return PHPUiImages.DESC_OBJS_EXTJAR;
+                               // } else {
+                               // return PHPUiImages.DESC_OBJS_EXTJAR_WSRC;
+                               // }
+                               // } else {
+                               // if (attach == null) {
+                               // return PHPUiImages.DESC_OBJS_JAR;
+                               // } else {
+                               // return PHPUiImages.DESC_OBJS_JAR_WSRC;
+                               // }
+                               // }
+                               // } else {
+                               return PHPUiImages.DESC_OBJS_PACKFRAG_ROOT;
+                               // }
+                       }
+
+                       case IJavaElement.PACKAGE_FRAGMENT:
+                               return getPackageFragmentIcon(element, renderFlags);
+
+                       case IJavaElement.COMPILATION_UNIT:
+                               return PHPUiImages.DESC_OBJS_CUNIT;
+
+                       case IJavaElement.CLASS_FILE:
+                               /*
+                                * this is too expensive for large packages try { IClassFile
+                                * cfile= (IClassFile)element; if (cfile.isClass()) return
+                                * PHPUiImages.IMG_OBJS_CFILECLASS; return
+                                * PHPUiImages.IMG_OBJS_CFILEINT; } catch(JavaModelException e) { //
+                                * fall through; }
+                                */
+                               return PHPUiImages.DESC_OBJS_CFILE;
+
+                       case IJavaElement.JAVA_PROJECT:
+                               IJavaProject jp = (IJavaProject) element;
+                               if (jp.getProject().isOpen()) {
+                                       IProject project = jp.getProject();
+                                       IWorkbenchAdapter adapter = (IWorkbenchAdapter) project
+                                                       .getAdapter(IWorkbenchAdapter.class);
+                                       if (adapter != null) {
+                                               ImageDescriptor result = adapter
+                                                               .getImageDescriptor(project);
+                                               if (result != null)
+                                                       return result;
+                                       }
+                                       return DESC_OBJ_PROJECT;
+                               }
+                               return DESC_OBJ_PROJECT_CLOSED;
+
+                       case IJavaElement.JAVA_MODEL:
+                               return PHPUiImages.DESC_OBJS_JAVA_MODEL;
+                       }
+
+                       Assert.isTrue(false, PHPUIMessages
+                                       .getString("JavaImageLabelprovider.assert.wrongImage")); //$NON-NLS-1$
+                       return null; //$NON-NLS-1$
+
+               } catch (JavaModelException e) {
+                       if (e.isDoesNotExist())
+                               return PHPUiImages.DESC_OBJS_UNKNOWN;
+                       PHPeclipsePlugin.log(e);
+                       return PHPUiImages.DESC_OBJS_GHOST;
+               }
+       }
+
+       protected ImageDescriptor getPackageFragmentIcon(IJavaElement element,
+                       int renderFlags) throws JavaModelException {
+               // IPackageFragment fragment= (IPackageFragment)element;
+               // boolean containsJavaElements= false;
+               // try {
+               // containsJavaElements= fragment.hasChildren();
+               // } catch(JavaModelException e) {
+               // // assuming no children;
+               // }
+               // if(!containsJavaElements && (fragment.getNonJavaResources().length >
+               // 0))
+               // return PHPUiImages.DESC_OBJS_EMPTY_PACKAGE_RESOURCES;
+               // else if (!containsJavaElements)
+               // return PHPUiImages.DESC_OBJS_EMPTY_PACKAGE;
+               return PHPUiImages.DESC_OBJS_PACKAGE;
+       }
+
+       public void dispose() {
+       }
+
+       // ---- Methods to compute the adornments flags
+       // ---------------------------------
+
+       private int computeJavaAdornmentFlags(IJavaElement element, int renderFlags) {
+               int flags = 0;
+               if (showOverlayIcons(renderFlags) && element instanceof IMember) {
+                       try {
+                               IMember member = (IMember) element;
+
+                               if (element.getElementType() == IJavaElement.METHOD
+                                               && ((IMethod) element).isConstructor())
+                                       flags |= JavaElementImageDescriptor.CONSTRUCTOR;
+
+                               int modifiers = member.getFlags();
+                               if (Flags.isAbstract(modifiers) && confirmAbstract(member))
+                                       flags |= JavaElementImageDescriptor.ABSTRACT;
+                               if (Flags.isFinal(modifiers) || isInterfaceField(member))
+                                       flags |= JavaElementImageDescriptor.FINAL;
+                               // if (Flags.isSynchronized(modifiers) &&
+                               // confirmSynchronized(member))
+                               // flags |= JavaElementImageDescriptor.SYNCHRONIZED;
+                               if (Flags.isStatic(modifiers) || isInterfaceField(member))
+                                       flags |= JavaElementImageDescriptor.STATIC;
+
+                               // if (member.getElementType() == IJavaElement.TYPE) {
+                               // if (JavaModelUtil.hasMainMethod((IType) member)) {
+                               // flags |= JavaElementImageDescriptor.RUNNABLE;
+                               // }
+                               // }
+                       } catch (JavaModelException e) {
+                               // do nothing. Can't compute runnable adornment or get flags
+                       }
+               }
+               return flags;
+       }
+
+       private static boolean confirmAbstract(IMember element)
+                       throws JavaModelException {
+               // never show the abstract symbol on interfaces or members in interfaces
+               if (element.getElementType() == IJavaElement.TYPE) {
+                       return ((IType) element).isClass();
+               }
+               return element.getDeclaringType().isClass();
+       }
+
+       private static boolean isInterfaceField(IMember element)
+                       throws JavaModelException {
+               // always show the final && static symbol on interface fields
+               if (element.getElementType() == IJavaElement.FIELD) {
+                       return element.getDeclaringType().isInterface();
+               }
+               return false;
+       }
+
+       private static boolean confirmSynchronized(IJavaElement member) {
+               // Synchronized types are allowed but meaningless.
+               return member.getElementType() != IJavaElement.TYPE;
+       }
+
+       public static ImageDescriptor getMethodImageDescriptor(
+                       boolean isInInterface, int flags) {
+               if (Flags.isPublic(flags) || isInInterface)
+                       return PHPUiImages.DESC_MISC_PUBLIC;
+               if (Flags.isProtected(flags))
+                       return PHPUiImages.DESC_MISC_PROTECTED;
+               if (Flags.isPrivate(flags))
+                       return PHPUiImages.DESC_MISC_PRIVATE;
+
+               return PHPUiImages.DESC_MISC_DEFAULT;
+       }
+
+       public static ImageDescriptor getFieldImageDescriptor(
+                       boolean isInInterface, int flags) {
+               if (Flags.isPublic(flags) || isInInterface)
+                       return PHPUiImages.DESC_FIELD_PUBLIC;
+               if (Flags.isProtected(flags))
+                       return PHPUiImages.DESC_FIELD_PROTECTED;
+               if (Flags.isPrivate(flags))
+                       return PHPUiImages.DESC_FIELD_PRIVATE;
+
+               return PHPUiImages.DESC_FIELD_DEFAULT;
+       }
+
+       public static ImageDescriptor getTypeImageDescriptor(boolean isInterface,
+                       boolean isInner, int flags) {
+               if (isInner) {
+                       if (isInterface) {
+                               return getInnerInterfaceImageDescriptor(flags);
+                       } else {
+                               return getInnerClassImageDescriptor(flags);
+                       }
+               } else {
+                       if (isInterface) {
+                               return getInterfaceImageDescriptor(flags);
+                       } else {
+                               return getClassImageDescriptor(flags);
+                       }
+               }
+       }
+
+       private static ImageDescriptor getClassImageDescriptor(int flags) {
+               if (Flags.isPublic(flags) || Flags.isProtected(flags)
+                               || Flags.isPrivate(flags))
+                       return PHPUiImages.DESC_OBJS_CLASS;
+               else
+                       return PHPUiImages.DESC_OBJS_CLASS_DEFAULT;
+       }
+
+       private static ImageDescriptor getInnerClassImageDescriptor(int flags) {
+               if (Flags.isPublic(flags))
+                       return PHPUiImages.DESC_OBJS_INNER_CLASS_PUBLIC;
+               else if (Flags.isPrivate(flags))
+                       return PHPUiImages.DESC_OBJS_INNER_CLASS_PRIVATE;
+               else if (Flags.isProtected(flags))
+                       return PHPUiImages.DESC_OBJS_INNER_CLASS_PROTECTED;
+               else
+                       return PHPUiImages.DESC_OBJS_INNER_CLASS_DEFAULT;
+       }
+
+       private static ImageDescriptor getInterfaceImageDescriptor(int flags) {
+               if (Flags.isPublic(flags) || Flags.isProtected(flags)
+                               || Flags.isPrivate(flags))
+                       return PHPUiImages.DESC_OBJS_INTERFACE;
+               else
+                       return PHPUiImages.DESC_OBJS_INTERFACE_DEFAULT;
+       }
+
+       private static ImageDescriptor getInnerInterfaceImageDescriptor(int flags) {
+               if (Flags.isPublic(flags))
+                       return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PUBLIC;
+               else if (Flags.isPrivate(flags))
+                       return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PRIVATE;
+               else if (Flags.isProtected(flags))
+                       return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PROTECTED;
+               else
+                       return PHPUiImages.DESC_OBJS_INTERFACE_DEFAULT;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementLabels.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaElementLabels.java
new file mode 100644 (file)
index 0000000..801580e
--- /dev/null
@@ -0,0 +1,811 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IField;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.Signature;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+
+public class JavaElementLabels {
+
+       /**
+        * Method names contain parameter types. e.g. <code>foo(int)</code>
+        */
+       public final static int M_PARAMETER_TYPES = 1 << 0;
+
+       /**
+        * Method names contain parameter names. e.g. <code>foo(index)</code>
+        */
+       public final static int M_PARAMETER_NAMES = 1 << 1;
+
+       /**
+        * Method names contain thrown exceptions. e.g.
+        * <code>foo throws IOException</code>
+        */
+       public final static int M_EXCEPTIONS = 1 << 2;
+
+       /**
+        * Method names contain return type (appended) e.g. <code>foo : int</code>
+        */
+       public final static int M_APP_RETURNTYPE = 1 << 3;
+
+       /**
+        * Method names contain return type (appended) e.g. <code>int foo</code>
+        */
+       public final static int M_PRE_RETURNTYPE = 1 << 4;
+
+       /**
+        * Method names are fully qualified. e.g. <code>java.util.Vector.size</code>
+        */
+       public final static int M_FULLY_QUALIFIED = 1 << 5;
+
+       /**
+        * Method names are post qualified. e.g.
+        * <code>size - java.util.Vector</code>
+        */
+       public final static int M_POST_QUALIFIED = 1 << 6;
+
+       /**
+        * Initializer names are fully qualified. e.g.
+        * <code>java.util.Vector.{ ... }</code>
+        */
+       public final static int I_FULLY_QUALIFIED = 1 << 7;
+
+       /**
+        * Type names are post qualified. e.g. <code>{ ... } - java.util.Map</code>
+        */
+       public final static int I_POST_QUALIFIED = 1 << 8;
+
+       /**
+        * Field names contain the declared type (appended) e.g.
+        * <code>int fHello</code>
+        */
+       public final static int F_APP_TYPE_SIGNATURE = 1 << 9;
+
+       /**
+        * Field names contain the declared type (prepended) e.g.
+        * <code>fHello : int</code>
+        */
+       public final static int F_PRE_TYPE_SIGNATURE = 1 << 10;
+
+       /**
+        * Fields names are fully qualified. e.g. <code>java.lang.System.out</code>
+        */
+       public final static int F_FULLY_QUALIFIED = 1 << 11;
+
+       /**
+        * Fields names are post qualified. e.g. <code>out - java.lang.System</code>
+        */
+       public final static int F_POST_QUALIFIED = 1 << 12;
+
+       /**
+        * Type names are fully qualified. e.g. <code>java.util.Map.MapEntry</code>
+        */
+       public final static int T_FULLY_QUALIFIED = 1 << 13;
+
+       /**
+        * Type names are type container qualified. e.g. <code>Map.MapEntry</code>
+        */
+       public final static int T_CONTAINER_QUALIFIED = 1 << 14;
+
+       /**
+        * Type names are post qualified. e.g. <code>MapEntry - java.util.Map</code>
+        */
+       public final static int T_POST_QUALIFIED = 1 << 15;
+
+       /**
+        * Declarations (import container / declarartion, package declarartion) are
+        * qualified. e.g. <code>java.util.Vector.class/import container</code>
+        */
+       public final static int D_QUALIFIED = 1 << 16;
+
+       /**
+        * Declarations (import container / declarartion, package declarartion) are
+        * post qualified. e.g.
+        * <code>import container - java.util.Vector.class</code>
+        */
+       public final static int D_POST_QUALIFIED = 1 << 17;
+
+       /**
+        * Class file names are fully qualified. e.g.
+        * <code>java.util.Vector.class</code>
+        */
+       public final static int CF_QUALIFIED = 1 << 18;
+
+       /**
+        * Class file names are post qualified. e.g.
+        * <code>Vector.class - java.util</code>
+        */
+       public final static int CF_POST_QUALIFIED = 1 << 19;
+
+       /**
+        * Compilation unit names are fully qualified. e.g.
+        * <code>java.util.Vector.java</code>
+        */
+       public final static int CU_QUALIFIED = 1 << 20;
+
+       /**
+        * Compilation unit names are post qualified. e.g.
+        * <code>Vector.java - java.util</code>
+        */
+       public final static int CU_POST_QUALIFIED = 1 << 21;
+
+       /**
+        * Package names are qualified. e.g. <code>MyProject/src/java.util</code>
+        */
+       public final static int P_QUALIFIED = 1 << 22;
+
+       /**
+        * Package names are post qualified. e.g.
+        * <code>java.util - MyProject/src</code>
+        */
+       public final static int P_POST_QUALIFIED = 1 << 23;
+
+       /**
+        * Package Fragment Roots contain variable name if from a variable. e.g.
+        * <code>JRE_LIB - c:\java\lib\rt.jar</code>
+        */
+       public final static int ROOT_VARIABLE = 1 << 24;
+
+       /**
+        * Package Fragment Roots contain the project name if not an archive
+        * (prepended). e.g. <code>MyProject/src</code>
+        */
+       public final static int ROOT_QUALIFIED = 1 << 25;
+
+       /**
+        * Package Fragment Roots contain the project name if not an archive
+        * (appended). e.g. <code>src - MyProject</code>
+        */
+       public final static int ROOT_POST_QUALIFIED = 1 << 26;
+
+       /**
+        * Add root path to all elements except Package Fragment Roots and Java
+        * projects. e.g. <code>java.lang.Vector - c:\java\lib\rt.jar</code>
+        * Option only applies to getElementLabel
+        */
+       public final static int APPEND_ROOT_PATH = 1 << 27;
+
+       /**
+        * Add root path to all elements except Package Fragment Roots and Java
+        * projects. e.g. <code>java.lang.Vector - c:\java\lib\rt.jar</code>
+        * Option only applies to getElementLabel
+        */
+       public final static int PREPEND_ROOT_PATH = 1 << 28;
+
+       /**
+        * Package names are compressed. e.g. <code>o*.e*.search</code>
+        */
+       public final static int P_COMPRESSED = 1 << 29;
+
+       /**
+        * Post qualify referenced package fragement roots. For example
+        * <code>jdt.jar - net.sourceforge.phpdt.ui</code> if the jar is
+        * referenced from another project.
+        */
+       public final static int REFERENCED_ROOT_POST_QUALIFIED = 1 << 30;
+
+       /**
+        * Qualify all elements
+        */
+       public final static int ALL_FULLY_QUALIFIED = F_FULLY_QUALIFIED
+                       | M_FULLY_QUALIFIED | I_FULLY_QUALIFIED | T_FULLY_QUALIFIED
+                       | D_QUALIFIED | CF_QUALIFIED | CU_QUALIFIED | P_QUALIFIED
+                       | ROOT_QUALIFIED;
+
+       /**
+        * Post qualify all elements
+        */
+       public final static int ALL_POST_QUALIFIED = F_POST_QUALIFIED
+                       | M_POST_QUALIFIED | I_POST_QUALIFIED | T_POST_QUALIFIED
+                       | D_POST_QUALIFIED | CF_POST_QUALIFIED | CU_POST_QUALIFIED
+                       | P_POST_QUALIFIED | ROOT_POST_QUALIFIED;
+
+       /**
+        * Default options (M_PARAMETER_TYPES enabled)
+        */
+       public final static int ALL_DEFAULT = M_PARAMETER_TYPES;
+
+       /**
+        * Default qualify options (All except Root and Package)
+        */
+       public final static int DEFAULT_QUALIFIED = F_FULLY_QUALIFIED
+                       | M_FULLY_QUALIFIED | I_FULLY_QUALIFIED | T_FULLY_QUALIFIED
+                       | D_QUALIFIED | CF_QUALIFIED | CU_QUALIFIED;
+
+       /**
+        * Default post qualify options (All except Root and Package)
+        */
+       public final static int DEFAULT_POST_QUALIFIED = F_POST_QUALIFIED
+                       | M_POST_QUALIFIED | I_POST_QUALIFIED | T_POST_QUALIFIED
+                       | D_POST_QUALIFIED | CF_POST_QUALIFIED | CU_POST_QUALIFIED;
+
+       public final static String CONCAT_STRING = PHPUIMessages
+                       .getString("JavaElementLabels.concat_string"); // " - ";
+                                                                                                                       // //$NON-NLS-1$
+
+       public final static String COMMA_STRING = PHPUIMessages
+                       .getString("JavaElementLabels.comma_string"); // ", ";
+                                                                                                                       // //$NON-NLS-1$
+
+       public final static String DECL_STRING = PHPUIMessages
+                       .getString("JavaElementLabels.declseparator_string"); // " "; //
+                                                                                                                                       // use for
+                                                                                                                                       // return
+                                                                                                                                       // type
+                                                                                                                                       // //$NON-NLS-1$
+
+       /*
+        * Package name compression
+        */
+       private static String fgPkgNamePattern = ""; //$NON-NLS-1$
+
+       private static String fgPkgNamePrefix;
+
+       private static String fgPkgNamePostfix;
+
+       private static int fgPkgNameChars;
+
+       private static int fgPkgNameLength = -1;
+
+       private JavaElementLabels() {
+       }
+
+       private static boolean getFlag(int flags, int flag) {
+               return (flags & flag) != 0;
+       }
+
+       public static String getTextLabel(Object obj, int flags) {
+               if (obj instanceof IJavaElement) {
+                       return getElementLabel((IJavaElement) obj, flags);
+               } else if (obj instanceof IAdaptable) {
+                       IWorkbenchAdapter wbadapter = (IWorkbenchAdapter) ((IAdaptable) obj)
+                                       .getAdapter(IWorkbenchAdapter.class);
+                       if (wbadapter != null) {
+                               return wbadapter.getLabel(obj);
+                       }
+               }
+               return ""; //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the label for a Java element. Flags as defined above.
+        */
+       public static String getElementLabel(IJavaElement element, int flags) {
+               StringBuffer buf = new StringBuffer(60);
+               getElementLabel(element, flags, buf);
+               return buf.toString();
+       }
+
+       /**
+        * Returns the label for a Java element. Flags as defined above.
+        */
+       public static void getElementLabel(IJavaElement element, int flags,
+                       StringBuffer buf) {
+               int type = element.getElementType();
+               IPackageFragmentRoot root = null;
+
+               if (type != IJavaElement.JAVA_MODEL
+                               && type != IJavaElement.JAVA_PROJECT
+                               && type != IJavaElement.PACKAGE_FRAGMENT_ROOT)
+                       root = JavaModelUtil.getPackageFragmentRoot(element);
+               if (root != null && getFlag(flags, PREPEND_ROOT_PATH)) {
+                       getPackageFragmentRootLabel(root, ROOT_QUALIFIED, buf);
+                       buf.append(CONCAT_STRING);
+               }
+
+               switch (type) {
+               case IJavaElement.METHOD:
+                       getMethodLabel((IMethod) element, flags, buf);
+                       break;
+               case IJavaElement.FIELD:
+                       getFieldLabel((IField) element, flags, buf);
+                       break;
+               // case IJavaElement.INITIALIZER:
+               // getInitializerLabel((IInitializer) element, flags, buf);
+               // break;
+               case IJavaElement.TYPE:
+                       getTypeLabel((IType) element, flags, buf);
+                       break;
+               // case IJavaElement.CLASS_FILE:
+               // getClassFileLabel((IClassFile) element, flags, buf);
+               // break;
+               case IJavaElement.COMPILATION_UNIT:
+                       getCompilationUnitLabel((ICompilationUnit) element, flags, buf);
+                       break;
+               case IJavaElement.PACKAGE_FRAGMENT:
+                       getPackageFragmentLabel((IPackageFragment) element, flags, buf);
+                       break;
+               case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+                       getPackageFragmentRootLabel((IPackageFragmentRoot) element, flags,
+                                       buf);
+                       break;
+               case IJavaElement.IMPORT_CONTAINER:
+               case IJavaElement.IMPORT_DECLARATION:
+               case IJavaElement.PACKAGE_DECLARATION:
+                       getDeclararionLabel(element, flags, buf);
+                       break;
+               case IJavaElement.JAVA_PROJECT:
+               case IJavaElement.JAVA_MODEL:
+                       buf.append(element.getElementName());
+                       break;
+               default:
+                       buf.append(element.getElementName());
+               }
+
+               if (root != null && getFlag(flags, APPEND_ROOT_PATH)) {
+                       buf.append(CONCAT_STRING);
+                       getPackageFragmentRootLabel(root, ROOT_QUALIFIED, buf);
+               }
+       }
+
+       /**
+        * Appends the label for a method to a StringBuffer. Considers the M_*
+        * flags.
+        */
+       public static void getMethodLabel(IMethod method, int flags,
+                       StringBuffer buf) {
+               try {
+                       // return type
+                       if (getFlag(flags, M_PRE_RETURNTYPE) && method.exists()
+                                       && !method.isConstructor()) {
+                               buf.append(Signature.getSimpleName(Signature.toString(method
+                                               .getReturnType())));
+                               buf.append(' ');
+                       }
+
+                       // qualification
+                       if (getFlag(flags, M_FULLY_QUALIFIED)) {
+                               getTypeLabel(method.getDeclaringType(), T_FULLY_QUALIFIED
+                                               | (flags & P_COMPRESSED), buf);
+                               buf.append('.');
+                       }
+
+                       buf.append(method.getElementName());
+
+                       // parameters
+                       if (getFlag(flags, M_PARAMETER_TYPES | M_PARAMETER_NAMES)) {
+                               buf.append('(');
+
+                               String[] types = getFlag(flags, M_PARAMETER_TYPES) ? method
+                                               .getParameterTypes() : null;
+                               String[] names = (getFlag(flags, M_PARAMETER_NAMES) && method
+                                               .exists()) ? method.getParameterNames() : null;
+                               int nParams = types != null ? types.length : names.length;
+
+                               for (int i = 0; i < nParams; i++) {
+                                       if (i > 0) {
+                                               buf.append(COMMA_STRING); //$NON-NLS-1$
+                                       }
+                                       if (types != null) {
+                                               buf.append(Signature.getSimpleName(Signature
+                                                               .toString(types[i])));
+                                       }
+                                       if (names != null) {
+                                               if (types != null) {
+                                                       buf.append(' ');
+                                               }
+                                               buf.append(names[i]);
+                                       }
+                               }
+                               buf.append(')');
+                       }
+
+                       if (getFlag(flags, M_EXCEPTIONS) && method.exists()) {
+                               String[] types = method.getExceptionTypes();
+                               if (types.length > 0) {
+                                       buf.append(" throws "); //$NON-NLS-1$
+                                       for (int i = 0; i < types.length; i++) {
+                                               if (i > 0) {
+                                                       buf.append(COMMA_STRING);
+                                               }
+                                               buf.append(Signature.getSimpleName(Signature
+                                                               .toString(types[i])));
+                                       }
+                               }
+                       }
+
+                       if (getFlag(flags, M_APP_RETURNTYPE) && method.exists()
+                                       && !method.isConstructor()) {
+                               buf.append(DECL_STRING);
+                               buf.append(Signature.getSimpleName(Signature.toString(method
+                                               .getReturnType())));
+                       }
+
+                       // post qualification
+                       if (getFlag(flags, M_POST_QUALIFIED)) {
+                               buf.append(CONCAT_STRING);
+                               getTypeLabel(method.getDeclaringType(), T_FULLY_QUALIFIED
+                                               | (flags & P_COMPRESSED), buf);
+                       }
+
+               } catch (JavaModelException e) {
+                       PHPeclipsePlugin.log(e); // NotExistsException will not reach
+                                                                               // this point
+               }
+       }
+
+       /**
+        * Appends the label for a field to a StringBuffer. Considers the F_* flags.
+        */
+       public static void getFieldLabel(IField field, int flags, StringBuffer buf) {
+               try {
+                       if (getFlag(flags, F_PRE_TYPE_SIGNATURE) && field.exists()) {
+                               buf.append(Signature.toString(field.getTypeSignature()));
+                               buf.append(' ');
+                       }
+
+                       // qualification
+                       if (getFlag(flags, F_FULLY_QUALIFIED)) {
+                               getTypeLabel(field.getDeclaringType(), T_FULLY_QUALIFIED
+                                               | (flags & P_COMPRESSED), buf);
+                               buf.append('.');
+                       }
+                       buf.append(field.getElementName());
+
+                       if (getFlag(flags, F_APP_TYPE_SIGNATURE) && field.exists()) {
+                               buf.append(DECL_STRING);
+                               buf.append(Signature.toString(field.getTypeSignature()));
+                       }
+
+                       // post qualification
+                       if (getFlag(flags, F_POST_QUALIFIED)) {
+                               buf.append(CONCAT_STRING);
+                               getTypeLabel(field.getDeclaringType(), T_FULLY_QUALIFIED
+                                               | (flags & P_COMPRESSED), buf);
+                       }
+
+               } catch (JavaModelException e) {
+                       PHPeclipsePlugin.log(e); // NotExistsException will not reach
+                                                                               // this point
+               }
+       }
+
+       /**
+        * Appends the label for a initializer to a StringBuffer. Considers the I_*
+        * flags.
+        */
+       // public static void getInitializerLabel(IInitializer initializer, int
+       // flags, StringBuffer buf) {
+       // // qualification
+       // if (getFlag(flags, I_FULLY_QUALIFIED)) {
+       // getTypeLabel(initializer.getDeclaringType(), T_FULLY_QUALIFIED | (flags &
+       // P_COMPRESSED), buf);
+       // buf.append('.');
+       // }
+       // buf.append(JavaUIMessages.getString("JavaElementLabels.initializer"));
+       // //$NON-NLS-1$
+       //
+       // // post qualification
+       // if (getFlag(flags, I_POST_QUALIFIED)) {
+       // buf.append(CONCAT_STRING);
+       // getTypeLabel(initializer.getDeclaringType(), T_FULLY_QUALIFIED | (flags &
+       // P_COMPRESSED), buf);
+       // }
+       // }
+       /**
+        * Appends the label for a type to a StringBuffer. Considers the T_* flags.
+        */
+       public static void getTypeLabel(IType type, int flags, StringBuffer buf) {
+               if (getFlag(flags, T_FULLY_QUALIFIED)) {
+                       if (type != null) { // jsurfer INSERT
+                               IPackageFragment pack = type.getPackageFragment();
+                               if (!pack.isDefaultPackage()) {
+                                       getPackageFragmentLabel(pack, (flags & P_COMPRESSED), buf);
+                                       buf.append('.');
+                               }
+                               buf.append(JavaModelUtil.getTypeQualifiedName(type));
+                       } // jsurfer INSERT
+               } else if (getFlag(flags, T_CONTAINER_QUALIFIED)) {
+                       buf.append(JavaModelUtil.getTypeQualifiedName(type));
+               } else {
+                       buf.append(type.getElementName());
+               }
+               // post qualification
+               if (getFlag(flags, T_POST_QUALIFIED)) {
+                       buf.append(CONCAT_STRING);
+                       IType declaringType = type.getDeclaringType();
+                       if (declaringType != null) {
+                               getTypeLabel(declaringType, T_FULLY_QUALIFIED
+                                               | (flags & P_COMPRESSED), buf);
+                       } else {
+                               getPackageFragmentLabel(type.getPackageFragment(),
+                                               (flags & P_COMPRESSED), buf);
+                       }
+               }
+       }
+
+       /**
+        * Appends the label for a declaration to a StringBuffer. Considers the D_*
+        * flags.
+        */
+       public static void getDeclararionLabel(IJavaElement declaration, int flags,
+                       StringBuffer buf) {
+               if (getFlag(flags, D_QUALIFIED)) {
+                       IJavaElement openable = (IJavaElement) declaration.getOpenable();
+                       if (openable != null) {
+                               buf.append(getElementLabel(openable, CF_QUALIFIED
+                                               | CU_QUALIFIED));
+                               buf.append('/');
+                       }
+               }
+               if (declaration.getElementType() == IJavaElement.IMPORT_CONTAINER) {
+                       buf.append(PHPUIMessages
+                                       .getString("JavaElementLabels.import_container")); //$NON-NLS-1$
+               } else {
+                       buf.append(declaration.getElementName());
+               }
+               // post qualification
+               if (getFlag(flags, D_POST_QUALIFIED)) {
+                       IJavaElement openable = (IJavaElement) declaration.getOpenable();
+                       if (openable != null) {
+                               buf.append(CONCAT_STRING);
+                               buf.append(getElementLabel(openable, CF_QUALIFIED
+                                               | CU_QUALIFIED));
+                       }
+               }
+       }
+
+       /**
+        * Appends the label for a class file to a StringBuffer. Considers the CF_*
+        * flags.
+        */
+       // public static void getClassFileLabel(IClassFile classFile, int flags,
+       // StringBuffer buf) {
+       // if (getFlag(flags, CF_QUALIFIED)) {
+       // IPackageFragment pack= (IPackageFragment) classFile.getParent();
+       // if (!pack.isDefaultPackage()) {
+       // buf.append(pack.getElementName());
+       // buf.append('.');
+       // }
+       // }
+       // buf.append(classFile.getElementName());
+       //              
+       // if (getFlag(flags, CF_POST_QUALIFIED)) {
+       // buf.append(CONCAT_STRING);
+       // getPackageFragmentLabel((IPackageFragment) classFile.getParent(), 0,
+       // buf);
+       // }
+       // }
+       /**
+        * Appends the label for a compilation unit to a StringBuffer. Considers the
+        * CU_* flags.
+        */
+       public static void getCompilationUnitLabel(ICompilationUnit cu, int flags,
+                       StringBuffer buf) {
+               if (getFlag(flags, CU_QUALIFIED)) {
+                       IPackageFragment pack = (IPackageFragment) cu.getParent();
+                       if (!pack.isDefaultPackage()) {
+                               buf.append(pack.getElementName());
+                               buf.append('.');
+                       }
+               }
+               buf.append(cu.getElementName());
+
+               if (getFlag(flags, CU_POST_QUALIFIED)) {
+                       buf.append(CONCAT_STRING);
+                       getPackageFragmentLabel((IPackageFragment) cu.getParent(), 0, buf);
+               }
+       }
+
+       /**
+        * Appends the label for a package fragment to a StringBuffer. Considers the
+        * P_* flags.
+        */
+       public static void getPackageFragmentLabel(IPackageFragment pack,
+                       int flags, StringBuffer buf) {
+               if (getFlag(flags, P_QUALIFIED)) {
+                       getPackageFragmentRootLabel(
+                                       (IPackageFragmentRoot) pack.getParent(), ROOT_QUALIFIED,
+                                       buf);
+                       buf.append('/');
+               }
+               refreshPackageNamePattern();
+               if (pack.isDefaultPackage()) {
+                       buf.append(PHPUIMessages
+                                       .getString("JavaElementLabels.default_package")); //$NON-NLS-1$
+               } else if (getFlag(flags, P_COMPRESSED) && fgPkgNameLength >= 0) {
+                       String name = pack.getElementName();
+                       int start = 0;
+                       int dot = name.indexOf('.', start);
+                       while (dot > 0) {
+                               if (dot - start > fgPkgNameLength - 1) {
+                                       buf.append(fgPkgNamePrefix);
+                                       if (fgPkgNameChars > 0)
+                                               buf.append(name.substring(start, Math.min(start
+                                                               + fgPkgNameChars, dot)));
+                                       buf.append(fgPkgNamePostfix);
+                               } else
+                                       buf.append(name.substring(start, dot + 1));
+                               start = dot + 1;
+                               dot = name.indexOf('.', start);
+                       }
+                       buf.append(name.substring(start));
+               } else {
+                       buf.append(pack.getElementName());
+               }
+               if (getFlag(flags, P_POST_QUALIFIED)) {
+                       buf.append(CONCAT_STRING);
+                       getPackageFragmentRootLabel(
+                                       (IPackageFragmentRoot) pack.getParent(), ROOT_QUALIFIED,
+                                       buf);
+               }
+       }
+
+       /**
+        * Appends the label for a package fragment root to a StringBuffer.
+        * Considers the ROOT_* flags.
+        */
+       public static void getPackageFragmentRootLabel(IPackageFragmentRoot root,
+                       int flags, StringBuffer buf) {
+               if (root.isArchive())
+                       getArchiveLabel(root, flags, buf);
+               else
+                       getFolderLabel(root, flags, buf);
+       }
+
+       private static void getArchiveLabel(IPackageFragmentRoot root, int flags,
+                       StringBuffer buf) {
+               // Handle variables different
+               if (getFlag(flags, ROOT_VARIABLE) && getVariableLabel(root, flags, buf))
+                       return;
+               boolean external = root.isExternal();
+               if (external)
+                       getExternalArchiveLabel(root, flags, buf);
+               else
+                       getInternalArchiveLabel(root, flags, buf);
+       }
+
+       private static boolean getVariableLabel(IPackageFragmentRoot root,
+                       int flags, StringBuffer buf) {
+               // try {
+               // IClasspathEntry rawEntry= root.getRawClasspathEntry();
+               // if (rawEntry != null) {
+               // if (rawEntry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
+               // buf.append(rawEntry.getPath().makeRelative());
+               // buf.append(CONCAT_STRING);
+               // if (root.isExternal())
+               // buf.append(root.getPath().toOSString());
+               // else
+               // buf.append(root.getPath().makeRelative().toString());
+               // return true;
+               // }
+               // }
+               // } catch (JavaModelException e) {
+               // PHPeclipsePlugin.log(e); // problems with class path
+               // }
+               return false;
+       }
+
+       private static void getExternalArchiveLabel(IPackageFragmentRoot root,
+                       int flags, StringBuffer buf) {
+               IPath path = root.getPath();
+               if (getFlag(flags, REFERENCED_ROOT_POST_QUALIFIED)) {
+                       int segements = path.segmentCount();
+                       if (segements > 0) {
+                               buf.append(path.segment(segements - 1));
+                               if (segements > 1 || path.getDevice() != null) {
+                                       buf.append(CONCAT_STRING);
+                                       buf.append(path.removeLastSegments(1).toOSString());
+                               }
+                       } else {
+                               buf.append(path.toOSString());
+                       }
+               } else {
+                       buf.append(path.toOSString());
+               }
+       }
+
+       private static void getInternalArchiveLabel(IPackageFragmentRoot root,
+                       int flags, StringBuffer buf) {
+               IResource resource = root.getResource();
+               boolean rootQualified = getFlag(flags, ROOT_QUALIFIED);
+               boolean referencedQualified = getFlag(flags,
+                               REFERENCED_ROOT_POST_QUALIFIED)
+                               && JavaModelUtil.isReferenced(root) && resource != null;
+               if (rootQualified) {
+                       buf.append(root.getPath().makeRelative().toString());
+               } else {
+                       buf.append(root.getElementName());
+                       if (referencedQualified) {
+                               buf.append(CONCAT_STRING);
+                               buf.append(resource.getParent().getFullPath().makeRelative()
+                                               .toString());
+                       } else if (getFlag(flags, ROOT_POST_QUALIFIED)) {
+                               buf.append(CONCAT_STRING);
+                               buf
+                                               .append(root.getParent().getPath().makeRelative()
+                                                               .toString());
+                       }
+               }
+       }
+
+       private static void getFolderLabel(IPackageFragmentRoot root, int flags,
+                       StringBuffer buf) {
+               IResource resource = root.getResource();
+               boolean rootQualified = getFlag(flags, ROOT_QUALIFIED);
+               boolean referencedQualified = getFlag(flags,
+                               REFERENCED_ROOT_POST_QUALIFIED)
+                               && JavaModelUtil.isReferenced(root) && resource != null;
+               if (rootQualified) {
+                       buf.append(root.getPath().makeRelative().toString());
+               } else {
+                       if (resource != null)
+                               buf.append(resource.getProjectRelativePath().toString());
+                       else
+                               buf.append(root.getElementName());
+                       if (referencedQualified) {
+                               buf.append(CONCAT_STRING);
+                               buf.append(resource.getProject().getName());
+                       } else if (getFlag(flags, ROOT_POST_QUALIFIED)) {
+                               buf.append(CONCAT_STRING);
+                               buf.append(root.getParent().getElementName());
+                       }
+               }
+       }
+
+       private static void refreshPackageNamePattern() {
+               String pattern = getPkgNamePatternForPackagesView();
+               if (pattern.equals(fgPkgNamePattern))
+                       return;
+               else if (pattern.equals("")) { //$NON-NLS-1$
+                       fgPkgNamePattern = ""; //$NON-NLS-1$
+                       fgPkgNameLength = -1;
+                       return;
+               }
+               fgPkgNamePattern = pattern;
+               int i = 0;
+               fgPkgNameChars = 0;
+               fgPkgNamePrefix = ""; //$NON-NLS-1$
+               fgPkgNamePostfix = ""; //$NON-NLS-1$
+               while (i < pattern.length()) {
+                       char ch = pattern.charAt(i);
+                       if (Character.isDigit(ch)) {
+                               fgPkgNameChars = ch - 48;
+                               if (i > 0)
+                                       fgPkgNamePrefix = pattern.substring(0, i);
+                               if (i >= 0)
+                                       fgPkgNamePostfix = pattern.substring(i + 1);
+                               fgPkgNameLength = fgPkgNamePrefix.length() + fgPkgNameChars
+                                               + fgPkgNamePostfix.length();
+                               return;
+                       }
+                       i++;
+               }
+               fgPkgNamePrefix = pattern;
+               fgPkgNameLength = pattern.length();
+       }
+
+       private static String getPkgNamePatternForPackagesView() {
+               IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+               if (!store
+                               .getBoolean(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES))
+                       return ""; //$NON-NLS-1$
+               return store
+                               .getString(PreferenceConstants.APPEARANCE_PKG_NAME_PATTERN_FOR_PKG_VIEW);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaUILabelProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/JavaUILabelProvider.java
new file mode 100644 (file)
index 0000000..abe10ec
--- /dev/null
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+public class JavaUILabelProvider extends LabelProvider {
+
+       protected JavaElementImageProvider fImageLabelProvider;
+
+       protected StorageLabelProvider fStorageLabelProvider;
+
+       protected ArrayList fLabelDecorators;
+
+       private int fImageFlags;
+
+       private int fTextFlags;
+
+       /**
+        * Creates a new label provider with default flags.
+        */
+       public JavaUILabelProvider() {
+               this(JavaElementLabels.M_PARAMETER_TYPES,
+                               JavaElementImageProvider.OVERLAY_ICONS);
+       }
+
+       /**
+        * @param textFlags
+        *            Flags defined in <code>JavaElementLabels</code>.
+        * @param imageFlags
+        *            Flags defined in <code>JavaElementImageProvider</code>.
+        */
+       public JavaUILabelProvider(int textFlags, int imageFlags) {
+               fImageLabelProvider = new JavaElementImageProvider();
+               fLabelDecorators = null;
+
+               fStorageLabelProvider = new StorageLabelProvider();
+               fImageFlags = imageFlags;
+               fTextFlags = textFlags;
+       }
+
+       /**
+        * Adds a decorator to the label provider
+        */
+       public void addLabelDecorator(ILabelDecorator decorator) {
+               if (fLabelDecorators == null) {
+                       fLabelDecorators = new ArrayList(2);
+               }
+               fLabelDecorators.add(decorator);
+       }
+
+       /**
+        * Sets the textFlags.
+        * 
+        * @param textFlags
+        *            The textFlags to set
+        */
+       public final void setTextFlags(int textFlags) {
+               fTextFlags = textFlags;
+       }
+
+       /**
+        * Sets the imageFlags
+        * 
+        * @param imageFlags
+        *            The imageFlags to set
+        */
+       public final void setImageFlags(int imageFlags) {
+               fImageFlags = imageFlags;
+       }
+
+       /**
+        * Gets the image flags. Can be overwriten by super classes.
+        * 
+        * @return Returns a int
+        */
+       public final int getImageFlags() {
+               return fImageFlags;
+       }
+
+       /**
+        * Gets the text flags.
+        * 
+        * @return Returns a int
+        */
+       public final int getTextFlags() {
+               return fTextFlags;
+       }
+
+       /**
+        * Evaluates the image flags for a element. Can be overwriten by super
+        * classes.
+        * 
+        * @return Returns a int
+        */
+       protected int evaluateImageFlags(Object element) {
+               return getImageFlags();
+       }
+
+       /**
+        * Evaluates the text flags for a element. Can be overwriten by super
+        * classes.
+        * 
+        * @return Returns a int
+        */
+       protected int evaluateTextFlags(Object element) {
+               return getTextFlags();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see ILabelProvider#getImage
+        */
+       public Image getImage(Object element) {
+               Image result = fImageLabelProvider.getImageLabel(element,
+                               evaluateImageFlags(element));
+               if (result == null && (element instanceof IStorage)) {
+                       result = fStorageLabelProvider.getImage(element);
+               }
+               if (fLabelDecorators != null && result != null) {
+                       for (int i = 0; i < fLabelDecorators.size(); i++) {
+                               ILabelDecorator decorator = (ILabelDecorator) fLabelDecorators
+                                               .get(i);
+                               result = decorator.decorateImage(result, element);
+                       }
+               }
+               return result;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see ILabelProvider#getText
+        */
+       public String getText(Object element) {
+               String result = JavaElementLabels.getTextLabel(element,
+                               evaluateTextFlags(element));
+               if (result.length() == 0 && (element instanceof IStorage)) {
+                       result = fStorageLabelProvider.getText(element);
+               }
+               if (fLabelDecorators != null && result.length() > 0) {
+                       for (int i = 0; i < fLabelDecorators.size(); i++) {
+                               ILabelDecorator decorator = (ILabelDecorator) fLabelDecorators
+                                               .get(i);
+                               result = decorator.decorateText(result, element);
+                       }
+               }
+               return result;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IBaseLabelProvider#dispose
+        */
+       public void dispose() {
+               if (fLabelDecorators != null) {
+                       for (int i = 0; i < fLabelDecorators.size(); i++) {
+                               ILabelDecorator decorator = (ILabelDecorator) fLabelDecorators
+                                               .get(i);
+                               decorator.dispose();
+                       }
+                       fLabelDecorators = null;
+               }
+               fStorageLabelProvider.dispose();
+               fImageLabelProvider.dispose();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IBaseLabelProvider#addListener(ILabelProviderListener)
+        */
+       public void addListener(ILabelProviderListener listener) {
+               if (fLabelDecorators != null) {
+                       for (int i = 0; i < fLabelDecorators.size(); i++) {
+                               ILabelDecorator decorator = (ILabelDecorator) fLabelDecorators
+                                               .get(i);
+                               decorator.addListener(listener);
+                       }
+               }
+               super.addListener(listener);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IBaseLabelProvider#isLabelProperty(Object, String)
+        */
+       public boolean isLabelProperty(Object element, String property) {
+               return true;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IBaseLabelProvider#removeListener(ILabelProviderListener)
+        */
+       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);
+                       }
+               }
+               super.removeListener(listener);
+       }
+
+       public static ILabelDecorator[] getDecorators(boolean errortick,
+                       ILabelDecorator extra) {
+               if (errortick) {
+                       if (extra == null) {
+                               return new ILabelDecorator[] {};
+                       } else {
+                               return new ILabelDecorator[] { extra };
+                       }
+               }
+               if (extra != null) {
+                       return new ILabelDecorator[] { extra };
+               }
+               return null;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ListContentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ListContentProvider.java
new file mode 100644 (file)
index 0000000..e520f4f
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * A specialized content provider to show a list of editor parts.
+ */
+public class ListContentProvider implements IStructuredContentProvider {
+       List fContents;
+
+       public ListContentProvider() {
+       }
+
+       public Object[] getElements(Object input) {
+               if (fContents != null && fContents == input)
+                       return fContents.toArray();
+               return new Object[0];
+       }
+
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               if (newInput instanceof List)
+                       fContents = (List) newInput;
+               else
+                       fContents = null;
+               // we use a fixed set.
+       }
+
+       public void dispose() {
+       }
+
+       public boolean isDeleted(Object o) {
+               return fContents != null && !fContents.contains(o);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilter.java
new file mode 100644 (file)
index 0000000..5b5bf44
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IField;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filter for the methods viewer. Changing a filter property does not trigger a
+ * refiltering of the viewer
+ */
+public class MemberFilter extends ViewerFilter {
+
+       public static final int FILTER_NONPUBLIC = 1;
+
+       public static final int FILTER_STATIC = 2;
+
+       public static final int FILTER_FIELDS = 4;
+
+       private int fFilterProperties;
+
+       /**
+        * Modifies filter and add a property to filter for
+        */
+       public final void addFilter(int filter) {
+               fFilterProperties |= filter;
+       }
+
+       /**
+        * Modifies filter and remove a property to filter for
+        */
+       public final void removeFilter(int filter) {
+               fFilterProperties &= (-1 ^ filter);
+       }
+
+       /**
+        * Tests if a property is filtered
+        */
+       public final boolean hasFilter(int filter) {
+               return (fFilterProperties & filter) != 0;
+       }
+
+       /*
+        * @see ViewerFilter@isFilterProperty
+        */
+       public boolean isFilterProperty(Object element, Object property) {
+               return false;
+       }
+
+       /*
+        * @see ViewerFilter@select
+        */
+       public boolean select(Viewer viewer, Object parentElement, Object element) {
+               try {
+                       if (hasFilter(FILTER_FIELDS) && element instanceof IField) {
+                               return false;
+                       }
+                       if (element instanceof IMember) {
+                               IMember member = (IMember) element;
+                               if (member.getElementName().startsWith("<")) { // filter out
+                                                                                                                               // <clinit>
+                                                                                                                               // //$NON-NLS-1$
+                                       return false;
+                               }
+                               int flags = member.getFlags();
+                               if (hasFilter(FILTER_STATIC)
+                                               && (Flags.isStatic(flags) || isFieldInInterface(member))
+                                               && member.getElementType() != IJavaElement.TYPE) {
+                                       return false;
+                               }
+                               if (hasFilter(FILTER_NONPUBLIC) && !Flags.isPublic(flags)
+                                               && !isMemberInInterface(member)
+                                               && !isTopLevelType(member)) {
+                                       return false;
+                               }
+                       }
+               } catch (JavaModelException e) {
+                       // ignore
+               }
+               return true;
+       }
+
+       private boolean isMemberInInterface(IMember member)
+                       throws JavaModelException {
+               IType parent = member.getDeclaringType();
+               return parent != null && parent.isInterface();
+       }
+
+       private boolean isFieldInInterface(IMember member)
+                       throws JavaModelException {
+               return (member.getElementType() == IJavaElement.FIELD)
+                               && member.getDeclaringType().isInterface();
+       }
+
+       private boolean isTopLevelType(IMember member) throws JavaModelException {
+               IType parent = member.getDeclaringType();
+               return parent == null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilterAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/MemberFilterAction.java
new file mode 100644 (file)
index 0000000..634678f
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import net.sourceforge.phpdt.ui.actions.MemberFilterActionGroup;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Action used to enable / disable method filter properties
+ */
+public class MemberFilterAction extends Action {
+
+       private int fFilterProperty;
+
+       private MemberFilterActionGroup fFilterActionGroup;
+
+       public MemberFilterAction(MemberFilterActionGroup actionGroup,
+                       String title, int property, String contextHelpId, boolean initValue) {
+               super(title);
+               fFilterActionGroup = actionGroup;
+               fFilterProperty = property;
+
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(this, contextHelpId);
+
+               setChecked(initValue);
+       }
+
+       /**
+        * Returns this action's filter property.
+        */
+       public int getFilterProperty() {
+               return fFilterProperty;
+       }
+
+       /*
+        * @see Action#actionPerformed
+        */
+       public void run() {
+               fFilterActionGroup.setMemberFilter(fFilterProperty, isChecked());
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemMarkerManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemMarkerManager.java
new file mode 100644 (file)
index 0000000..129837b
--- /dev/null
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.HashSet;
+
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.CompilationUnitAnnotationModelEvent;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+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.runtime.CoreException;
+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.jface.util.ListenerList;
+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.
+ */
+public class ProblemMarkerManager implements IResourceChangeListener,
+               IAnnotationModelListener, IAnnotationModelListenerExtension {
+
+       /**
+        * Visitors used to look if the element change delta containes a marker
+        * change.
+        */
+       private static class ProjectErrorVisitor implements IResourceDeltaVisitor {
+
+               private HashSet fChangedElements;
+
+               public ProjectErrorVisitor(HashSet changedElements) {
+                       fChangedElements = changedElements;
+               }
+
+               public boolean visit(IResourceDelta delta) throws CoreException {
+                       IResource res = delta.getResource();
+                       if (res instanceof IProject
+                                       && delta.getKind() == IResourceDelta.CHANGED) {
+                               try {
+                                       IProject project = (IProject) res;
+                                       if (!project.isAccessible()
+                                                       || !project
+                                                                       .hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
+                                               // only track open Java projects
+                                               return false;
+                                       }
+                               } catch (CoreException e) {
+                                       PHPeclipsePlugin.log(e);
+                                       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(10);
+       }
+
+       /*
+        * @see IResourceChangeListener#resourceChanged
+        */
+       public void resourceChanged(IResourceChangeEvent event) {
+               HashSet changedElements = new HashSet();
+
+               try {
+                       IResourceDelta delta = event.getDelta();
+                       if (delta != null)
+                               delta.accept(new ProjectErrorVisitor(changedElements));
+               } catch (CoreException e) {
+                       PHPeclipsePlugin.log(e.getStatus());
+               }
+
+               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) {
+               if (event instanceof CompilationUnitAnnotationModelEvent) {
+                       CompilationUnitAnnotationModelEvent cuEvent = (CompilationUnitAnnotationModelEvent) event;
+                       if (cuEvent.includesProblemMarkerAnnotationChanges()) {
+                               IResource[] changes = new IResource[] { cuEvent
+                                               .getUnderlyingResource() };
+                               fireChanges(changes, false);
+                       }
+               }
+       }
+
+       /**
+        * Adds a listener for problem marker changes.
+        */
+       public void addListener(IProblemChangedListener listener) {
+               if (fListeners.isEmpty()) {
+                       PHPeclipsePlugin.getWorkspace().addResourceChangeListener(this);
+                       WebUI.getDefault().getCompilationUnitDocumentProvider()
+                                       .addGlobalAnnotationModelListener(this);
+               }
+               fListeners.add(listener);
+       }
+
+       /**
+        * Removes a <code>IProblemChangedListener</code>.
+        */
+       public void removeListener(IProblemChangedListener listener) {
+               fListeners.remove(listener);
+               if (fListeners.isEmpty()) {
+                       PHPeclipsePlugin.getWorkspace().removeResourceChangeListener(this);
+                       WebUI.getDefault().getCompilationUnitDocumentProvider()
+                                       .removeGlobalAnnotationModelListener(this);
+               }
+       }
+
+       private void fireChanges(final IResource[] changes,
+                       final boolean isMarkerChange) {
+               Display display = SWTUtil.getStandardDisplay();
+               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/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemTableViewer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemTableViewer.java
new file mode 100644 (file)
index 0000000..6bc9ca3
--- /dev/null
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.ui.IWorkingCopyProvider;
+import net.sourceforge.phpdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Extends a TableViewer to allow more performance when showing error ticks. A
+ * <code>ProblemItemMapper</code> is contained that maps all items in the tree
+ * to underlying resource
+ */
+public class ProblemTableViewer extends TableViewer {
+
+       protected ResourceToItemsMapper fResourceToItemsMapper;
+
+       /**
+        * Constructor for ProblemTableViewer.
+        * 
+        * @param parent
+        */
+       public ProblemTableViewer(Composite parent) {
+               super(parent);
+               initMapper();
+       }
+
+       /**
+        * Constructor for ProblemTableViewer.
+        * 
+        * @param parent
+        * @param style
+        */
+       public ProblemTableViewer(Composite parent, int style) {
+               super(parent, style);
+               initMapper();
+       }
+
+       /**
+        * Constructor for ProblemTableViewer.
+        * 
+        * @param table
+        */
+       public ProblemTableViewer(Table table) {
+               super(table);
+               initMapper();
+       }
+
+       private void initMapper() {
+               fResourceToItemsMapper = new ResourceToItemsMapper(this);
+       }
+
+       /*
+        * @see StructuredViewer#mapElement(Object, Widget)
+        */
+       protected void mapElement(Object element, Widget item) {
+               super.mapElement(element, item);
+               if (item instanceof Item) {
+                       fResourceToItemsMapper.addToMap(element, (Item) item);
+               }
+       }
+
+       /*
+        * @see StructuredViewer#unmapElement(Object, Widget)
+        */
+       protected void unmapElement(Object element, Widget item) {
+               if (item instanceof Item) {
+                       fResourceToItemsMapper.removeFromMap(element, (Item) item);
+               }
+               super.unmapElement(element, item);
+       }
+
+       /*
+        * @see StructuredViewer#unmapAllElements()
+        */
+       protected void unmapAllElements() {
+               fResourceToItemsMapper.clearMap();
+               super.unmapAllElements();
+       }
+
+       /*
+        * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent)
+        */
+       protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
+               if (event instanceof ProblemsLabelChangedEvent) {
+                       ProblemsLabelChangedEvent e = (ProblemsLabelChangedEvent) event;
+                       if (!e.isMarkerChange() && canIgnoreChangesFromAnnotionModel()) {
+                               return;
+                       }
+               }
+
+               Object[] changed = event.getElements();
+               if (changed != null && !fResourceToItemsMapper.isEmpty()) {
+                       ArrayList others = new ArrayList(changed.length);
+                       for (int i = 0; i < changed.length; i++) {
+                               Object curr = changed[i];
+                               if (curr instanceof IResource) {
+                                       fResourceToItemsMapper.resourceChanged((IResource) curr);
+                               } else {
+                                       others.add(curr);
+                               }
+                       }
+                       if (others.isEmpty()) {
+                               return;
+                       }
+                       event = new LabelProviderChangedEvent((IBaseLabelProvider) event
+                                       .getSource(), others.toArray());
+               }
+               super.handleLabelProviderChanged(event);
+       }
+
+       /**
+        * Answers whether this viewer can ignore label provider changes resulting
+        * from marker changes in annotation models
+        */
+       private boolean canIgnoreChangesFromAnnotionModel() {
+               Object contentProvider = getContentProvider();
+               return contentProvider instanceof IWorkingCopyProvider
+                               && !((IWorkingCopyProvider) contentProvider)
+                                               .providesWorkingCopies();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemTreeViewer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ProblemTreeViewer.java
new file mode 100644 (file)
index 0000000..ba501eb
--- /dev/null
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.ui.IWorkingCopyProvider;
+import net.sourceforge.phpdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Extends a TreeViewer to allow more performance when showing error ticks. A
+ * <code>ProblemItemMapper</code> is contained that maps all items in the tree
+ * to underlying resource
+ */
+public class ProblemTreeViewer extends TreeViewer {
+
+       protected ResourceToItemsMapper fResourceToItemsMapper;
+
+       /*
+        * @see TreeViewer#TreeViewer(Composite)
+        */
+       public ProblemTreeViewer(Composite parent) {
+               super(parent);
+               initMapper();
+       }
+
+       /*
+        * @see TreeViewer#TreeViewer(Composite, int)
+        */
+       public ProblemTreeViewer(Composite parent, int style) {
+               super(parent, style);
+               initMapper();
+       }
+
+       /*
+        * @see TreeViewer#TreeViewer(Tree)
+        */
+       public ProblemTreeViewer(Tree tree) {
+               super(tree);
+               initMapper();
+       }
+
+       private void initMapper() {
+               fResourceToItemsMapper = new ResourceToItemsMapper(this);
+       }
+
+       /*
+        * @see StructuredViewer#mapElement(Object, Widget)
+        */
+       protected void mapElement(Object element, Widget item) {
+               super.mapElement(element, item);
+               if (item instanceof Item) {
+                       fResourceToItemsMapper.addToMap(element, (Item) item);
+               }
+       }
+
+       /*
+        * @see StructuredViewer#unmapElement(Object, Widget)
+        */
+       protected void unmapElement(Object element, Widget item) {
+               if (item instanceof Item) {
+                       fResourceToItemsMapper.removeFromMap(element, (Item) item);
+               }
+               super.unmapElement(element, item);
+       }
+
+       /*
+        * @see StructuredViewer#unmapAllElements()
+        */
+       protected void unmapAllElements() {
+               fResourceToItemsMapper.clearMap();
+               super.unmapAllElements();
+       }
+
+       /*
+        * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent)
+        */
+       protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
+               if (event instanceof ProblemsLabelChangedEvent) {
+                       ProblemsLabelChangedEvent e = (ProblemsLabelChangedEvent) event;
+                       if (!e.isMarkerChange() && canIgnoreChangesFromAnnotionModel()) {
+                               return;
+                       }
+               }
+
+               Object[] changed = event.getElements();
+               if (changed != null && !fResourceToItemsMapper.isEmpty()) {
+                       ArrayList others = new ArrayList();
+                       for (int i = 0; i < changed.length; i++) {
+                               Object curr = changed[i];
+                               if (curr instanceof IResource) {
+                                       fResourceToItemsMapper.resourceChanged((IResource) curr);
+                               } else {
+                                       others.add(curr);
+                               }
+                       }
+                       if (others.isEmpty()) {
+                               return;
+                       }
+                       event = new LabelProviderChangedEvent((IBaseLabelProvider) event
+                                       .getSource(), others.toArray());
+               }
+               super.handleLabelProviderChanged(event);
+       }
+
+       /**
+        * Answers whether this viewer can ignore label provider changes resulting
+        * from marker changes in annotation models
+        */
+       private boolean canIgnoreChangesFromAnnotionModel() {
+               Object contentProvider = getContentProvider();
+               return contentProvider instanceof IWorkingCopyProvider
+                               && !((IWorkingCopyProvider) contentProvider)
+                                               .providesWorkingCopies();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object)
+        */
+       public boolean isExpandable(Object element) {
+               // workaround for 65762
+               if (hasFilters() && element instanceof IMember) {
+                       return getFilteredChildren(element).length > 0;
+               }
+               return super.isExpandable(element);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ResourceToItemsMapper.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/ResourceToItemsMapper.java
new file mode 100644 (file)
index 0000000..dba7cae
--- /dev/null
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Stack;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.ContentViewer;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IViewerLabelProvider;
+import org.eclipse.jface.viewers.ViewerLabel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Item;
+
+/**
+ * Helper class for updating error markers and other decorators that work on
+ * resources. Items are mapped to their element's underlying resource. Method
+ * <code>resourceChanged</code> updates all items that are affected from the
+ * changed elements.
+ */
+public class ResourceToItemsMapper {
+
+       private static final int NUMBER_LIST_REUSE = 10;
+
+       // map from resource to item
+       private HashMap fResourceToItem;
+
+       private Stack fReuseLists;
+
+       private ContentViewer fContentViewer;
+
+       public ResourceToItemsMapper(ContentViewer viewer) {
+               fResourceToItem = new HashMap();
+               fReuseLists = new Stack();
+
+               fContentViewer = viewer;
+       }
+
+       /**
+        * Must be called from the UI thread.
+        */
+       public void resourceChanged(IResource changedResource) {
+               Object obj = fResourceToItem.get(changedResource);
+               if (obj == null) {
+                       // not mapped
+               } else if (obj instanceof Item) {
+                       updateItem((Item) obj);
+               } else { // List of Items
+                       List list = (List) obj;
+                       for (int k = 0; k < list.size(); k++) {
+                               updateItem((Item) list.get(k));
+                       }
+               }
+       }
+
+       private void updateItem(Item item) {
+               if (!item.isDisposed()) { // defensive code
+                       ILabelProvider lprovider = (ILabelProvider) fContentViewer
+                                       .getLabelProvider();
+
+                       Object data = item.getData();
+
+                       // If it is an IItemLabelProvider than short circuit: patch Tod (bug
+                       // 55012)
+                       if (lprovider instanceof IViewerLabelProvider) {
+                               IViewerLabelProvider provider = (IViewerLabelProvider) lprovider;
+
+                               ViewerLabel updateLabel = new ViewerLabel(item.getText(), item
+                                               .getImage());
+                               provider.updateLabel(updateLabel, data);
+
+                               if (updateLabel.hasNewImage()) {
+                                       item.setImage(updateLabel.getImage());
+                               }
+                               if (updateLabel.hasNewText()) {
+                                       item.setText(updateLabel.getText());
+                               }
+                       } else {
+                               Image oldImage = item.getImage();
+                               Image image = lprovider.getImage(data);
+                               if (image != null && !image.equals(oldImage)) {
+                                       item.setImage(image);
+                               }
+                               String oldText = item.getText();
+                               String text = lprovider.getText(data);
+                               if (text != null && !text.equals(oldText)) {
+                                       item.setText(text);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Adds a new item to the map.
+        * 
+        * @param element
+        *            Element to map
+        * @param item
+        *            The item used for the element
+        */
+       public void addToMap(Object element, Item item) {
+               IResource resource = getCorrespondingResource(element);
+               if (resource != null) {
+                       Object existingMapping = fResourceToItem.get(resource);
+                       if (existingMapping == null) {
+                               fResourceToItem.put(resource, item);
+                       } else if (existingMapping instanceof Item) {
+                               if (existingMapping != item) {
+                                       List list = getNewList();
+                                       list.add(existingMapping);
+                                       list.add(item);
+                                       fResourceToItem.put(resource, list);
+                               }
+                       } else { // List
+                               List list = (List) existingMapping;
+                               if (!list.contains(item)) {
+                                       list.add(item);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Removes an element from the map.
+        */
+       public void removeFromMap(Object element, Item item) {
+               IResource resource = getCorrespondingResource(element);
+               if (resource != null) {
+                       Object existingMapping = fResourceToItem.get(resource);
+                       if (existingMapping == null) {
+                               return;
+                       } else if (existingMapping instanceof Item) {
+                               fResourceToItem.remove(resource);
+                       } else { // List
+                               List list = (List) existingMapping;
+                               list.remove(item);
+                               if (list.isEmpty()) {
+                                       fResourceToItem.remove(list);
+                                       releaseList(list);
+                               }
+                       }
+               }
+       }
+
+       private List getNewList() {
+               if (!fReuseLists.isEmpty()) {
+                       return (List) fReuseLists.pop();
+               }
+               return new ArrayList(2);
+       }
+
+       private void releaseList(List list) {
+               if (fReuseLists.size() < NUMBER_LIST_REUSE) {
+                       fReuseLists.push(list);
+               }
+       }
+
+       /**
+        * Clears the map.
+        */
+       public void clearMap() {
+               fResourceToItem.clear();
+       }
+
+       /**
+        * Tests if the map is empty
+        */
+       public boolean isEmpty() {
+               return fResourceToItem.isEmpty();
+       }
+
+       /**
+        * Method that decides which elements can have error markers Returns null if
+        * an element can not have error markers.
+        */
+       private static IResource getCorrespondingResource(Object element) {
+               if (element instanceof IJavaElement) {
+                       IJavaElement elem = (IJavaElement) element;
+                       if (!elem.isReadOnly()) { // only modifieable elements can get
+                                                                               // error ticks
+                               IResource res = elem.getResource();
+                               if (res == null) {
+                                       ICompilationUnit cu = (ICompilationUnit) elem
+                                                       .getAncestor(IJavaElement.COMPILATION_UNIT);
+                                       if (cu != null) {
+                                               // elements in compilation units are mapped to the
+                                               // underlying resource of the original cu
+                                               res = cu.getResource();
+                                       }
+                               }
+                               return res;
+                       }
+                       return null;
+               } else if (element instanceof IResource) {
+                       return (IResource) element;
+               }
+               return null;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java
new file mode 100644 (file)
index 0000000..682852d
--- /dev/null
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+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.texteditor.ITextEditor;
+
+/**
+ * Infrastructure to share an AST for editor post selection listeners.
+ */
+public class SelectionListenerWithASTManager {
+
+       private static SelectionListenerWithASTManager fgDefault;
+
+       /**
+        * @return Returns the default manager instance.
+        */
+       public static SelectionListenerWithASTManager getDefault() {
+               if (fgDefault == null) {
+                       fgDefault = new SelectionListenerWithASTManager();
+               }
+               return fgDefault;
+       }
+
+       private final static class PartListenerGroup {
+               private ITextEditor fPart;
+
+               private ISelectionChangedListener fSelectionListener,
+                               fPostSelectionListener;
+
+               private Job fCurrentJob;
+
+               private ListenerList fAstListeners;
+
+               /**
+                * Lock to avoid having more than one calculateAndInform job in
+                * parallel. Only jobs may synchronize on this as otherwise deadlocks
+                * are possible.
+                */
+               private final Object fJobLock = new Object();
+
+               public PartListenerGroup(ITextEditor part) {
+                       fPart = part;
+                       fCurrentJob = null;
+                       fAstListeners = new ListenerList();
+
+                       fSelectionListener = new ISelectionChangedListener() {
+                               public void selectionChanged(SelectionChangedEvent event) {
+                                       ISelection selection = event.getSelection();
+                                       if (selection instanceof ITextSelection) {
+                                               fireSelectionChanged((ITextSelection) selection);
+                                       }
+                               }
+                       };
+
+                       fPostSelectionListener = new ISelectionChangedListener() {
+                               public void selectionChanged(SelectionChangedEvent event) {
+                                       ISelection selection = event.getSelection();
+                                       if (selection instanceof ITextSelection) {
+                                               firePostSelectionChanged((ITextSelection) selection);
+                                       }
+                               }
+                       };
+               }
+
+               public boolean isEmpty() {
+                       return fAstListeners.isEmpty();
+               }
+
+               public void install(ISelectionListenerWithAST listener) {
+                       if (isEmpty()) {
+                               ISelectionProvider selectionProvider = fPart
+                                               .getSelectionProvider();
+                               if (selectionProvider instanceof IPostSelectionProvider) {
+                                       ((IPostSelectionProvider) selectionProvider)
+                                                       .addPostSelectionChangedListener(fPostSelectionListener);
+                                       selectionProvider
+                                                       .addSelectionChangedListener(fSelectionListener);
+                               }
+                       }
+                       fAstListeners.add(listener);
+               }
+
+               public void uninstall(ISelectionListenerWithAST listener) {
+                       fAstListeners.remove(listener);
+                       if (isEmpty()) {
+                               ISelectionProvider selectionProvider = fPart
+                                               .getSelectionProvider();
+                               if (selectionProvider instanceof IPostSelectionProvider) {
+                                       ((IPostSelectionProvider) selectionProvider)
+                                                       .removePostSelectionChangedListener(fPostSelectionListener);
+                                       selectionProvider
+                                                       .removeSelectionChangedListener(fSelectionListener);
+                               }
+                       }
+               }
+
+               public void fireSelectionChanged(final ITextSelection selection) {
+                       if (fCurrentJob != null) {
+                               fCurrentJob.cancel();
+                       }
+               }
+
+               public void firePostSelectionChanged(final ITextSelection selection) {
+                       if (fCurrentJob != null) {
+                               fCurrentJob.cancel();
+                       }
+
+                       fCurrentJob = new Job("SelectionListenerWithASTManager Job") {// JavaUIMessages.SelectionListenerWithASTManager_job_title)
+                                                                                                                                                       // {
+                               public IStatus run(IProgressMonitor monitor) {
+                                       if (monitor == null) {
+                                               monitor = new NullProgressMonitor();
+                                       }
+                                       synchronized (fJobLock) {
+                                               return calculateASTandInform(/*input,*/ selection, monitor);
+                                       }
+                               }
+                       };
+                       fCurrentJob.setPriority(Job.DECORATE);
+                       fCurrentJob.setSystem(true);
+                       fCurrentJob.schedule();
+               }
+
+               protected IStatus calculateASTandInform(/*IJavaElement input,*/
+                               ITextSelection selection, IProgressMonitor monitor) {
+                       if (monitor.isCanceled()) {
+                               return Status.CANCEL_STATUS;
+                       }
+                       // create AST
+                       try {
+                               // CompilationUnit astRoot=
+                               // PHPeclipsePlugin.getDefault().getASTProvider().getAST(input,
+                               // ASTProvider.WAIT_ACTIVE_ONLY, monitor);
+
+                               // if (astRoot != null && !monitor.isCanceled()) {
+                               Object[] listeners;
+                               synchronized (PartListenerGroup.this) {
+                                       listeners = fAstListeners.getListeners();
+                               }
+                               for (int i = 0; i < listeners.length; i++) {
+                                       ((ISelectionListenerWithAST) listeners[i])
+                                                       .selectionChanged(fPart, selection);// , astRoot);
+                                       if (monitor.isCanceled()) {
+                                               return Status.CANCEL_STATUS;
+                                       }
+                               }
+                               return Status.OK_STATUS;
+                               // }
+                       } catch (OperationCanceledException e) {
+                               // thrown when cancelling the AST creation
+                       }
+                       return Status.CANCEL_STATUS;
+               }
+       }
+
+       private Map fListenerGroups;
+
+       private SelectionListenerWithASTManager() {
+               fListenerGroups = new HashMap();
+       }
+
+       /**
+        * Registers a selection listener for the given editor part.
+        * 
+        * @param part
+        *            The editor part to listen to.
+        * @param listener
+        *            The listener to register.
+        */
+       public void addListener(ITextEditor part, ISelectionListenerWithAST listener) {
+               synchronized (this) {
+                       PartListenerGroup partListener = (PartListenerGroup) fListenerGroups
+                                       .get(part);
+                       if (partListener == null) {
+                               partListener = new PartListenerGroup(part);
+                               fListenerGroups.put(part, partListener);
+                       }
+                       partListener.install(listener);
+               }
+       }
+
+       /**
+        * Unregisters a selection listener.
+        * 
+        * @param part
+        *            The editor part the listener was registered.
+        * @param listener
+        *            The listener to unregister.
+        */
+       public void removeListener(ITextEditor part,
+                       ISelectionListenerWithAST listener) {
+               synchronized (this) {
+                       PartListenerGroup partListener = (PartListenerGroup) fListenerGroups
+                                       .get(part);
+                       if (partListener != null) {
+                               partListener.uninstall(listener);
+                               if (partListener.isEmpty()) {
+                                       fListenerGroups.remove(part);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Forces a selection changed event that is sent to all listeners registered
+        * to the given editor part. The event is sent from a background thread:
+        * this method call can return before the listeners are informed.
+        * 
+        * @param part
+        *            The editor part that has a changed selection
+        * @param selection
+        *            The new text selection
+        */
+       public void forceSelectionChange(ITextEditor part, ITextSelection selection) {
+               synchronized (this) {
+                       PartListenerGroup partListener = (PartListenerGroup) fListenerGroups
+                                       .get(part);
+                       if (partListener != null) {
+                               partListener.firePostSelectionChanged(selection);
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/StatusBarUpdater.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/StatusBarUpdater.java
new file mode 100644 (file)
index 0000000..978536f
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+
+/**
+ * Add the <code>StatusBarUpdater</code> to your ViewPart to have the
+ * statusbar describing the selected elements.
+ */
+public class StatusBarUpdater implements ISelectionChangedListener {
+
+       private final int LABEL_FLAGS = JavaElementLabels.DEFAULT_QUALIFIED
+                       | JavaElementLabels.ROOT_POST_QUALIFIED
+                       | JavaElementLabels.APPEND_ROOT_PATH
+                       | JavaElementLabels.M_PARAMETER_TYPES
+                       | JavaElementLabels.M_PARAMETER_NAMES
+                       | JavaElementLabels.M_APP_RETURNTYPE
+                       | JavaElementLabels.M_EXCEPTIONS
+                       | JavaElementLabels.F_APP_TYPE_SIGNATURE;
+
+       private IStatusLineManager fStatusLineManager;
+
+       public StatusBarUpdater(IStatusLineManager statusLineManager) {
+               fStatusLineManager = statusLineManager;
+       }
+
+       /*
+        * @see ISelectionChangedListener#selectionChanged
+        */
+       public void selectionChanged(SelectionChangedEvent event) {
+               String statusBarMessage = formatMessage(event.getSelection());
+               fStatusLineManager.setMessage(statusBarMessage);
+       }
+
+       protected String formatMessage(ISelection sel) {
+               if (sel instanceof IStructuredSelection && !sel.isEmpty()) {
+                       IStructuredSelection selection = (IStructuredSelection) sel;
+
+                       int nElements = selection.size();
+                       if (nElements > 1) {
+                               return PHPUIMessages
+                                               .getFormattedString(
+                                                               "StatusBarUpdater.num_elements_selected", String.valueOf(nElements)); //$NON-NLS-1$
+                       } else {
+                               Object elem = selection.getFirstElement();
+                               if (elem instanceof IJavaElement) {
+                                       return formatJavaElementMessage((IJavaElement) elem);
+                               } else if (elem instanceof IResource) {
+                                       return formatResourceMessage((IResource) elem);
+                               }
+                       }
+               }
+               return ""; //$NON-NLS-1$
+       }
+
+       private String formatJavaElementMessage(IJavaElement element) {
+               return JavaElementLabels.getElementLabel(element, LABEL_FLAGS);
+       }
+
+       private String formatResourceMessage(IResource element) {
+               IContainer parent = element.getParent();
+               if (parent != null && parent.getType() != IResource.ROOT)
+                       return element.getName() + JavaElementLabels.CONCAT_STRING
+                                       + parent.getFullPath().makeRelative().toString();
+               else
+                       return element.getName();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/StorageLabelProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/viewsupport/StorageLabelProvider.java
new file mode 100644 (file)
index 0000000..a5d86bc
--- /dev/null
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+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.PlatformUI;
+
+/**
+ * Standard label provider for IStorage objects. Use this class when you want to
+ * present IStorage objects in a viewer.
+ */
+public class StorageLabelProvider extends LabelProvider {
+
+       private IEditorRegistry fEditorRegistry = PlatformUI.getWorkbench()
+                       .getEditorRegistry();
+
+       private Map fJarImageMap = new HashMap(10);
+
+       private Image fDefaultImage;
+
+       /*
+        * (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;
+               }
+               if (fDefaultImage != null)
+                       fDefaultImage.dispose();
+               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 = fEditorRegistry.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 = fEditorRegistry.getImageDescriptor(name);
+               image = desc.createImage();
+
+               fJarImageMap.put(key, image);
+
+               return image;
+       }
+
+       private Image getDefaultImage() {
+               if (fDefaultImage == null)
+                       fDefaultImage = fEditorRegistry.getImageDescriptor((String) null)
+                                       .createImage();
+               return fDefaultImage;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/IStatusChangeListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/IStatusChangeListener.java
new file mode 100644 (file)
index 0000000..4e1a2ab
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards;
+
+import org.eclipse.core.runtime.IStatus;
+
+public interface IStatusChangeListener {
+
+       /**
+        * Notifies this listener that the given status has changed.
+        * 
+        * @param status
+        *            the new status
+        */
+       void statusChanged(IStatus status);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewClassCreationWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewClassCreationWizard.java
new file mode 100644 (file)
index 0000000..89a5050
--- /dev/null
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.ui.wizards.NewClassWizardPage;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class NewClassCreationWizard extends NewElementWizard {
+
+       private NewClassWizardPage fPage;
+
+       public NewClassCreationWizard() {
+               super();
+               setDefaultPageImageDescriptor(PHPUiImages.DESC_WIZBAN_NEWCLASS);
+               setDialogSettings(WebUI.getDefault().getDialogSettings());
+               setWindowTitle(NewWizardMessages
+                               .getString("NewClassCreationWizard.title")); //$NON-NLS-1$
+       }
+
+       /*
+        * @see Wizard#createPages
+        */
+       public void addPages() {
+               super.addPages();
+               fPage = new NewClassWizardPage();
+               addPage(fPage);
+               fPage.init(getSelection());
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.ui.wizards.NewElementWizard#finishPage(org.eclipse.core.runtime.IProgressMonitor)
+        */
+       protected void finishPage(IProgressMonitor monitor)
+                       throws InterruptedException, CoreException {
+               fPage.createType(monitor); // use the full progress monitor
+               ICompilationUnit cu = JavaModelUtil.toOriginal(fPage.getCreatedType()
+                               .getCompilationUnit());
+               if (cu != null) {
+                       IResource resource = cu.getResource();
+                       selectAndReveal(resource);
+                       openResource((IFile) resource);
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.wizard.IWizard#performFinish()
+        */
+       public boolean performFinish() {
+               // warnAboutTypeCommentDeprecation();
+               return super.performFinish();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewElementWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewElementWizard.java
new file mode 100644 (file)
index 0000000..f6f0882
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.internal.ui.actions.WorkbenchRunnableAdapter;
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
+
+public abstract class NewElementWizard extends Wizard implements INewWizard {
+
+       private IWorkbench fWorkbench;
+
+       private IStructuredSelection fSelection;
+
+       public NewElementWizard() {
+               setNeedsProgressMonitor(true);
+       }
+
+       protected void openResource(final IFile resource) {
+               final IWorkbenchPage activePage = WebUI.getActivePage();
+               if (activePage != null) {
+                       final Display display = getShell().getDisplay();
+                       if (display != null) {
+                               display.asyncExec(new Runnable() {
+                                       public void run() {
+                                               try {
+                                                       IDE.openEditor(activePage, resource, true);
+                                               } catch (PartInitException e) {
+                                                       PHPeclipsePlugin.log(e);
+                                               }
+                                       }
+                               });
+                       }
+               }
+       }
+
+       /**
+        * Subclasses should override to perform the actions of the wizard. This
+        * method is run in the wizard container's context as a workspace runnable.
+        */
+       protected void finishPage(IProgressMonitor monitor)
+                       throws InterruptedException, CoreException {
+       }
+
+       protected void handleFinishException(Shell shell,
+                       InvocationTargetException e) {
+               String title = NewWizardMessages
+                               .getString("NewElementWizard.op_error.title"); //$NON-NLS-1$
+               String message = NewWizardMessages
+                               .getString("NewElementWizard.op_error.message"); //$NON-NLS-1$
+               ExceptionHandler.handle(e, shell, title, message);
+       }
+
+       /*
+        * @see Wizard#performFinish
+        */
+       public boolean performFinish() {
+               IWorkspaceRunnable op = new IWorkspaceRunnable() {
+                       public void run(IProgressMonitor monitor) throws CoreException,
+                                       OperationCanceledException {
+                               try {
+                                       finishPage(monitor);
+                               } catch (InterruptedException e) {
+                                       throw new OperationCanceledException(e.getMessage());
+                               }
+                       }
+               };
+               try {
+                       getContainer().run(false, true, new WorkbenchRunnableAdapter(op));
+               } catch (InvocationTargetException e) {
+                       handleFinishException(getShell(), e);
+                       return false;
+               } catch (InterruptedException e) {
+                       return false;
+               }
+               return true;
+       }
+
+       // protected void warnAboutTypeCommentDeprecation() {
+       // String key= IUIConstants.DIALOGSTORE_TYPECOMMENT_DEPRECATED;
+       // if (OptionalMessageDialog.isDialogEnabled(key)) {
+       // Templates templates= Templates.getInstance();
+       // boolean isOldWorkspace= templates.getTemplates("filecomment").length > 0
+       // && templates.getTemplates("typecomment").length > 0;
+       // //$NON-NLS-1$ //$NON-NLS-2$
+       // if (!isOldWorkspace) {
+       // OptionalMessageDialog.setDialogEnabled(key, false);
+       // }
+       // String title=
+       // NewWizardMessages.getString("NewElementWizard.typecomment.deprecated.title");
+       // //$NON-NLS-1$
+       // String message=
+       // NewWizardMessages.getString("NewElementWizard.typecomment.deprecated.message");
+       // //$NON-NLS-1$
+       // OptionalMessageDialog.open(key, getShell(), title,
+       // OptionalMessageDialog.getDefaultImage(), message,
+       // OptionalMessageDialog.INFORMATION, new String[] {
+       // IDialogConstants.OK_LABEL }, 0);
+       // }
+       // }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench,
+        *      org.eclipse.jface.viewers.IStructuredSelection)
+        */
+       public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
+               fWorkbench = workbench;
+               fSelection = currentSelection;
+       }
+
+       public IStructuredSelection getSelection() {
+               return fSelection;
+       }
+
+       public IWorkbench getWorkbench() {
+               return fWorkbench;
+       }
+
+       protected void selectAndReveal(IResource newResource) {
+               BasicNewResourceWizard.selectAndReveal(newResource, fWorkbench
+                               .getActiveWorkbenchWindow());
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.java
new file mode 100644 (file)
index 0000000..a78bece
--- /dev/null
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class NewWizardMessages {
+
+       private static final String RESOURCE_BUNDLE = NewWizardMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private NewWizardMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.properties
new file mode 100644 (file)
index 0000000..add51e7
--- /dev/null
@@ -0,0 +1,564 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+# ------- AbstractOpenWizardAction ------- 
+
+AbstractOpenWizardAction.noproject.title=New
+AbstractOpenWizardAction.noproject.message=A project needs to be created first.\nOpen the 'New Project' wizard'?
+
+AbstractOpenWizardAction.createerror.title=Open Wizard
+AbstractOpenWizardAction.createerror.message=The wizard could not be opened. See log for details.
+
+# ------- NewElementWizard ------- 
+
+NewElementWizard.op_error.title=New
+NewElementWizard.op_error.message=Creation of element failed.
+
+NewElementWizard.typecomment.deprecated.title=Type Creation
+NewElementWizard.typecomment.deprecated.message=You can configure the default layout of newly created files and types on the 'code generation' preference page.  This was previously implemented on the template page in the templates 'filecomment' and 'typecomment'.
+# ------- NewContainerWizardPage ------- 
+
+NewContainerWizardPage.container.label=Source Fol&der:
+NewContainerWizardPage.container.button=Br&owse...
+
+NewContainerWizardPage.error.EnterContainerName=Folder name is empty.
+NewContainerWizardPage.error.ContainerIsBinary=''{0}'' is a JAR archive.
+NewContainerWizardPage.error.ContainerDoesNotExist=Folder ''{0}'' does not exist.
+NewContainerWizardPage.error.NotAFolder=''{0}'' must be a project or folder.
+NewContainerWizardPage.error.ProjectClosed=Project ''{0}'' must be accessible.
+
+NewContainerWizardPage.warning.NotAJavaProject=Folder is not a Java project.
+NewContainerWizardPage.warning.NotInAJavaProject=Folder is not in a Java project.
+NewContainerWizardPage.warning.NotOnClassPath=Folder is not on the Java build class path.
+
+NewContainerWizardPage.ChooseSourceContainerDialog.title=Folder Selection
+NewContainerWizardPage.ChooseSourceContainerDialog.description=&Choose a folder:
+
+# ------- NewPackageWizardPage ------- 
+
+NewPackageCreationWizard.title=New Java Package
+
+NewPackageWizardPage.package.label=&Name:
+
+
+NewPackageWizardPage.error.InvalidPackageName=Invalid package name. {0}
+NewPackageWizardPage.error.IsOutputFolder=Name conflict with output folder.
+
+NewPackageWizardPage.error.PackageExists=Package already exists.
+NewPackageWizardPage.error.EnterName=Enter a package name.
+NewPackageWizardPage.warning.PackageNotShown=Package already exists. Note: Views might filter empty parent packages.
+NewPackageWizardPage.warning.DiscouragedPackageName=Discouraged package name. {0}
+
+NewPackageWizardPage.title=Java Package
+NewPackageWizardPage.description=Create a Java package.
+NewPackageWizardPage.info=Creates folders corresponding to packages.
+# ------- NewTypeWizardPage ------- 
+
+NewTypeWizardPage.package.label=Pac&kage:
+NewTypeWizardPage.package.button=Bro&wse...
+
+NewTypeWizardPage.enclosing.selection.label=Enclosing t&ype:
+NewTypeWizardPage.enclosing.button=Bro&wse...
+
+NewTypeWizardPage.error.InvalidPackageName=Package name is not valid. {0}
+NewTypeWizardPage.error.ClashOutputLocation=Package clashes with project output folder.
+NewTypeWizardPage.warning.DiscouragedPackageName=This package name is discouraged. {0}
+
+NewTypeWizardPage.default=(default)
+
+NewTypeWizardPage.ChoosePackageDialog.title=Package Selection
+NewTypeWizardPage.ChoosePackageDialog.description=&Choose a folder:
+NewTypeWizardPage.ChoosePackageDialog.empty=Cannot find packages to select.
+
+NewTypeWizardPage.ChooseEnclosingTypeDialog.title=Enclosing Type Selection
+NewTypeWizardPage.ChooseEnclosingTypeDialog.description=&Choose a type to which the new class will be added:
+
+NewTypeWizardPage.error.EnclosingTypeEnterName=Name of enclosing type must be entered.
+NewTypeWizardPage.error.EnclosingTypeNotExists=Enclosing type does not exist.
+NewTypeWizardPage.error.EnclosingNotInCU=Enclosing type is binary.
+NewTypeWizardPage.error.EnclosingNotEditable=Enclosing type is not editable.
+NewTypeWizardPage.warning.EnclosingNotInSourceFolder=Enclosing type is not in specified source folder.
+
+NewTypeWizardPage.typename.label=Na&me:
+
+NewTypeWizardPage.superclass.label=&Superclass:
+NewTypeWizardPage.superclass.button=Brows&e...
+
+NewTypeWizardPage.interfaces.class.label=&Interfaces:
+NewTypeWizardPage.interfaces.ifc.label=Extended &interfaces:
+NewTypeWizardPage.interfaces.add=&Add...
+NewTypeWizardPage.interfaces.remove=&Remove
+
+NewTypeWizardPage.modifiers.acc.label=Modifiers:
+NewTypeWizardPage.modifiers.public=&public
+NewTypeWizardPage.modifiers.private=pri&vate
+NewTypeWizardPage.modifiers.protected=pro&tected
+NewTypeWizardPage.modifiers.default=defa&ult
+NewTypeWizardPage.modifiers.abstract=abs&tract
+NewTypeWizardPage.modifiers.final=fina&l
+NewTypeWizardPage.modifiers.static=stati&c
+
+NewTypeWizardPage.error.EnterTypeName=Type name is empty.
+NewTypeWizardPage.error.TypeNameExists=Type already exists.
+NewTypeWizardPage.error.InvalidTypeName=Type name is not valid. {0}
+NewTypeWizardPage.error.QualifiedName=Type name must not be qualified.
+NewTypeWizardPage.warning.TypeNameDiscouraged=Type name is discouraged. {0}
+
+NewTypeWizardPage.error.InvalidSuperClassName=Superclass name is not valid.
+NewTypeWizardPage.warning.SuperClassNotExists=Warning: Superclass does not exist in current project.
+NewTypeWizardPage.warning.SuperClassIsFinal=Warning: Superclass ''{0}'' is final.
+NewTypeWizardPage.warning.SuperClassIsNotVisible=Warning: Superclass ''{0}'' is not visible.
+NewTypeWizardPage.warning.SuperClassIsNotClass=Warning: Superclass ''{0}'' is an interface.
+
+NewTypeWizardPage.warning.InterfaceIsNotVisible=Extended interface ''{0}'' is not visible.
+NewTypeWizardPage.warning.InterfaceNotExists=Extended interface ''{0}'' does not exist in current project.
+NewTypeWizardPage.warning.InterfaceIsNotInterface=Extended interface ''{0}'' is not an interface.
+
+NewTypeWizardPage.error.ModifiersFinalAndAbstract=Class cannot be both final and abstract
+
+NewTypeWizardPage.SuperClassDialog.title=Superclass Selection
+NewTypeWizardPage.SuperClassDialog.message=&Choose a type:
+
+NewTypeWizardPage.InterfacesDialog.class.title= Implemented Interfaces Selection
+NewTypeWizardPage.InterfacesDialog.interface.title= Extended Interfaces Selection
+NewTypeWizardPage.InterfacesDialog.message=&Choose interfaces:
+
+NewTypeWizardPage.operationdesc=Creating type....
+
+# ------- SuperInterfaceSelectionDialog -----
+
+SuperInterfaceSelectionDialog.addButton.label=&Add
+SuperInterfaceSelectionDialog.interfaceadded.info=''{0}'' added.
+
+# ------- NewClassWizardPage ------- 
+
+NewClassCreationWizard.title=New Java Class
+
+NewClassWizardPage.title=Java Class
+NewClassWizardPage.description=Create a new Java class.
+
+NewClassWizardPage.methods.label=Which method stubs would you like to create?
+NewClassWizardPage.methods.main=public static void main(Strin&g[] args)
+NewClassWizardPage.methods.constructors=&Constructors from superclass
+NewClassWizardPage.methods.inherited=In&herited abstract methods
+
+
+# ------- NewInterfaceWizardPage -------
+
+NewInterfaceCreationWizard.title=New Java Interface
+
+NewInterfaceWizardPage.title=Java Interface
+NewInterfaceWizardPage.description=Create a new Java interface.
+
+# ------- JavaCapabilityWizard ------- 
+
+JavaCapabilityWizard.title=Configure Java Capability
+JavaCapabilityWizard.op_error.title=Error Configure Java Capability
+JavaCapabilityWizard.op_error.message=An error occurred while configuring the Java project
+
+# ------- JavaCapabilityConfigurationPage ------- 
+
+JavaCapabilityConfigurationPage.title=Java Settings
+JavaCapabilityConfigurationPage.description=Define the Java build settings.
+JavaCapabilityConfigurationPage.op_desc_java=Configuring Java project...
+
+
+# ------- NewProjectCreationWizard ------- 
+
+NewProjectCreationWizard.title=New Java Project
+NewProjectCreationWizard.op_error.title=Error Creating Java Project
+NewProjectCreationWizard.op_error_create.message=An error occurred while creating the Java project
+NewProjectCreationWizard.MainPage.title=Java Project
+NewProjectCreationWizard.MainPage.description=Create a new Java project.
+
+NewProjectCreationWizardPage.op_error.title=Error Creating Java Project
+NewProjectCreationWizardPage.op_error_remove.message=An error occurred while removing a temporary project
+NewProjectCreationWizardPage.EarlyCreationOperation.desc=Creating project and examining existing resources...
+NewProjectCreationWizardPage.EarlyCreationOperation.error.title=New Java Project
+NewProjectCreationWizardPage.EarlyCreationOperation.error.desc=An error occurred while creating project. Check log for details.
+NewProjectCreationWizardPage.createproject.desc=Creating project...
+NewProjectCreationWizardPage.removeproject.desc=Removing project...
+
+# ------- NewJavaProjectWizardPage------- 
+
+NewJavaProjectWizardPage.title=Java Settings
+NewJavaProjectWizardPage.description=Define the Java build settings.
+
+NewJavaProjectWizardPage.op_desc=Creating Java project...
+
+
+# ------- NewSourceFolderWizardPage-------
+
+NewSourceFolderCreationWizard.title=New Source Folder
+
+NewSourceFolderWizardPage.title=Source folder
+NewSourceFolderWizardPage.description=Add a new source folder
+
+NewSourceFolderWizardPage.root.label=Fol&der name:
+NewSourceFolderWizardPage.root.button=Br&owse...
+
+NewSourceFolderWizardPage.project.label=Project &name:
+NewSourceFolderWizardPage.project.button=Bro&wse...
+
+NewSourceFolderWizardPage.exclude.label=&Update exclusion filters in other source folders to solve nesting.
+
+NewSourceFolderWizardPage.ChooseExistingRootDialog.title=Existing Folder Selection
+NewSourceFolderWizardPage.ChooseExistingRootDialog.description=&Choose folder as source folder:
+
+NewSourceFolderWizardPage.ChooseProjectDialog.title=Project Selection
+NewSourceFolderWizardPage.ChooseProjectDialog.description=&Choose project for the new source folder:
+
+NewSourceFolderWizardPage.error.EnterRootName=Root name must be entered.
+NewSourceFolderWizardPage.error.InvalidRootName=Invalid folder name. {0}
+NewSourceFolderWizardPage.error.NotAFolder=Not a folder.
+NewSourceFolderWizardPage.error.AlreadyExisting=Already a source folder.
+
+NewSourceFolderWizardPage.error.EnterProjectName=Project name must be entered.
+NewSourceFolderWizardPage.error.InvalidProjectPath=Invalid project path.
+NewSourceFolderWizardPage.error.NotAJavaProject=Project is not a Java project.
+NewSourceFolderWizardPage.error.ProjectNotExists=Project does not exist.
+
+NewSourceFolderWizardPage.warning.ReplaceSFandOL=To avoid overlapping, the existing project source folder entry will be replaced and the output folder set to ''{0}''.
+NewSourceFolderWizardPage.warning.ReplaceOL=An exclusion pattern will be added to the project source folder entry and the output folder will be set to ''{0}''.
+NewSourceFolderWizardPage.warning.ReplaceSF=To avoid overlapping, the existing project source folder entry will be replaced.
+NewSourceFolderWizardPage.warning.AddedExclusions=Exclusion patterns of {0} source folder(s) updated to solve nesting.
+
+# ------- NewSnippetFileWizardPage------- 
+
+NewSnippetFileCreationWizard.title=New Scrapbook Page
+
+NewSnippetFileWizardPage.title=Create Java Scrapbook Page
+
+NewSnippetFileWizardPage.error.AlreadyExists=A resource with the specified path already exists.
+NewSnippetFileWizardPage.error.OnlyInJavaProject=The scrapbook page can only be created in a Java project.
+
+NewSnippetFileWizardPage.open_error.message=Error in NewScrapbookPage
+
+# ------- BuildPathsBlock ------- 
+
+BuildPathsBlock.tab.source=&Source
+BuildPathsBlock.tab.projects=&Projects
+BuildPathsBlock.tab.libraries=&Libraries
+BuildPathsBlock.tab.order=&Order and Export
+
+BuildPathsBlock.classpath.label=Build &class path order and exported entries:\n(Exported entries are contributed to dependent projects)
+
+BuildPathsBlock.classpath.up.button=&Up
+BuildPathsBlock.classpath.down.button=&Down
+BuildPathsBlock.classpath.checkall.button=Select &All
+BuildPathsBlock.classpath.uncheckall.button=D&eselect All
+
+BuildPathsBlock.buildpath.label=Defaul&t output folder:
+BuildPathsBlock.buildpath.button=Bro&wse...
+
+BuildPathsBlock.error.InvalidBuildPath=Invalid build output folder: ''{0}''
+BuildPathsBlock.error.EnterBuildPath=Build output folder must be entered.
+
+BuildPathsBlock.warning.EntryMissing=Build path entry is missing: {0}
+BuildPathsBlock.warning.EntriesMissing={0} build path entries are missing.
+
+BuildPathsBlock.operationdesc_project=Creating project...
+BuildPathsBlock.operationdesc_java=Setting build paths...
+
+BuildPathsBlock.ChooseOutputFolderDialog.title=Folder Selection
+BuildPathsBlock.ChooseOutputFolderDialog.description=&Choose the folder for the build output:
+
+BuildPathsBlock.RemoveBinariesDialog.title=Setting Build Paths
+BuildPathsBlock.RemoveBinariesDialog.description=The output folder has changed. OK to remove all generated resources from the old location ''{0}''?
+
+# ------- CPListLabelProvider ------- 
+
+CPListLabelProvider.new=(new)
+CPListLabelProvider.classcontainer=(class folder)
+CPListLabelProvider.twopart={0} - {1}
+CPListLabelProvider.willbecreated=(will be created)
+
+
+# ------- SourceContainerWorkbookPage------- 
+
+SourceContainerWorkbookPage.folders.label=Source folders on build pat&h:
+SourceContainerWorkbookPage.folders.remove.button=&Remove
+SourceContainerWorkbookPage.folders.add.button=&Add Folder...
+SourceContainerWorkbookPage.folders.edit.button=&Edit...
+
+SourceContainerWorkbookPage.folders.check=Allow output folders for sour&ce folders.
+
+SourceContainerWorkbookPage.ExistingSourceFolderDialog.new.title=Source Folder Selection
+SourceContainerWorkbookPage.ExistingSourceFolderDialog.new.description=&Choose source folders to be added to the build path:
+
+SourceContainerWorkbookPage.ExistingSourceFolderDialog.edit.title=Source Folder Selection
+SourceContainerWorkbookPage.ExistingSourceFolderDialog.edit.description=&Select the source folder:
+
+SourceContainerWorkbookPage.NewSourceFolderDialog.new.title=New Source Folder
+SourceContainerWorkbookPage.NewSourceFolderDialog.edit.title=Edit Source Folder
+
+SourceContainerWorkbookPage.NewSourceFolderDialog.description=&Enter a path relative to ''{0}'':
+
+SourceContainerWorkbookPage.ChangeOutputLocationDialog.title=Source Folder Added
+SourceContainerWorkbookPage.ChangeOutputLocationDialog.project_and_output.message=Do you want to remove the project as source folder and update build output folder to ''{0}''?
+SourceContainerWorkbookPage.ChangeOutputLocationDialog.project.message=Do you want to remove the project as source folder?
+
+SourceContainerWorkbookPage.exclusion_added.title=Source Folder Added
+SourceContainerWorkbookPage.exclusion_added.message=Exclusion filters have been added to nesting folders.
+
+# ------- ProjectsWorkbookPage------- 
+
+ProjectsWorkbookPage.projects.label=&Required projects on the build path:
+ProjectsWorkbookPage.projects.checkall.button=Select &All
+ProjectsWorkbookPage.projects.uncheckall.button=&Deselect All
+
+# ------- LibrariesWorkbookPage------- 
+
+LibrariesWorkbookPage.libraries.label=JARs &and class folders on the build path:
+LibrariesWorkbookPage.libraries.remove.button=&Remove
+       
+LibrariesWorkbookPage.libraries.addjar.button=Add &JARs...
+LibrariesWorkbookPage.libraries.addextjar.button=Add E&xternal JARs...
+LibrariesWorkbookPage.libraries.addvariable.button=Add &Variable...
+LibrariesWorkbookPage.libraries.addlibrary.button=Add Li&brary...
+LibrariesWorkbookPage.libraries.addclassfolder.button=Add Class &Folder...
+
+
+LibrariesWorkbookPage.libraries.edit.button=&Edit...
+
+LibrariesWorkbookPage.ExistingClassFolderDialog.new.title=Class Folder Selection
+LibrariesWorkbookPage.ExistingClassFolderDialog.new.description=&Choose class folders to be added to the build path:
+
+LibrariesWorkbookPage.ExistingClassFolderDialog.edit.title=Edit Class Folder
+LibrariesWorkbookPage.ExistingClassFolderDialog.edit.description=&Select the class folder:
+
+LibrariesWorkbookPage.NewClassFolderDialog.new.title=New Class Folder
+LibrariesWorkbookPage.NewClassFolderDialog.edit.title=Edit Class Folder
+
+LibrariesWorkbookPage.NewClassFolderDialog.description=&Enter a path relative to ''{0}'':
+
+LibrariesWorkbookPage.JARArchiveDialog.new.title=JAR Selection
+LibrariesWorkbookPage.JARArchiveDialog.new.description=&Choose jar archives to be added to the build path:
+
+LibrariesWorkbookPage.JARArchiveDialog.edit.title=Edit JAR
+LibrariesWorkbookPage.JARArchiveDialog.edit.description=&Select the jar archive:
+
+LibrariesWorkbookPage.ContainerDialog.new.title=Add Library
+LibrariesWorkbookPage.ContainerDialog.edit.title=Edit Library
+
+LibrariesWorkbookPage.VariableSelectionDialog.new.title=New Variable Classpath Entry
+LibrariesWorkbookPage.VariableSelectionDialog.edit.title=Edit Variable Entry
+
+LibrariesWorkbookPage.ExtJARArchiveDialog.new.title=JAR Selection
+
+LibrariesWorkbookPage.ExtJARArchiveDialog.edit.title=Edit JAR
+
+LibrariesWorkbookPage.SourceAttachmentDialog.title=Source For ''{0}''
+LibrariesWorkbookPage.JavadocPropertyDialog.title=Javadoc For ''{0}''
+
+LibrariesWorkbookPage.AdvancedDialog.title=Add Classpath Entry
+LibrariesWorkbookPage.AdvancedDialog.description=Select the entry to add to the classpath:
+LibrariesWorkbookPage.AdvancedDialog.createfolder=Create &New Class Folder
+LibrariesWorkbookPage.AdvancedDialog.addfolder=Add &Existing Class Folder
+LibrariesWorkbookPage.AdvancedDialog.addcontainer=Add &Container:
+
+# ------- NewContainerDialog------- 
+
+NewContainerDialog.error.invalidpath=Invalid folder path: ''{0}''
+NewContainerDialog.error.enterpath=Folder name must be entered
+NewContainerDialog.error.pathexists=This folder is already in the list or it is an output folder.
+# ------- NewSourceFolderDialog------- 
+
+NewSourceFolderDialog.error.invalidpath=Invalid folder path: ''{0}''
+NewSourceFolderDialog.error.enterpath=Folder name must be entered.
+NewSourceFolderDialog.error.pathexists=The folder is already in the list.
+
+# ------- SourceAttachmentBlock------- 
+
+SourceAttachmentBlock.message=Select the location (folder, JAR or zip) containing the source for ''{0}'':
+SourceAttachmentBlock.filename.description=Source attachments for variable entries are defined by variable paths. The first segment of such a path describes a variable name, the rest is an optional path extension.
+
+SourceAttachmentBlock.filename.label=Lo&cation path:
+SourceAttachmentBlock.filename.externalfile.button=External &File...
+SourceAttachmentBlock.filename.externalfolder.button=External F&older...
+SourceAttachmentBlock.filename.internal.button=&Workspace...
+
+SourceAttachmentBlock.filename.varlabel=Lo&cation variable path:
+SourceAttachmentBlock.filename.variable.button=&Variable...
+SourceAttachmentBlock.filename.external.varbutton=&Extension....
+
+SourceAttachmentBlock.filename.error.notvalid=The archive path is not a valid path.
+SourceAttachmentBlock.filename.error.filenotexists=The path ''{0}'' does not exist.
+SourceAttachmentBlock.filename.error.varnotexists=Variable in the location path does not exist.
+SourceAttachmentBlock.filename.error.deviceinpath=Location must be described a variable path.
+SourceAttachmentBlock.filename.warning.varempty=Location variable path is empty.
+
+SourceAttachmentBlock.intjardialog.title=Source Location Selection
+SourceAttachmentBlock.intjardialog.message=&Select folder or JAR/zip archive containing the source:
+
+SourceAttachmentBlock.extvardialog.title=Variable Extension Selection
+SourceAttachmentBlock.extvardialog.description=Select source location:
+
+SourceAttachmentBlock.extjardialog.text=JAR/ZIP File Selection
+SourceAttachmentBlock.extfolderdialog.text=Folder Selection
+
+SourceAttachmentBlock.putoncpdialog.title=Setting Source Attachment
+SourceAttachmentBlock.putoncpdialog.message=Source can only be attached to libraries on the build path.\nDo you want to add the library to the build path?
+
+SourceAttachmentDialog.title=Source Attachment Configuration
+SourceAttachmentDialog.error.title=Error Attaching Source
+SourceAttachmentDialog.error.message=An error occurred while associating the source.
+
+# ------- EditVariableEntryDialog ------- 
+
+EditVariableEntryDialog.filename.varlabel=Edit classpath variable entry:
+EditVariableEntryDialog.filename.variable.button=&Variable...
+EditVariableEntryDialog.filename.external.varbutton=&Extension....
+
+EditVariableEntryDialog.extvardialog.title=Variable Extension Selection
+EditVariableEntryDialog.extvardialog.description=Select JAR archive:
+
+EditVariableEntryDialog.filename.error.notvalid=The archive path is not a valid path.
+EditVariableEntryDialog.filename.error.filenotexists=The path ''{0}'' does not point to an existing archive.
+EditVariableEntryDialog.filename.error.varnotexists=Variable in the archive path does not exist.
+EditVariableEntryDialog.filename.error.deviceinpath=The archive has to be described by a variable path.
+EditVariableEntryDialog.filename.warning.varempty=Archive variable path is empty.
+EditVariableEntryDialog.filename.error.alreadyexists=Classpath entry already exists.
+
+
+# ------- VariableBlock------- 
+
+VariableBlock.vars.label=Defined &classpath variables:
+VariableBlock.vars.add.button=Ne&w...
+VariableBlock.vars.edit.button=&Edit...
+VariableBlock.vars.remove.button=&Remove
+VariableBlock.operation_desc=Setting classpath variables...
+
+VariableBlock.operation_errror.title=Classpath Variables
+VariableBlock.operation_errror.message=Problem while setting classpath variable. See log for details.
+
+VariableBlock.needsbuild.title=Classpath Variables Changed
+VariableBlock.needsbuild.message=The classpath variables have changed. A full rebuild is recommended to make changes effective. Do the full build now?
+
+VariablePathDialogField.variabledialog.title=Variable Selection
+
+CPVariableElementLabelProvider.reserved=(reserved)
+CPVariableElementLabelProvider.empty=(empty)
+
+# ------- VariableCreationDialog------- 
+
+VariableCreationDialog.titlenew=New Variable Entry
+VariableCreationDialog.titleedit=Edit Variable Entry
+       
+VariableCreationDialog.name.label=&Name:
+VariableCreationDialog.path.label=&Path:
+VariableCreationDialog.path.file.button=&File...
+VariableCreationDialog.path.dir.button=F&older...
+
+VariableCreationDialog.error.entername=Variable name must be entered.
+VariableCreationDialog.error.invalidname=Invalid name: ''{0}''.
+VariableCreationDialog.error.nameexists=Variable name already exists.
+VariableCreationDialog.error.invalidpath=The path is invalid.
+
+VariableCreationDialog.warning.pathnotexists=Path does not exist.
+
+
+VariableCreationDialog.extjardialog.text=JAR Selection
+VariableCreationDialog.extdirdialog.text=Folder Selection
+VariableCreationDialog.extdirdialog.message=&Specify folder to be represented by the variable:
+
+# ------- NewVariableEntryDialog ------- 
+NewVariableEntryDialog.vars.extend=E&xtend...
+NewVariableEntryDialog.vars.config=&Edit...
+
+NewVariableEntryDialog.vars.label=Select &variables to add to build path:
+
+NewVariableEntryDialog.ExtensionDialog.title=Variable Extension
+NewVariableEntryDialog.ExtensionDialog.description=Choose extensions to ''{0}''.
+
+NewVariableEntryDialog.info.isfolder=Variable points to a folder: Click 'extend' to choose an archive inside the folder.
+NewVariableEntryDialog.info.noselection=Select variable(s) to add to the classpath.
+NewVariableEntryDialog.info.selected={0} variables selected.
+
+# ------- OutputLocationDialog ------- 
+
+OutputLocationDialog.title=Source Folder Output Location
+
+OutputLocationDialog.usedefault.label=Project's default output folder.
+OutputLocationDialog.usespecific.label=Specific output folder (path relative to ''{0}'').
+OutputLocationDialog.location.button=Bro&wse...
+
+OutputLocationDialog.error.existingisfile=Location is an existing file
+OutputLocationDialog.error.invalidpath=Invalid path: {0}
+
+OutputLocationDialog.ChooseOutputFolder.title=Folder Selection
+OutputLocationDialog.ChooseOutputFolder.description=&Choose the folder for the build output:
+
+# ------- ExclusionPatternDialog ------- 
+
+ExclusionPatternDialog.title=Source Folder Exclusion Patterns
+
+ExclusionPatternDialog.pattern.label=E&xclusion patterns for ''{0}'':
+ExclusionPatternDialog.pattern.add=A&dd...
+ExclusionPatternDialog.pattern.add.multiple=Add &Multiple...
+ExclusionPatternDialog.pattern.remove=&Remove
+ExclusionPatternDialog.pattern.edit=&Edit...
+
+ExclusionPatternDialog.ChooseExclusionPattern.title=Exclusion Pattern Selection
+ExclusionPatternDialog.ChooseExclusionPattern.description=&Choose folders or files to exclude:
+
+# ------- ExclusionPatternEntryDialog ------- 
+
+ExclusionPatternEntryDialog.add.title=Add Exclusion Pattern
+ExclusionPatternEntryDialog.edit.title=Edit Exclusion Pattern
+ExclusionPatternEntryDialog.description=Enter a pattern for excluding files from the source folder. Allowed wildcards are '*', '?' and '**'. Examples: 'java/util/A*.java', 'java/util/', '**/Test*'.
+
+ExclusionPatternEntryDialog.pattern.label=E&xclusion pattern (Path relative to ''{0}''):
+ExclusionPatternEntryDialog.pattern.button=Bro&wse...
+
+ExclusionPatternEntryDialog.error.empty=Enter a pattern.
+ExclusionPatternEntryDialog.error.notrelative=Pattern must be a relative path.
+ExclusionPatternEntryDialog.error.exists=Pattern already exists.
+
+ExclusionPatternEntryDialog.ChooseExclusionPattern.title=Exclusion Pattern Selection
+ExclusionPatternEntryDialog.ChooseExclusionPattern.description=&Choose a folder or file to exclude:
+
+# ------- ClasspathContainerDefaultPage------- 
+
+ClasspathContainerDefaultPage.title=Classpath Container
+ClasspathContainerDefaultPage.description=Select classpath container path. First segment is the container type.
+
+ClasspathContainerDefaultPage.path.label=&Classpath container path:
+
+ClasspathContainerDefaultPage.path.error.enterpath=Enter path.
+ClasspathContainerDefaultPage.path.error.invalidpath=Invalid path.
+ClasspathContainerDefaultPage.path.error.needssegment=Path needs at least one segment.
+ClasspathContainerDefaultPage.path.error.alreadyexists=Entry already exists.
+
+# ------- ClasspathContainerSelectionPage------- 
+
+ClasspathContainerSelectionPage.title=Add Library
+ClasspathContainerSelectionPage.description=Select the library type to add.
+
+# ------- ClasspathContainerWizard------- 
+
+ClasspathContainerWizard.pagecreationerror.title= Library Wizard
+ClasspathContainerWizard.pagecreationerror.message=Wizard page creation failed. Check log for details.
+
+
+FolderSelectionDialog.button=Create New Folder...
+CPListLabelProvider.none=(None)
+CPListLabelProvider.source_attachment.label=Source attachment: 
+CPListLabelProvider.source_attachment_root.label=Source attachment root: 
+CPListLabelProvider.javadoc_location.label=Javadoc location: 
+CPListLabelProvider.output_folder.label=Output folder: 
+CPListLabelProvider.default_output_folder.label=(Default output folder)
+CPListLabelProvider.exclusion_filter.label=Exclusion filter: 
+CPListLabelProvider.exclusion_filter_separator=; 
+CPListLabelProvider.unknown_element.label=unknown element
+NewSourceFolderDialog.useproject.button=&Project as source folder
+NewSourceFolderDialog.usefolder.button=&Folder as source folder
+NewSourceFolderDialog.sourcefolder.label=&Source folder name:
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/CheckedListDialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/CheckedListDialogField.java
new file mode 100644 (file)
index 0000000..fe748f9
--- /dev/null
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * A list with checkboxes and a button bar. Typical buttons are 'Check All' and
+ * 'Uncheck All'. List model is independend of widget creation. DialogFields
+ * controls are: Label, List and Composite containing buttons.
+ */
+public class CheckedListDialogField extends ListDialogField {
+
+       private int fCheckAllButtonIndex;
+
+       private int fUncheckAllButtonIndex;
+
+       private List fCheckElements;
+
+       public CheckedListDialogField(IListAdapter adapter,
+                       String[] customButtonLabels, ILabelProvider lprovider) {
+               super(adapter, customButtonLabels, lprovider);
+               fCheckElements = new ArrayList();
+
+               fCheckAllButtonIndex = -1;
+               fUncheckAllButtonIndex = -1;
+       }
+
+       /**
+        * Sets the index of the 'check' button in the button label array passed in
+        * the constructor. The behaviour of the button marked as the check button
+        * will then be handled internally. (enable state, button invocation
+        * behaviour)
+        */
+       public void setCheckAllButtonIndex(int checkButtonIndex) {
+               Assert.isTrue(checkButtonIndex < fButtonLabels.length);
+               fCheckAllButtonIndex = checkButtonIndex;
+       }
+
+       /**
+        * Sets the index of the 'uncheck' button in the button label array passed
+        * in the constructor. The behaviour of the button marked as the uncheck
+        * button will then be handled internally. (enable state, button invocation
+        * behaviour)
+        */
+       public void setUncheckAllButtonIndex(int uncheckButtonIndex) {
+               Assert.isTrue(uncheckButtonIndex < fButtonLabels.length);
+               fUncheckAllButtonIndex = uncheckButtonIndex;
+       }
+
+       /*
+        * @see ListDialogField#createTableViewer
+        */
+       protected TableViewer createTableViewer(Composite parent) {
+               Table table = new Table(parent, SWT.CHECK + getListStyle());
+               CheckboxTableViewer tableViewer = new CheckboxTableViewer(table);
+               tableViewer.addCheckStateListener(new ICheckStateListener() {
+                       public void checkStateChanged(CheckStateChangedEvent e) {
+                               doCheckStateChanged(e);
+                       }
+               });
+               return tableViewer;
+       }
+
+       /*
+        * @see ListDialogField#getListControl
+        */
+       public Control getListControl(Composite parent) {
+               Control control = super.getListControl(parent);
+               if (parent != null) {
+                       ((CheckboxTableViewer) fTable).setCheckedElements(fCheckElements
+                                       .toArray());
+               }
+               return control;
+       }
+
+       /*
+        * @see DialogField#dialogFieldChanged Hooks in to get element changes to
+        *      update check model.
+        */
+       public void dialogFieldChanged() {
+               for (int i = fCheckElements.size() - 1; i >= 0; i--) {
+                       if (!fElements.contains(fCheckElements.get(i))) {
+                               fCheckElements.remove(i);
+                       }
+               }
+               super.dialogFieldChanged();
+       }
+
+       private void checkStateChanged() {
+               // call super and do not update check model
+               super.dialogFieldChanged();
+       }
+
+       /**
+        * Gets the checked elements.
+        */
+       public List getCheckedElements() {
+               return new ArrayList(fCheckElements);
+       }
+
+       /**
+        * Returns true if the element is checked.
+        */
+       public boolean isChecked(Object obj) {
+               return fCheckElements.contains(obj);
+       }
+
+       /**
+        * Sets the checked elements.
+        */
+       public void setCheckedElements(List list) {
+               fCheckElements = new ArrayList(list);
+               if (fTable != null) {
+                       ((CheckboxTableViewer) fTable).setCheckedElements(list.toArray());
+               }
+               checkStateChanged();
+       }
+
+       /**
+        * Sets the checked state of an element.
+        */
+       public void setChecked(Object object, boolean state) {
+               setCheckedWithoutUpdate(object, state);
+               checkStateChanged();
+       }
+
+       /**
+        * Sets the checked state of an element. No dialog changed listener is
+        * informed.
+        */
+       public void setCheckedWithoutUpdate(Object object, boolean state) {
+               if (!fCheckElements.contains(object)) {
+                       fCheckElements.add(object);
+               }
+               if (fTable != null) {
+                       ((CheckboxTableViewer) fTable).setChecked(object, state);
+               }
+       }
+
+       /**
+        * Sets the check state of all elements
+        */
+       public void checkAll(boolean state) {
+               if (state) {
+                       fCheckElements = getElements();
+               } else {
+                       fCheckElements.clear();
+               }
+               if (fTable != null) {
+                       ((CheckboxTableViewer) fTable).setAllChecked(state);
+               }
+               checkStateChanged();
+       }
+
+       private void doCheckStateChanged(CheckStateChangedEvent e) {
+               if (e.getChecked()) {
+                       fCheckElements.add(e.getElement());
+               } else {
+                       fCheckElements.remove(e.getElement());
+               }
+               checkStateChanged();
+       }
+
+       // ------ enable / disable management
+
+       /*
+        * @see ListDialogField#getManagedButtonState
+        */
+       protected boolean getManagedButtonState(ISelection sel, int index) {
+               if (index == fCheckAllButtonIndex) {
+                       return !fElements.isEmpty();
+               } else if (index == fUncheckAllButtonIndex) {
+                       return !fElements.isEmpty();
+               }
+               return super.getManagedButtonState(sel, index);
+       }
+
+       /*
+        * @see ListDialogField#extraButtonPressed
+        */
+       protected boolean managedButtonPressed(int index) {
+               if (index == fCheckAllButtonIndex) {
+                       checkAll(true);
+               } else if (index == fUncheckAllButtonIndex) {
+                       checkAll(false);
+               } else {
+                       return super.managedButtonPressed(index);
+               }
+               return true;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ComboDialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ComboDialogField.java
new file mode 100644 (file)
index 0000000..777e4bf
--- /dev/null
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Dialog field containing a label and a combo control.
+ */
+public class ComboDialogField extends DialogField {
+
+       private String fText;
+
+       private int fSelectionIndex;
+
+       private String[] fItems;
+
+       private Combo fComboControl;
+
+       private ModifyListener fModifyListener;
+
+       private int fFlags;
+
+       public ComboDialogField(int flags) {
+               super();
+               fText = ""; //$NON-NLS-1$
+               fItems = new String[0];
+               fFlags = flags;
+               fSelectionIndex = -1;
+       }
+
+       // ------- layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+
+               Label label = getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(1));
+               Combo combo = getComboControl(parent);
+               combo.setLayoutData(gridDataForCombo(nColumns - 1));
+
+               return new Control[] { label, combo };
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 2;
+       }
+
+       protected static GridData gridDataForCombo(int span) {
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = false;
+               gd.horizontalSpan = span;
+               return gd;
+       }
+
+       // ------- focus methods
+
+       /*
+        * @see DialogField#setFocus
+        */
+       public boolean setFocus() {
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.setFocus();
+               }
+               return true;
+       }
+
+       // ------- ui creation
+
+       /**
+        * Creates or returns the created combo control.
+        * 
+        * @param parent
+        *            The parent composite or <code>null</code> when the widget
+        *            has already been created.
+        */
+       public Combo getComboControl(Composite parent) {
+               if (fComboControl == null) {
+                       assertCompositeNotNull(parent);
+                       fModifyListener = new ModifyListener() {
+                               public void modifyText(ModifyEvent e) {
+                                       doModifyText(e);
+                               }
+                       };
+                       SelectionListener selectionListener = new SelectionListener() {
+                               public void widgetSelected(SelectionEvent e) {
+                                       doSelectionChanged(e);
+                               }
+
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                               };
+                       };
+
+                       fComboControl = new Combo(parent, fFlags);
+                       // moved up due to 1GEUNW2
+                       fComboControl.setItems(fItems);
+                       if (fSelectionIndex != -1) {
+                               fComboControl.select(fSelectionIndex);
+                       } else {
+                               fComboControl.setText(fText);
+                       }
+                       fComboControl.setFont(parent.getFont());
+                       fComboControl.addModifyListener(fModifyListener);
+                       fComboControl.addSelectionListener(selectionListener);
+                       fComboControl.setEnabled(isEnabled());
+               }
+               return fComboControl;
+       }
+
+       private void doModifyText(ModifyEvent e) {
+               if (isOkToUse(fComboControl)) {
+                       fText = fComboControl.getText();
+                       fSelectionIndex = fComboControl.getSelectionIndex();
+               }
+               dialogFieldChanged();
+       }
+
+       private void doSelectionChanged(SelectionEvent e) {
+               if (isOkToUse(fComboControl)) {
+                       fItems = fComboControl.getItems();
+                       fText = fComboControl.getText();
+                       fSelectionIndex = fComboControl.getSelectionIndex();
+               }
+               dialogFieldChanged();
+       }
+
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#updateEnableState
+        */
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.setEnabled(isEnabled());
+               }
+       }
+
+       // ------ text access
+
+       /**
+        * Gets the combo items.
+        */
+       public String[] getItems() {
+               return fItems;
+       }
+
+       /**
+        * Sets the combo items. Triggers a dialog-changed event.
+        */
+       public void setItems(String[] items) {
+               fItems = items;
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.setItems(items);
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+        * Gets the text.
+        */
+       public String getText() {
+               return fText;
+       }
+
+       /**
+        * Sets the text. Triggers a dialog-changed event.
+        */
+       public void setText(String text) {
+               fText = text;
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.setText(text);
+               } else {
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Selects an item.
+        */
+       public void selectItem(int index) {
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.select(index);
+               } else {
+                       if (index >= 0 && index < fItems.length) {
+                               fText = fItems[index];
+                               fSelectionIndex = index;
+                       }
+               }
+               dialogFieldChanged();
+       }
+
+       public int getSelectionIndex() {
+               return fSelectionIndex;
+       }
+
+       /**
+        * Sets the text without triggering a dialog-changed event.
+        */
+       public void setTextWithoutUpdate(String text) {
+               fText = text;
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.removeModifyListener(fModifyListener);
+                       fComboControl.setText(text);
+                       fComboControl.addModifyListener(fModifyListener);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/DialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/DialogField.java
new file mode 100644 (file)
index 0000000..b624ec5
--- /dev/null
@@ -0,0 +1,228 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.jface.util.Assert;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Base class of all dialog fields. Dialog fields manage controls together with
+ * the model, independed from the creation time of the widgets. - support for
+ * automated layouting. - enable / disable, set focus a concept of the base
+ * class.
+ * 
+ * DialogField have a label.
+ */
+public class DialogField {
+
+       private Label fLabel;
+
+       protected String fLabelText;
+
+       private IDialogFieldListener fDialogFieldListener;
+
+       private boolean fEnabled;
+
+       public DialogField() {
+               fEnabled = true;
+               fLabel = null;
+               fLabelText = ""; //$NON-NLS-1$
+       }
+
+       /**
+        * Sets the label of the dialog field.
+        */
+       public void setLabelText(String labeltext) {
+               fLabelText = labeltext;
+       }
+
+       // ------ change listener
+
+       /**
+        * Defines the listener for this dialog field.
+        */
+       public final void setDialogFieldListener(IDialogFieldListener listener) {
+               fDialogFieldListener = listener;
+       }
+
+       /**
+        * Programatical invocation of a dialog field change.
+        */
+       public void dialogFieldChanged() {
+               if (fDialogFieldListener != null) {
+                       fDialogFieldListener.dialogFieldChanged(this);
+               }
+       }
+
+       // ------- focus management
+
+       /**
+        * Tries to set the focus to the dialog field. Returns <code>true</code>
+        * if the dialog field can take focus. To be reimplemented by dialog field
+        * implementors.
+        */
+       public boolean setFocus() {
+               return false;
+       }
+
+       /**
+        * Posts <code>setFocus</code> to the display event queue.
+        */
+       public void postSetFocusOnDialogField(Display display) {
+               if (display != null) {
+                       display.asyncExec(new Runnable() {
+                               public void run() {
+                                       setFocus();
+                               }
+                       });
+               }
+       }
+
+       // ------- layout helpers
+
+       /**
+        * Creates all controls of the dialog field and fills it to a composite. The
+        * composite is assumed to have <code>MGridLayout</code> as layout. The
+        * dialog field will adjust its controls' spans to the number of columns
+        * given. To be reimplemented by dialog field implementors.
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+
+               Label label = getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(nColumns));
+
+               return new Control[] { label };
+       }
+
+       /**
+        * Returns the number of columns of the dialog field. To be reimplemented by
+        * dialog field implementors.
+        */
+       public int getNumberOfControls() {
+               return 1;
+       }
+
+       protected static GridData gridDataForLabel(int span) {
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = span;
+               return gd;
+       }
+
+       // ------- ui creation
+
+       /**
+        * Creates or returns the created label widget.
+        * 
+        * @param parent
+        *            The parent composite or <code>null</code> if the widget has
+        *            already been created.
+        */
+       public Label getLabelControl(Composite parent) {
+               if (fLabel == null) {
+                       assertCompositeNotNull(parent);
+
+                       fLabel = new Label(parent, SWT.LEFT | SWT.WRAP);
+                       fLabel.setFont(parent.getFont());
+                       fLabel.setEnabled(fEnabled);
+                       if (fLabelText != null && !"".equals(fLabelText)) { //$NON-NLS-1$
+                               fLabel.setText(fLabelText);
+                       } else {
+                               // XXX: to avoid a 16 pixel wide empty label - revisit
+                               fLabel.setText("."); //$NON-NLS-1$
+                               fLabel.setVisible(false);
+                       }
+               }
+               return fLabel;
+       }
+
+       /**
+        * Creates a spacer control.
+        * 
+        * @param parent
+        *            The parent composite
+        */
+       public static Control createEmptySpace(Composite parent) {
+               return createEmptySpace(parent, 1);
+       }
+
+       /**
+        * Creates a spacer control with the given span. The composite is assumed to
+        * have <code>MGridLayout</code> as layout.
+        * 
+        * @param parent
+        *            The parent composite
+        */
+       public static Control createEmptySpace(Composite parent, int span) {
+               Label label = new Label(parent, SWT.LEFT);
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.BEGINNING;
+               gd.grabExcessHorizontalSpace = false;
+               gd.horizontalSpan = span;
+               gd.horizontalIndent = 0;
+               gd.widthHint = 0;
+               gd.heightHint = 0;
+               label.setLayoutData(gd);
+               return label;
+       }
+
+       /**
+        * Tests is the control is not <code>null</code> and not disposed.
+        */
+       protected final boolean isOkToUse(Control control) {
+               return (control != null) && !(control.isDisposed());
+       }
+
+       // --------- enable / disable management
+
+       /**
+        * Sets the enable state of the dialog field.
+        */
+       public final void setEnabled(boolean enabled) {
+               if (enabled != fEnabled) {
+                       fEnabled = enabled;
+                       updateEnableState();
+               }
+       }
+
+       /**
+        * Called when the enable state changed. To be extended by dialog field
+        * implementors.
+        */
+       protected void updateEnableState() {
+               if (fLabel != null) {
+                       fLabel.setEnabled(fEnabled);
+               }
+       }
+
+       /**
+        * Gets the enable state of the dialog field.
+        */
+       public final boolean isEnabled() {
+               return fEnabled;
+       }
+
+       protected final void assertCompositeNotNull(Composite comp) {
+               Assert.isNotNull(comp,
+                               "uncreated control requested with composite null"); //$NON-NLS-1$
+       }
+
+       protected final void assertEnoughColumns(int nColumns) {
+               Assert.isTrue(nColumns >= getNumberOfControls(),
+                               "given number of columns is too small"); //$NON-NLS-1$
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IDialogFieldListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IDialogFieldListener.java
new file mode 100644 (file)
index 0000000..2d497d8
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+/**
+ * Change listener used by <code>DialogField</code>
+ */
+public interface IDialogFieldListener {
+
+       /**
+        * The dialog field has changed.
+        */
+       void dialogFieldChanged(DialogField field);
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IListAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IListAdapter.java
new file mode 100644 (file)
index 0000000..825a78c
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+/**
+ * Change listener used by <code>ListDialogField</code> and
+ * <code>CheckedListDialogField</code>
+ */
+public interface IListAdapter {
+
+       /**
+        * A button from the button bar has been pressed.
+        */
+       void customButtonPressed(ListDialogField field, int index);
+
+       /**
+        * The selection of the list has changed.
+        */
+       void selectionChanged(ListDialogField field);
+
+       /**
+        * En entry in the list has been double clicked
+        */
+       void doubleClicked(ListDialogField field);
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IStringButtonAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IStringButtonAdapter.java
new file mode 100644 (file)
index 0000000..7a3f1cf
--- /dev/null
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+/**
+ * Change listener used by <code>StringButtonDialogField</code>
+ */
+public interface IStringButtonAdapter {
+
+       void changeControlPressed(DialogField field);
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ITreeListAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ITreeListAdapter.java
new file mode 100644 (file)
index 0000000..d4d186b
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.swt.events.KeyEvent;
+
+/**
+ * Change listener used by <code>TreeListDialogField</code>
+ */
+public interface ITreeListAdapter {
+
+       /**
+        * A button from the button bar has been pressed.
+        */
+       void customButtonPressed(TreeListDialogField field, int index);
+
+       /**
+        * The selection of the list has changed.
+        */
+       void selectionChanged(TreeListDialogField field);
+
+       /**
+        * The list has been double clicked
+        */
+       void doubleClicked(TreeListDialogField field);
+
+       /**
+        * A key has been pressed
+        */
+       void keyPressed(TreeListDialogField field, KeyEvent event);
+
+       Object[] getChildren(TreeListDialogField field, Object element);
+
+       Object getParent(TreeListDialogField field, Object element);
+
+       boolean hasChildren(TreeListDialogField field, Object element);
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/LayoutUtil.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/LayoutUtil.java
new file mode 100644 (file)
index 0000000..baee413
--- /dev/null
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+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.Control;
+
+public class LayoutUtil {
+
+       /**
+        * Calculates the number of columns needed by field editors
+        */
+       public static int getNumberOfColumns(DialogField[] editors) {
+               int nCulumns = 0;
+               for (int i = 0; i < editors.length; i++) {
+                       nCulumns = Math.max(editors[i].getNumberOfControls(), nCulumns);
+               }
+               return nCulumns;
+       }
+
+       /**
+        * Creates a composite and fills in the given editors.
+        * 
+        * @param labelOnTop
+        *            Defines if the label of all fields should be on top of the
+        *            fields
+        */
+       public static void doDefaultLayout(Composite parent, DialogField[] editors,
+                       boolean labelOnTop) {
+               doDefaultLayout(parent, editors, labelOnTop, 0, 0, 0, 0);
+       }
+
+       /**
+        * Creates a composite and fills in the given editors.
+        * 
+        * @param labelOnTop
+        *            Defines if the label of all fields should be on top of the
+        *            fields
+        * @param minWidth
+        *            The minimal width of the composite
+        * @param minHeight
+        *            The minimal height of the composite
+        */
+       public static void doDefaultLayout(Composite parent, DialogField[] editors,
+                       boolean labelOnTop, int minWidth, int minHeight) {
+               doDefaultLayout(parent, editors, labelOnTop, minWidth, minHeight, 0, 0);
+       }
+
+       /**
+        * Creates a composite and fills in the given editors.
+        * 
+        * @param labelOnTop
+        *            Defines if the label of all fields should be on top of the
+        *            fields
+        * @param minWidth
+        *            The minimal width of the composite
+        * @param minHeight
+        *            The minimal height of the composite
+        * @param marginWidth
+        *            The margin width to be used by the composite
+        * @param marginHeight
+        *            The margin height to be used by the composite
+        * @deprecated
+        */
+       public static void doDefaultLayout(Composite parent, DialogField[] editors,
+                       boolean labelOnTop, int minWidth, int minHeight, int marginWidth,
+                       int marginHeight) {
+               int nCulumns = getNumberOfColumns(editors);
+               Control[][] controls = new Control[editors.length][];
+               for (int i = 0; i < editors.length; i++) {
+                       controls[i] = editors[i].doFillIntoGrid(parent, nCulumns);
+               }
+               if (labelOnTop) {
+                       nCulumns--;
+                       modifyLabelSpans(controls, nCulumns);
+               }
+               GridLayout layout = new GridLayout();
+               if (marginWidth != SWT.DEFAULT) {
+                       layout.marginWidth = marginWidth;
+               }
+               if (marginHeight != SWT.DEFAULT) {
+                       layout.marginHeight = marginHeight;
+               }
+               layout.numColumns = nCulumns;
+               parent.setLayout(layout);
+       }
+
+       private static void modifyLabelSpans(Control[][] controls, int nCulumns) {
+               for (int i = 0; i < controls.length; i++) {
+                       setHorizontalSpan(controls[i][0], nCulumns);
+               }
+       }
+
+       /**
+        * Sets the span of a control. Assumes that GridData is used.
+        */
+       public static void setHorizontalSpan(Control control, int span) {
+               Object ld = control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData) ld).horizontalSpan = span;
+               } else if (span != 1) {
+                       GridData gd = new GridData();
+                       gd.horizontalSpan = span;
+                       control.setLayoutData(gd);
+               }
+       }
+
+       /**
+        * Sets the width hint of a control. Assumes that GridData is used.
+        */
+       public static void setWidthHint(Control control, int widthHint) {
+               Object ld = control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData) ld).widthHint = widthHint;
+               }
+       }
+
+       /**
+        * Sets the heigthHint hint of a control. Assumes that GridData is used.
+        */
+       public static void setHeigthHint(Control control, int heigthHint) {
+               Object ld = control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData) ld).heightHint = heigthHint;
+               }
+       }
+
+       /**
+        * Sets the horizontal indent of a control. Assumes that GridData is used.
+        */
+       public static void setHorizontalIndent(Control control, int horizontalIndent) {
+               Object ld = control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData) ld).horizontalIndent = horizontalIndent;
+               }
+       }
+
+       /**
+        * Sets the horizontal indent of a control. Assumes that GridData is used.
+        */
+       public static void setHorizontalGrabbing(Control control) {
+               Object ld = control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData) ld).grabExcessHorizontalSpace = true;
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ListDialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ListDialogField.java
new file mode 100644 (file)
index 0000000..2c028b0
--- /dev/null
@@ -0,0 +1,918 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpdt.internal.ui.util.TableLayoutComposite;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+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.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * A list with a button bar. Typical buttons are 'Add', 'Remove', 'Up' and
+ * 'Down'. List model is independend of widget creation. DialogFields controls
+ * are: Label, List and Composite containing buttons.
+ */
+public class ListDialogField extends DialogField {
+
+       public static class ColumnsDescription {
+               private ColumnLayoutData[] columns;
+
+               private String[] headers;
+
+               private boolean drawLines;
+
+               public ColumnsDescription(ColumnLayoutData[] columns, String[] headers,
+                               boolean drawLines) {
+                       this.columns = columns;
+                       this.headers = headers;
+                       this.drawLines = drawLines;
+               }
+
+               public ColumnsDescription(String[] headers, boolean drawLines) {
+                       this(createColumnWeightData(headers.length), headers, drawLines);
+               }
+
+               public ColumnsDescription(int nColumns, boolean drawLines) {
+                       this(createColumnWeightData(nColumns), null, drawLines);
+               }
+
+               private static ColumnLayoutData[] createColumnWeightData(int nColumns) {
+                       ColumnLayoutData[] data = new ColumnLayoutData[nColumns];
+                       for (int i = 0; i < nColumns; i++) {
+                               data[i] = new ColumnWeightData(1);
+                       }
+                       return data;
+               }
+       }
+
+       protected TableViewer fTable;
+
+       protected ILabelProvider fLabelProvider;
+
+       protected ListViewerAdapter fListViewerAdapter;
+
+       protected List fElements;
+
+       protected ViewerSorter fViewerSorter;
+
+       protected String[] fButtonLabels;
+
+       private Button[] fButtonControls;
+
+       private boolean[] fButtonsEnabled;
+
+       private int fRemoveButtonIndex;
+
+       private int fUpButtonIndex;
+
+       private int fDownButtonIndex;
+
+       private Label fLastSeparator;
+
+       private Control fTableControl;
+
+       private Composite fButtonsControl;
+
+       private ISelection fSelectionWhenEnabled;
+
+       private IListAdapter fListAdapter;
+
+       private Object fParentElement;
+
+       private ColumnsDescription fTableColumns;
+
+       /**
+        * Creates the <code>ListDialogField</code>.
+        * 
+        * @param adapter
+        *            A listener for button invocation, selection changes. Can be
+        *            <code>null</code>.
+        * @param buttonLabels
+        *            The labels of all buttons: <code>null</code> is a valid
+        *            array entry and marks a separator.
+        * @param lprovider
+        *            The label provider to render the table entries
+        */
+       public ListDialogField(IListAdapter adapter, String[] buttonLabels,
+                       ILabelProvider lprovider) {
+               super();
+               fListAdapter = adapter;
+
+               fLabelProvider = lprovider;
+               fListViewerAdapter = new ListViewerAdapter();
+               fParentElement = this;
+
+               fElements = new ArrayList(10);
+
+               fButtonLabels = buttonLabels;
+               if (fButtonLabels != null) {
+                       int nButtons = fButtonLabels.length;
+                       fButtonsEnabled = new boolean[nButtons];
+                       for (int i = 0; i < nButtons; i++) {
+                               fButtonsEnabled[i] = true;
+                       }
+               }
+
+               fTable = null;
+               fTableControl = null;
+               fButtonsControl = null;
+               fTableColumns = null;
+
+               fRemoveButtonIndex = -1;
+               fUpButtonIndex = -1;
+               fDownButtonIndex = -1;
+       }
+
+       /**
+        * Sets the index of the 'remove' button in the button label array passed in
+        * the constructor. The behaviour of the button marked as the 'remove'
+        * button will then be handled internally. (enable state, button invocation
+        * behaviour)
+        */
+       public void setRemoveButtonIndex(int removeButtonIndex) {
+               Assert.isTrue(removeButtonIndex < fButtonLabels.length);
+               fRemoveButtonIndex = removeButtonIndex;
+       }
+
+       /**
+        * Sets the index of the 'up' button in the button label array passed in the
+        * constructor. The behaviour of the button marked as the 'up' button will
+        * then be handled internally. (enable state, button invocation behaviour)
+        */
+       public void setUpButtonIndex(int upButtonIndex) {
+               Assert.isTrue(upButtonIndex < fButtonLabels.length);
+               fUpButtonIndex = upButtonIndex;
+       }
+
+       /**
+        * Sets the index of the 'down' button in the button label array passed in
+        * the constructor. The behaviour of the button marked as the 'down' button
+        * will then be handled internally. (enable state, button invocation
+        * behaviour)
+        */
+       public void setDownButtonIndex(int downButtonIndex) {
+               Assert.isTrue(downButtonIndex < fButtonLabels.length);
+               fDownButtonIndex = downButtonIndex;
+       }
+
+       /**
+        * Sets the viewerSorter.
+        * 
+        * @param viewerSorter
+        *            The viewerSorter to set
+        */
+       public void setViewerSorter(ViewerSorter viewerSorter) {
+               fViewerSorter = viewerSorter;
+       }
+
+       public void setTableColumns(ColumnsDescription column) {
+               fTableColumns = column;
+       }
+
+       // ------ adapter communication
+
+       private void buttonPressed(int index) {
+               if (!managedButtonPressed(index) && fListAdapter != null) {
+                       fListAdapter.customButtonPressed(this, index);
+               }
+       }
+
+       /**
+        * Checks if the button pressed is handled internally
+        * 
+        * @return Returns true if button has been handled.
+        */
+       protected boolean managedButtonPressed(int index) {
+               if (index == fRemoveButtonIndex) {
+                       remove();
+               } else if (index == fUpButtonIndex) {
+                       up();
+               } else if (index == fDownButtonIndex) {
+                       down();
+               } else {
+                       return false;
+               }
+               return true;
+       }
+
+       // ------ layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               PixelConverter converter = new PixelConverter(parent);
+
+               assertEnoughColumns(nColumns);
+
+               Label label = getLabelControl(parent);
+               GridData gd = gridDataForLabel(1);
+               gd.verticalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gd);
+
+               Control list = getListControl(parent);
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = false;
+               gd.verticalAlignment = GridData.FILL;
+               gd.grabExcessVerticalSpace = true;
+               gd.horizontalSpan = nColumns - 2;
+               gd.widthHint = converter.convertWidthInCharsToPixels(50);
+               gd.heightHint = converter.convertHeightInCharsToPixels(6);
+
+               list.setLayoutData(gd);
+
+               Composite buttons = getButtonBox(parent);
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = false;
+               gd.verticalAlignment = GridData.FILL;
+               gd.grabExcessVerticalSpace = true;
+               gd.horizontalSpan = 1;
+               buttons.setLayoutData(gd);
+
+               return new Control[] { label, list, buttons };
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 3;
+       }
+
+       /**
+        * Sets the minimal width of the buttons. Must be called after widget
+        * creation.
+        */
+       public void setButtonsMinWidth(int minWidth) {
+               if (fLastSeparator != null) {
+                       ((GridData) fLastSeparator.getLayoutData()).widthHint = minWidth;
+               }
+       }
+
+       // ------ ui creation
+
+       /**
+        * Returns the list control. When called the first time, the control will be
+        * created.
+        * 
+        * @param The
+        *            parent composite when called the first time, or
+        *            <code>null</code> after.
+        */
+       public Control getListControl(Composite parent) {
+               if (fTableControl == null) {
+                       assertCompositeNotNull(parent);
+
+                       if (fTableColumns == null) {
+                               fTable = createTableViewer(parent);
+                               Table tableControl = fTable.getTable();
+
+                               fTableControl = tableControl;
+                               tableControl.setLayout(new TableLayout());
+                       } else {
+                               TableLayoutComposite composite = new TableLayoutComposite(
+                                               parent, SWT.NONE);
+                               fTableControl = composite;
+
+                               fTable = createTableViewer(composite);
+                               Table tableControl = fTable.getTable();
+
+                               tableControl.setHeaderVisible(fTableColumns.headers != null);
+                               tableControl.setLinesVisible(fTableColumns.drawLines);
+                               ColumnLayoutData[] columns = fTableColumns.columns;
+                               for (int i = 0; i < columns.length; i++) {
+                                       composite.addColumnData(columns[i]);
+                                       TableColumn column = new TableColumn(tableControl, SWT.NONE);
+                                       // tableLayout.addColumnData(columns[i]);
+                                       if (fTableColumns.headers != null) {
+                                               column.setText(fTableColumns.headers[i]);
+                                       }
+                               }
+                       }
+
+                       fTable.getTable().addKeyListener(new KeyAdapter() {
+                               public void keyPressed(KeyEvent e) {
+                                       handleKeyPressed(e);
+                               }
+                       });
+
+                       // fTableControl.setLayout(tableLayout);
+
+                       fTable.setContentProvider(fListViewerAdapter);
+                       fTable.setLabelProvider(fLabelProvider);
+                       fTable.addSelectionChangedListener(fListViewerAdapter);
+                       fTable.addDoubleClickListener(fListViewerAdapter);
+
+                       fTable.setInput(fParentElement);
+
+                       if (fViewerSorter != null) {
+                               fTable.setSorter(fViewerSorter);
+                       }
+
+                       fTableControl.setEnabled(isEnabled());
+                       if (fSelectionWhenEnabled != null) {
+                               postSetSelection(fSelectionWhenEnabled);
+                       }
+               }
+               return fTableControl;
+       }
+
+       /**
+        * Returns the internally used table viewer.
+        */
+       public TableViewer getTableViewer() {
+               return fTable;
+       }
+
+       /*
+        * Subclasses may override to specify a different style.
+        */
+       protected int getListStyle() {
+               int style = SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL;
+               if (fTableColumns != null) {
+                       style |= SWT.FULL_SELECTION;
+               }
+               return style;
+       }
+
+       protected TableViewer createTableViewer(Composite parent) {
+               Table table = new Table(parent, getListStyle());
+               return new TableViewer(table);
+       }
+
+       protected Button createButton(Composite parent, String label,
+                       SelectionListener listener) {
+               Button button = new Button(parent, SWT.PUSH);
+               button.setText(label);
+               button.addSelectionListener(listener);
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = true;
+               gd.verticalAlignment = GridData.BEGINNING;
+               gd.heightHint = SWTUtil.getButtonHeightHint(button);
+               gd.widthHint = SWTUtil.getButtonWidthHint(button);
+
+               button.setLayoutData(gd);
+               return button;
+       }
+
+       private Label createSeparator(Composite parent) {
+               Label separator = new Label(parent, SWT.NONE);
+               separator.setVisible(false);
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.verticalAlignment = GridData.BEGINNING;
+               gd.heightHint = 4;
+               separator.setLayoutData(gd);
+               return separator;
+       }
+
+       /**
+        * Returns the composite containing the buttons. When called the first time,
+        * the control will be created.
+        * 
+        * @param The
+        *            parent composite when called the first time, or
+        *            <code>null</code> after.
+        */
+       public Composite getButtonBox(Composite parent) {
+               if (fButtonsControl == null) {
+                       assertCompositeNotNull(parent);
+
+                       SelectionListener listener = new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       doButtonSelected(e);
+                               }
+
+                               public void widgetSelected(SelectionEvent e) {
+                                       doButtonSelected(e);
+                               }
+                       };
+
+                       Composite contents = new Composite(parent, SWT.NULL);
+                       GridLayout layout = new GridLayout();
+                       layout.marginWidth = 0;
+                       layout.marginHeight = 0;
+                       contents.setLayout(layout);
+
+                       if (fButtonLabels != null) {
+                               fButtonControls = new Button[fButtonLabels.length];
+                               for (int i = 0; i < fButtonLabels.length; i++) {
+                                       String currLabel = fButtonLabels[i];
+                                       if (currLabel != null) {
+                                               fButtonControls[i] = createButton(contents, currLabel,
+                                                               listener);
+                                               fButtonControls[i].setEnabled(isEnabled()
+                                                               && fButtonsEnabled[i]);
+                                       } else {
+                                               fButtonControls[i] = null;
+                                               createSeparator(contents);
+                                       }
+                               }
+                       }
+
+                       fLastSeparator = createSeparator(contents);
+
+                       updateButtonState();
+                       fButtonsControl = contents;
+               }
+
+               return fButtonsControl;
+       }
+
+       private void doButtonSelected(SelectionEvent e) {
+               if (fButtonControls != null) {
+                       for (int i = 0; i < fButtonControls.length; i++) {
+                               if (e.widget == fButtonControls[i]) {
+                                       buttonPressed(i);
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Handles key events in the table viewer. Specifically when the delete key
+        * is pressed.
+        */
+       protected void handleKeyPressed(KeyEvent event) {
+               if (event.character == SWT.DEL && event.stateMask == 0) {
+                       if (fRemoveButtonIndex != -1
+                                       && isButtonEnabled(fTable.getSelection(),
+                                                       fRemoveButtonIndex)) {
+                               managedButtonPressed(fRemoveButtonIndex);
+                       }
+               }
+       }
+
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#dialogFieldChanged
+        */
+       public void dialogFieldChanged() {
+               super.dialogFieldChanged();
+               updateButtonState();
+       }
+
+       /*
+        * Updates the enable state of the all buttons
+        */
+       protected void updateButtonState() {
+               if (fButtonControls != null) {
+                       ISelection sel = fTable.getSelection();
+                       for (int i = 0; i < fButtonControls.length; i++) {
+                               Button button = fButtonControls[i];
+                               if (isOkToUse(button)) {
+                                       button.setEnabled(isButtonEnabled(sel, i));
+                               }
+                       }
+               }
+       }
+
+       protected boolean getManagedButtonState(ISelection sel, int index) {
+               if (index == fRemoveButtonIndex) {
+                       return !sel.isEmpty();
+               } else if (index == fUpButtonIndex) {
+                       return !sel.isEmpty() && canMoveUp();
+               } else if (index == fDownButtonIndex) {
+                       return !sel.isEmpty() && canMoveDown();
+               }
+               return true;
+       }
+
+       /*
+        * @see DialogField#updateEnableState
+        */
+       protected void updateEnableState() {
+               super.updateEnableState();
+
+               boolean enabled = isEnabled();
+               if (isOkToUse(fTableControl)) {
+                       if (!enabled) {
+                               fSelectionWhenEnabled = fTable.getSelection();
+                               selectElements(null);
+                       } else {
+                               selectElements(fSelectionWhenEnabled);
+                               fSelectionWhenEnabled = null;
+                       }
+                       fTableControl.setEnabled(enabled);
+               }
+               updateButtonState();
+       }
+
+       /**
+        * Sets a button enabled or disabled.
+        */
+       public void enableButton(int index, boolean enable) {
+               if (fButtonsEnabled != null && index < fButtonsEnabled.length) {
+                       fButtonsEnabled[index] = enable;
+                       updateButtonState();
+               }
+       }
+
+       private boolean isButtonEnabled(ISelection sel, int index) {
+               boolean extraState = getManagedButtonState(sel, index);
+               return isEnabled() && extraState && fButtonsEnabled[index];
+       }
+
+       // ------ model access
+
+       /**
+        * Sets the elements shown in the list.
+        */
+       public void setElements(List elements) {
+               fElements = new ArrayList(elements);
+               if (fTable != null) {
+                       fTable.refresh();
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+        * Gets the elements shown in the list. The list returned is a copy, so it
+        * can be modified by the user.
+        */
+       public List getElements() {
+               return new ArrayList(fElements);
+       }
+
+       /**
+        * Gets the elements shown at the given index.
+        */
+       public Object getElement(int index) {
+               return fElements.get(index);
+       }
+
+       /**
+        * Gets the index of an element in the list or -1 if element is not in list.
+        */
+       public int getIndexOfElement(Object elem) {
+               return fElements.indexOf(elem);
+       }
+
+       /**
+        * Replace an element.
+        */
+       public void replaceElement(Object oldElement, Object newElement)
+                       throws IllegalArgumentException {
+               int idx = fElements.indexOf(oldElement);
+               if (idx != -1) {
+                       fElements.set(idx, newElement);
+                       if (fTable != null) {
+                               List selected = getSelectedElements();
+                               if (selected.remove(oldElement)) {
+                                       selected.add(newElement);
+                               }
+                               fTable.refresh();
+                               selectElements(new StructuredSelection(selected));
+                       }
+                       dialogFieldChanged();
+               } else {
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       /**
+        * Adds an element at the end of the list.
+        */
+       public void addElement(Object element) {
+               if (fElements.contains(element)) {
+                       return;
+               }
+               fElements.add(element);
+               if (fTable != null) {
+                       fTable.add(element);
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+        * Adds elements at the end of the list.
+        */
+       public void addElements(List elements) {
+               int nElements = elements.size();
+
+               if (nElements > 0) {
+                       // filter duplicated
+                       ArrayList elementsToAdd = new ArrayList(nElements);
+
+                       for (int i = 0; i < nElements; i++) {
+                               Object elem = elements.get(i);
+                               if (!fElements.contains(elem)) {
+                                       elementsToAdd.add(elem);
+                               }
+                       }
+                       fElements.addAll(elementsToAdd);
+                       if (fTable != null) {
+                               fTable.add(elementsToAdd.toArray());
+                       }
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Adds an element at a position.
+        */
+       public void insertElementAt(Object element, int index) {
+               if (fElements.contains(element)) {
+                       return;
+               }
+               fElements.add(index, element);
+               if (fTable != null) {
+                       fTable.add(element);
+               }
+
+               dialogFieldChanged();
+       }
+
+       /**
+        * Adds an element at a position.
+        */
+       public void removeAllElements() {
+               if (fElements.size() > 0) {
+                       fElements.clear();
+                       if (fTable != null) {
+                               fTable.refresh();
+                       }
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Removes an element from the list.
+        */
+       public void removeElement(Object element) throws IllegalArgumentException {
+               if (fElements.remove(element)) {
+                       if (fTable != null) {
+                               fTable.remove(element);
+                       }
+                       dialogFieldChanged();
+               } else {
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       /**
+        * Removes elements from the list.
+        */
+       public void removeElements(List elements) {
+               if (elements.size() > 0) {
+                       fElements.removeAll(elements);
+                       if (fTable != null) {
+                               fTable.remove(elements.toArray());
+                       }
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Gets the number of elements
+        */
+       public int getSize() {
+               return fElements.size();
+       }
+
+       public void selectElements(ISelection selection) {
+               fSelectionWhenEnabled = selection;
+               if (fTable != null) {
+                       fTable.setSelection(selection, true);
+               }
+       }
+
+       public void selectFirstElement() {
+               Object element = null;
+               if (fViewerSorter != null) {
+                       Object[] arr = fElements.toArray();
+                       fViewerSorter.sort(fTable, arr);
+                       if (arr.length > 0) {
+                               element = arr[0];
+                       }
+               } else {
+                       if (fElements.size() > 0) {
+                               element = fElements.get(0);
+                       }
+               }
+               if (element != null) {
+                       selectElements(new StructuredSelection(element));
+               }
+       }
+
+       public void postSetSelection(final ISelection selection) {
+               if (isOkToUse(fTableControl)) {
+                       Display d = fTableControl.getDisplay();
+                       d.asyncExec(new Runnable() {
+                               public void run() {
+                                       if (isOkToUse(fTableControl)) {
+                                               selectElements(selection);
+                                       }
+                               }
+                       });
+               }
+       }
+
+       /**
+        * Refreshes the table.
+        */
+       public void refresh() {
+               if (fTable != null) {
+                       fTable.refresh();
+               }
+       }
+
+       // ------- list maintenance
+
+       private List moveUp(List elements, List move) {
+               int nElements = elements.size();
+               List res = new ArrayList(nElements);
+               Object floating = null;
+               for (int i = 0; i < nElements; i++) {
+                       Object curr = elements.get(i);
+                       if (move.contains(curr)) {
+                               res.add(curr);
+                       } else {
+                               if (floating != null) {
+                                       res.add(floating);
+                               }
+                               floating = curr;
+                       }
+               }
+               if (floating != null) {
+                       res.add(floating);
+               }
+               return res;
+       }
+
+       private void moveUp(List toMoveUp) {
+               if (toMoveUp.size() > 0) {
+                       setElements(moveUp(fElements, toMoveUp));
+                       fTable.reveal(toMoveUp.get(0));
+               }
+       }
+
+       private void moveDown(List toMoveDown) {
+               if (toMoveDown.size() > 0) {
+                       setElements(reverse(moveUp(reverse(fElements), toMoveDown)));
+                       fTable.reveal(toMoveDown.get(toMoveDown.size() - 1));
+               }
+       }
+
+       private List reverse(List p) {
+               List reverse = new ArrayList(p.size());
+               for (int i = p.size() - 1; i >= 0; i--) {
+                       reverse.add(p.get(i));
+               }
+               return reverse;
+       }
+
+       private void remove() {
+               removeElements(getSelectedElements());
+       }
+
+       private void up() {
+               moveUp(getSelectedElements());
+       }
+
+       private void down() {
+               moveDown(getSelectedElements());
+       }
+
+       private boolean canMoveUp() {
+               if (isOkToUse(fTableControl)) {
+                       int[] indc = fTable.getTable().getSelectionIndices();
+                       for (int i = 0; i < indc.length; i++) {
+                               if (indc[i] != i) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       private boolean canMoveDown() {
+               if (isOkToUse(fTableControl)) {
+                       int[] indc = fTable.getTable().getSelectionIndices();
+                       int k = fElements.size() - 1;
+                       for (int i = indc.length - 1; i >= 0; i--, k--) {
+                               if (indc[i] != k) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Returns the selected elements.
+        */
+       public List getSelectedElements() {
+               List result = new ArrayList();
+               if (fTable != null) {
+                       ISelection selection = fTable.getSelection();
+                       if (selection instanceof IStructuredSelection) {
+                               Iterator iter = ((IStructuredSelection) selection).iterator();
+                               while (iter.hasNext()) {
+                                       result.add(iter.next());
+                               }
+                       }
+               }
+               return result;
+       }
+
+       // ------- ListViewerAdapter
+
+       private class ListViewerAdapter implements IStructuredContentProvider,
+                       ISelectionChangedListener, IDoubleClickListener {
+
+               // ------- ITableContentProvider Interface ------------
+
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+                       // will never happen
+               }
+
+               public boolean isDeleted(Object element) {
+                       return false;
+               }
+
+               public void dispose() {
+               }
+
+               public Object[] getElements(Object obj) {
+                       return fElements.toArray();
+               }
+
+               // ------- ISelectionChangedListener Interface ------------
+
+               public void selectionChanged(SelectionChangedEvent event) {
+                       doListSelected(event);
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
+                */
+               public void doubleClick(DoubleClickEvent event) {
+                       doDoubleClick(event);
+               }
+
+       }
+
+       protected void doListSelected(SelectionChangedEvent event) {
+               updateButtonState();
+               if (fListAdapter != null) {
+                       fListAdapter.selectionChanged(this);
+               }
+       }
+
+       protected void doDoubleClick(DoubleClickEvent event) {
+               if (fListAdapter != null) {
+                       fListAdapter.doubleClicked(this);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogField.java
new file mode 100644 (file)
index 0000000..57b9cd2
--- /dev/null
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+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.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Dialog Field containing a single button such as a radio or checkbox button.
+ */
+public class SelectionButtonDialogField extends DialogField {
+
+       private Button fButton;
+
+       private boolean fIsSelected;
+
+       private DialogField[] fAttachedDialogFields;
+
+       private int fButtonStyle;
+
+       /**
+        * Creates a selection button. Allowed button styles: SWT.RADIO, SWT.CHECK,
+        * SWT.TOGGLE, SWT.PUSH
+        */
+       public SelectionButtonDialogField(int buttonStyle) {
+               super();
+               fIsSelected = false;
+               fAttachedDialogFields = null;
+               fButtonStyle = buttonStyle;
+       }
+
+       /**
+        * Attaches a field to the selection state of the selection button. The
+        * attached field will be disabled if the selection button is not selected.
+        */
+       public void attachDialogField(DialogField dialogField) {
+               attachDialogFields(new DialogField[] { dialogField });
+       }
+
+       /**
+        * Attaches fields to the selection state of the selection button. The
+        * attached fields will be disabled if the selection button is not selected.
+        */
+       public void attachDialogFields(DialogField[] dialogFields) {
+               fAttachedDialogFields = dialogFields;
+               for (int i = 0; i < dialogFields.length; i++) {
+                       dialogFields[i].setEnabled(fIsSelected);
+               }
+       }
+
+       /**
+        * Returns <code>true</code> is teh gived field is attached to the
+        * selection button.
+        */
+       public boolean isAttached(DialogField editor) {
+               if (fAttachedDialogFields != null) {
+                       for (int i = 0; i < fAttachedDialogFields.length; i++) {
+                               if (fAttachedDialogFields[i] == editor) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       // ------- layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+
+               Button button = getSelectionButton(parent);
+               GridData gd = new GridData();
+               gd.horizontalSpan = nColumns;
+               gd.horizontalAlignment = GridData.FILL;
+               if (fButtonStyle == SWT.PUSH) {
+                       gd.heightHint = SWTUtil.getButtonHeightHint(button);
+                       gd.widthHint = SWTUtil.getButtonWidthHint(button);
+               }
+
+               button.setLayoutData(gd);
+
+               return new Control[] { button };
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 1;
+       }
+
+       // ------- ui creation
+
+       /**
+        * Returns the selection button widget. When called the first time, the
+        * widget will be created.
+        * 
+        * @param The
+        *            parent composite when called the first time, or
+        *            <code>null</code> after.
+        */
+       public Button getSelectionButton(Composite group) {
+               if (fButton == null) {
+                       assertCompositeNotNull(group);
+
+                       fButton = new Button(group, fButtonStyle);
+                       fButton.setFont(group.getFont());
+                       fButton.setText(fLabelText);
+                       fButton.setEnabled(isEnabled());
+                       fButton.setSelection(fIsSelected);
+                       fButton.addSelectionListener(new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       doWidgetSelected(e);
+                               }
+
+                               public void widgetSelected(SelectionEvent e) {
+                                       doWidgetSelected(e);
+                               }
+                       });
+               }
+               return fButton;
+       }
+
+       private void doWidgetSelected(SelectionEvent e) {
+               if (isOkToUse(fButton)) {
+                       changeValue(fButton.getSelection());
+               }
+       }
+
+       private void changeValue(boolean newState) {
+               if (fIsSelected != newState) {
+                       fIsSelected = newState;
+                       if (fAttachedDialogFields != null) {
+                               boolean focusSet = false;
+                               for (int i = 0; i < fAttachedDialogFields.length; i++) {
+                                       fAttachedDialogFields[i].setEnabled(fIsSelected);
+                                       if (fIsSelected && !focusSet) {
+                                               focusSet = fAttachedDialogFields[i].setFocus();
+                                       }
+                               }
+                       }
+                       dialogFieldChanged();
+               } else if (fButtonStyle == SWT.PUSH) {
+                       dialogFieldChanged();
+               }
+       }
+
+       // ------ model access
+
+       /**
+        * Returns the selection state of the button.
+        */
+       public boolean isSelected() {
+               return fIsSelected;
+       }
+
+       /**
+        * Sets the selection state of the button.
+        */
+       public void setSelection(boolean selected) {
+               changeValue(selected);
+               if (isOkToUse(fButton)) {
+                       fButton.setSelection(selected);
+               }
+       }
+
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#updateEnableState
+        */
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (isOkToUse(fButton)) {
+                       fButton.setEnabled(isEnabled());
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogFieldGroup.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogFieldGroup.java
new file mode 100644 (file)
index 0000000..2655aa8
--- /dev/null
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.jface.util.Assert;
+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.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;
+
+/**
+ * Dialog field describing a group with buttons (Checkboxes, radio buttons..)
+ */
+public class SelectionButtonDialogFieldGroup extends DialogField {
+
+       private Composite fButtonComposite;
+
+       private Button[] fButtons;
+
+       private String[] fButtonNames;
+
+       private boolean[] fButtonsSelected;
+
+       private boolean[] fButtonsEnabled;
+
+       private int fGroupBorderStyle;
+
+       private int fGroupNumberOfColumns;
+
+       private int fButtonsStyle;
+
+       /**
+        * Creates a group without border.
+        */
+       public SelectionButtonDialogFieldGroup(int buttonsStyle,
+                       String[] buttonNames, int nColumns) {
+               this(buttonsStyle, buttonNames, nColumns, SWT.NONE);
+       }
+
+       /**
+        * Creates a group with border (label in border). Accepted button styles
+        * are: SWT.RADIO, SWT.CHECK, SWT.TOGGLE For border styles see
+        * <code>Group</code>
+        */
+       public SelectionButtonDialogFieldGroup(int buttonsStyle,
+                       String[] buttonNames, int nColumns, int borderStyle) {
+               super();
+
+               Assert.isTrue(buttonsStyle == SWT.RADIO || buttonsStyle == SWT.CHECK
+                               || buttonsStyle == SWT.TOGGLE);
+               fButtonNames = buttonNames;
+
+               int nButtons = buttonNames.length;
+               fButtonsSelected = new boolean[nButtons];
+               fButtonsEnabled = new boolean[nButtons];
+               for (int i = 0; i < nButtons; i++) {
+                       fButtonsSelected[i] = false;
+                       fButtonsEnabled[i] = true;
+               }
+               if (fButtonsStyle == SWT.RADIO) {
+                       fButtonsSelected[0] = true;
+               }
+
+               fGroupBorderStyle = borderStyle;
+               fGroupNumberOfColumns = (nColumns <= 0) ? nButtons : nColumns;
+
+               fButtonsStyle = buttonsStyle;
+
+       }
+
+       // ------- layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+
+               if (fGroupBorderStyle == SWT.NONE) {
+                       Label label = getLabelControl(parent);
+                       label.setLayoutData(gridDataForLabel(1));
+
+                       Composite buttonsgroup = getSelectionButtonsGroup(parent);
+                       GridData gd = new GridData();
+                       gd.horizontalSpan = nColumns - 1;
+                       buttonsgroup.setLayoutData(gd);
+
+                       return new Control[] { label, buttonsgroup };
+               } else {
+                       Composite buttonsgroup = getSelectionButtonsGroup(parent);
+                       GridData gd = new GridData();
+                       gd.horizontalSpan = nColumns;
+                       buttonsgroup.setLayoutData(gd);
+
+                       return new Control[] { buttonsgroup };
+               }
+       }
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public int getNumberOfControls() {
+               return (fGroupBorderStyle == SWT.NONE) ? 2 : 1;
+       }
+
+       // ------- ui creation
+
+       private Button createSelectionButton(int index, Composite group,
+                       SelectionListener listener) {
+               Button button = new Button(group, fButtonsStyle | SWT.LEFT);
+               button.setFont(group.getFont());
+               button.setText(fButtonNames[index]);
+               button.setEnabled(isEnabled() && fButtonsEnabled[index]);
+               button.setSelection(fButtonsSelected[index]);
+               button.addSelectionListener(listener);
+               button.setLayoutData(new GridData());
+               return button;
+       }
+
+       /**
+        * Returns the group widget. When called the first time, the widget will be
+        * created.
+        * 
+        * @param The
+        *            parent composite when called the first time, or
+        *            <code>null</code> after.
+        */
+       public Composite getSelectionButtonsGroup(Composite parent) {
+               if (fButtonComposite == null) {
+                       assertCompositeNotNull(parent);
+
+                       GridLayout layout = new GridLayout();
+                       layout.makeColumnsEqualWidth = true;
+                       layout.numColumns = fGroupNumberOfColumns;
+
+                       if (fGroupBorderStyle != SWT.NONE) {
+                               Group group = new Group(parent, fGroupBorderStyle);
+                               if (fLabelText != null && fLabelText.length() > 0) {
+                                       group.setText(fLabelText);
+                               }
+                               fButtonComposite = group;
+                       } else {
+                               fButtonComposite = new Composite(parent, SWT.NULL);
+                               layout.marginHeight = 0;
+                               layout.marginWidth = 0;
+                       }
+
+                       fButtonComposite.setLayout(layout);
+
+                       SelectionListener listener = new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       doWidgetSelected(e);
+                               }
+
+                               public void widgetSelected(SelectionEvent e) {
+                                       doWidgetSelected(e);
+                               }
+                       };
+                       int nButtons = fButtonNames.length;
+                       fButtons = new Button[nButtons];
+                       for (int i = 0; i < nButtons; i++) {
+                               fButtons[i] = createSelectionButton(i, fButtonComposite,
+                                               listener);
+                       }
+                       int nRows = nButtons / fGroupNumberOfColumns;
+                       int nFillElements = nRows * fGroupNumberOfColumns - nButtons;
+                       for (int i = 0; i < nFillElements; i++) {
+                               createEmptySpace(fButtonComposite);
+                       }
+               }
+               return fButtonComposite;
+       }
+
+       /**
+        * Returns a button from the group or <code>null</code> if not yet
+        * created.
+        */
+       public Button getSelectionButton(int index) {
+               if (index >= 0 && index < fButtons.length) {
+                       return fButtons[index];
+               }
+               return null;
+       }
+
+       private void doWidgetSelected(SelectionEvent e) {
+               Button button = (Button) e.widget;
+               for (int i = 0; i < fButtons.length; i++) {
+                       if (fButtons[i] == button) {
+                               fButtonsSelected[i] = button.getSelection();
+                               dialogFieldChanged();
+                               return;
+                       }
+               }
+       }
+
+       // ------ model access
+
+       /**
+        * Returns the selection state of a button contained in the group.
+        * 
+        * @param The
+        *            index of the button
+        */
+       public boolean isSelected(int index) {
+               if (index >= 0 && index < fButtonsSelected.length) {
+                       return fButtonsSelected[index];
+               }
+               return false;
+       }
+
+       /**
+        * Sets the selection state of a button contained in the group.
+        */
+       public void setSelection(int index, boolean selected) {
+               if (index >= 0 && index < fButtonsSelected.length) {
+                       if (fButtonsSelected[index] != selected) {
+                               fButtonsSelected[index] = selected;
+                               if (fButtons != null) {
+                                       Button button = fButtons[index];
+                                       if (isOkToUse(button)) {
+                                               button.setSelection(selected);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // ------ enable / disable management
+
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (fButtons != null) {
+                       boolean enabled = isEnabled();
+                       for (int i = 0; i < fButtons.length; i++) {
+                               Button button = fButtons[i];
+                               if (isOkToUse(button)) {
+                                       button.setEnabled(enabled && fButtonsEnabled[i]);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Sets the enable state of a button contained in the group.
+        */
+       public void enableSelectionButton(int index, boolean enable) {
+               if (index >= 0 && index < fButtonsEnabled.length) {
+                       fButtonsEnabled[index] = enable;
+                       if (fButtons != null) {
+                               Button button = fButtons[index];
+                               if (isOkToUse(button)) {
+                                       button.setEnabled(isEnabled() && enable);
+                               }
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/Separator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/Separator.java
new file mode 100644 (file)
index 0000000..ea736b9
--- /dev/null
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+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.Label;
+
+/**
+ * Dialog field describing a separator.
+ */
+public class Separator extends DialogField {
+
+       private Label fSeparator;
+
+       private int fStyle;
+
+       public Separator() {
+               this(SWT.NONE);
+       }
+
+       /**
+        * @param style
+        *            of the separator. See <code>Label</code> for possible
+        *            styles.
+        */
+       public Separator(int style) {
+               super();
+               fStyle = style;
+       }
+
+       // ------- layout helpers
+
+       /**
+        * Creates the separator and fills it in a MGridLayout.
+        * 
+        * @param height
+        *            The heigth of the separator
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns, int height) {
+               assertEnoughColumns(nColumns);
+
+               Control separator = getSeparator(parent);
+               separator.setLayoutData(gridDataForSeperator(nColumns, height));
+
+               return new Control[] { separator };
+       }
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               return doFillIntoGrid(parent, nColumns, 4);
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 1;
+       }
+
+       protected static GridData gridDataForSeperator(int span, int height) {
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.verticalAlignment = GridData.BEGINNING;
+               gd.heightHint = height;
+               gd.horizontalSpan = span;
+               return gd;
+       }
+
+       // ------- ui creation
+
+       /**
+        * Creates or returns the created separator.
+        * 
+        * @param parent
+        *            The parent composite or <code>null</code> if the widget has
+        *            already been created.
+        */
+       public Control getSeparator(Composite parent) {
+               if (fSeparator == null) {
+                       assertCompositeNotNull(parent);
+                       fSeparator = new Label(parent, fStyle);
+               }
+               return fSeparator;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonDialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonDialogField.java
new file mode 100644 (file)
index 0000000..aa06105
--- /dev/null
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+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.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Dialog field containing a label, text control and a button control.
+ */
+public class StringButtonDialogField extends StringDialogField {
+
+       private Button fBrowseButton;
+
+       private String fBrowseButtonLabel;
+
+       private IStringButtonAdapter fStringButtonAdapter;
+
+       private boolean fButtonEnabled;
+
+       public StringButtonDialogField(IStringButtonAdapter adapter) {
+               super();
+               fStringButtonAdapter = adapter;
+               fBrowseButtonLabel = "!Browse...!"; //$NON-NLS-1$
+               fButtonEnabled = true;
+       }
+
+       /**
+        * Sets the label of the button.
+        */
+       public void setButtonLabel(String label) {
+               fBrowseButtonLabel = label;
+       }
+
+       // ------ adapter communication
+
+       /**
+        * Programmatical pressing of the button
+        */
+       public void changeControlPressed() {
+               fStringButtonAdapter.changeControlPressed(this);
+       }
+
+       // ------- layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+
+               Label label = getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(1));
+               Text text = getTextControl(parent);
+               text.setLayoutData(gridDataForText(nColumns - 2));
+               Button button = getChangeControl(parent);
+               button.setLayoutData(gridDataForButton(button, 1));
+
+               return new Control[] { label, text, button };
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 3;
+       }
+
+       protected static GridData gridDataForButton(Button button, int span) {
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = false;
+               gd.horizontalSpan = span;
+               gd.heightHint = SWTUtil.getButtonHeightHint(button);
+               gd.widthHint = SWTUtil.getButtonWidthHint(button);
+               return gd;
+       }
+
+       // ------- ui creation
+
+       /**
+        * Creates or returns the created buttom widget.
+        * 
+        * @param parent
+        *            The parent composite or <code>null</code> if the widget has
+        *            already been created.
+        */
+       public Button getChangeControl(Composite parent) {
+               if (fBrowseButton == null) {
+                       assertCompositeNotNull(parent);
+
+                       fBrowseButton = new Button(parent, SWT.PUSH);
+                       fBrowseButton.setText(fBrowseButtonLabel);
+                       fBrowseButton.setEnabled(isEnabled() && fButtonEnabled);
+                       fBrowseButton.addSelectionListener(new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       changeControlPressed();
+                               }
+
+                               public void widgetSelected(SelectionEvent e) {
+                                       changeControlPressed();
+                               }
+                       });
+
+               }
+               return fBrowseButton;
+       }
+
+       // ------ enable / disable management
+
+       /**
+        * Sets the enable state of the button.
+        */
+       public void enableButton(boolean enable) {
+               if (isOkToUse(fBrowseButton)) {
+                       fBrowseButton.setEnabled(isEnabled() && enable);
+               }
+               fButtonEnabled = enable;
+       }
+
+       /*
+        * @see DialogField#updateEnableState
+        */
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (isOkToUse(fBrowseButton)) {
+                       fBrowseButton.setEnabled(isEnabled() && fButtonEnabled);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonStatusDialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonStatusDialogField.java
new file mode 100644 (file)
index 0000000..87fd7ea
--- /dev/null
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Dialog field containing a label, text control, status label and a button
+ * control. The status label can be either a image or text label, and can be usd
+ * to give additional information about the current element chosen.
+ */
+public class StringButtonStatusDialogField extends StringButtonDialogField {
+
+       private Label fStatusLabelControl;
+
+       private Object fStatus; // String or ImageDescriptor
+
+       private String fWidthHintString;
+
+       private int fWidthHint;
+
+       public StringButtonStatusDialogField(IStringButtonAdapter adapter) {
+               super(adapter);
+               fStatus = null;
+               fWidthHintString = null;
+               fWidthHint = -1;
+       }
+
+       // ------ set status
+
+       /**
+        * Sets the status string.
+        */
+       public void setStatus(String status) {
+               if (isOkToUse(fStatusLabelControl)) {
+                       fStatusLabelControl.setText(status);
+               }
+               fStatus = status;
+       }
+
+       /**
+        * Sets the status image. Caller is responsible to dispose image
+        */
+       public void setStatus(Image image) {
+               if (isOkToUse(fStatusLabelControl)) {
+                       if (image == null) {
+                               fStatusLabelControl.setImage(null);
+                       } else {
+                               fStatusLabelControl.setImage(image);
+                       }
+               }
+               fStatus = image;
+       }
+
+       /**
+        * Sets the staus string hint of the status label. The string is used to
+        * calculate the size of the status label.
+        */
+       public void setStatusWidthHint(String widthHintString) {
+               fWidthHintString = widthHintString;
+               fWidthHint = -1;
+       }
+
+       /**
+        * Sets the width hint of the status label.
+        */
+       public void setStatusWidthHint(int widthHint) {
+               fWidthHint = widthHint;
+               fWidthHintString = null;
+       }
+
+       // ------- layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+
+               Label label = getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(1));
+               Text text = getTextControl(parent);
+               text.setLayoutData(gridDataForText(nColumns - 3));
+               Label status = getStatusLabelControl(parent);
+               status.setLayoutData(gridDataForStatusLabel(parent, 1));
+               Button button = getChangeControl(parent);
+               button.setLayoutData(gridDataForButton(button, 1));
+
+               return new Control[] { label, text, status, button };
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 4;
+       }
+
+       protected GridData gridDataForStatusLabel(Control aControl, int span) {
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.BEGINNING;
+               gd.grabExcessHorizontalSpace = false;
+               gd.horizontalIndent = 0;
+               if (fWidthHintString != null) {
+                       GC gc = new GC(aControl);
+                       gc.setFont(JFaceResources.getDialogFont());
+                       gd.widthHint = gc.textExtent(fWidthHintString).x;
+                       gc.dispose();
+               } else if (fWidthHint != -1) {
+                       gd.widthHint = fWidthHint;
+               } else {
+                       gd.widthHint = SWT.DEFAULT;
+               }
+               return gd;
+       }
+
+       // ------- ui creation
+
+       /**
+        * Creates or returns the created status label widget.
+        * 
+        * @param parent
+        *            The parent composite or <code>null</code> when the widget
+        *            has already been created.
+        */
+       public Label getStatusLabelControl(Composite parent) {
+               if (fStatusLabelControl == null) {
+                       assertCompositeNotNull(parent);
+                       fStatusLabelControl = new Label(parent, SWT.LEFT);
+                       fStatusLabelControl.setFont(parent.getFont());
+                       fStatusLabelControl.setEnabled(isEnabled());
+                       if (fStatus instanceof Image) {
+                               fStatusLabelControl.setImage((Image) fStatus);
+                       } else if (fStatus instanceof String) {
+                               fStatusLabelControl.setText((String) fStatus);
+                       } else {
+                               // must be null
+                       }
+               }
+               return fStatusLabelControl;
+       }
+
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#updateEnableState
+        */
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (isOkToUse(fStatusLabelControl)) {
+                       fStatusLabelControl.setEnabled(isEnabled());
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringDialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringDialogField.java
new file mode 100644 (file)
index 0000000..e43b145
--- /dev/null
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Dialog field containing a label and a text control.
+ */
+public class StringDialogField extends DialogField {
+
+       private String fText;
+
+       private Text fTextControl;
+
+       private ModifyListener fModifyListener;
+
+       public StringDialogField() {
+               super();
+               fText = ""; //$NON-NLS-1$
+       }
+
+       // ------- layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+
+               Label label = getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(1));
+               Text text = getTextControl(parent);
+               text.setLayoutData(gridDataForText(nColumns - 1));
+
+               return new Control[] { label, text };
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 2;
+       }
+
+       protected static GridData gridDataForText(int span) {
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = false;
+               gd.horizontalSpan = span;
+               return gd;
+       }
+
+       // ------- focus methods
+
+       /*
+        * @see DialogField#setFocus
+        */
+       public boolean setFocus() {
+               if (isOkToUse(fTextControl)) {
+                       fTextControl.setFocus();
+                       fTextControl.setSelection(0, fTextControl.getText().length());
+               }
+               return true;
+       }
+
+       // ------- ui creation
+
+       /**
+        * Creates or returns the created text control.
+        * 
+        * @param parent
+        *            The parent composite or <code>null</code> when the widget
+        *            has already been created.
+        */
+       public Text getTextControl(Composite parent) {
+               if (fTextControl == null) {
+                       assertCompositeNotNull(parent);
+                       fModifyListener = new ModifyListener() {
+                               public void modifyText(ModifyEvent e) {
+                                       doModifyText(e);
+                               }
+                       };
+
+                       fTextControl = new Text(parent, SWT.SINGLE | SWT.BORDER);
+                       // moved up due to 1GEUNW2
+                       fTextControl.setText(fText);
+                       fTextControl.setFont(parent.getFont());
+                       fTextControl.addModifyListener(fModifyListener);
+
+                       fTextControl.setEnabled(isEnabled());
+               }
+               return fTextControl;
+       }
+
+       private void doModifyText(ModifyEvent e) {
+               if (isOkToUse(fTextControl)) {
+                       fText = fTextControl.getText();
+               }
+               dialogFieldChanged();
+       }
+
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#updateEnableState
+        */
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (isOkToUse(fTextControl)) {
+                       fTextControl.setEnabled(isEnabled());
+               }
+       }
+
+       // ------ text access
+
+       /**
+        * Gets the text. Can not be <code>null</code>
+        */
+       public String getText() {
+               return fText;
+       }
+
+       /**
+        * Sets the text. Triggers a dialog-changed event.
+        */
+       public void setText(String text) {
+               fText = text;
+               if (isOkToUse(fTextControl)) {
+                       fTextControl.setText(text);
+               } else {
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Sets the text without triggering a dialog-changed event.
+        */
+       public void setTextWithoutUpdate(String text) {
+               fText = text;
+               if (isOkToUse(fTextControl)) {
+                       fTextControl.removeModifyListener(fModifyListener);
+                       fTextControl.setText(text);
+                       fTextControl.addModifyListener(fModifyListener);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/TreeListDialogField.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/TreeListDialogField.java
new file mode 100644 (file)
index 0000000..8bed2ad
--- /dev/null
@@ -0,0 +1,922 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+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.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * A list with a button bar. Typical buttons are 'Add', 'Remove', 'Up' and
+ * 'Down'. List model is independend of widget creation. DialogFields controls
+ * are: Label, List and Composite containing buttons.
+ */
+public class TreeListDialogField extends DialogField {
+
+       protected TreeViewer fTree;
+
+       protected ILabelProvider fLabelProvider;
+
+       protected TreeViewerAdapter fTreeViewerAdapter;
+
+       protected List fElements;
+
+       protected ViewerSorter fViewerSorter;
+
+       protected String[] fButtonLabels;
+
+       private Button[] fButtonControls;
+
+       private boolean[] fButtonsEnabled;
+
+       private int fRemoveButtonIndex;
+
+       private int fUpButtonIndex;
+
+       private int fDownButtonIndex;
+
+       private Label fLastSeparator;
+
+       private Tree fTreeControl;
+
+       private Composite fButtonsControl;
+
+       private ISelection fSelectionWhenEnabled;
+
+       private ITreeListAdapter fTreeAdapter;
+
+       private Object fParentElement;
+
+       private int fTreeExpandLevel;
+
+       /**
+        * @param adapter
+        *            Can be <code>null</code>.
+        */
+       public TreeListDialogField(ITreeListAdapter adapter, String[] buttonLabels,
+                       ILabelProvider lprovider) {
+               super();
+               fTreeAdapter = adapter;
+
+               fLabelProvider = lprovider;
+               fTreeViewerAdapter = new TreeViewerAdapter();
+               fParentElement = this;
+
+               fElements = new ArrayList(10);
+
+               fButtonLabels = buttonLabels;
+               if (fButtonLabels != null) {
+                       int nButtons = fButtonLabels.length;
+                       fButtonsEnabled = new boolean[nButtons];
+                       for (int i = 0; i < nButtons; i++) {
+                               fButtonsEnabled[i] = true;
+                       }
+               }
+
+               fTree = null;
+               fTreeControl = null;
+               fButtonsControl = null;
+
+               fRemoveButtonIndex = -1;
+               fUpButtonIndex = -1;
+               fDownButtonIndex = -1;
+
+               fTreeExpandLevel = 0;
+       }
+
+       /**
+        * Sets the index of the 'remove' button in the button label array passed in
+        * the constructor. The behaviour of the button marked as the 'remove'
+        * button will then behandled internally. (enable state, button invocation
+        * behaviour)
+        */
+       public void setRemoveButtonIndex(int removeButtonIndex) {
+               Assert.isTrue(removeButtonIndex < fButtonLabels.length);
+               fRemoveButtonIndex = removeButtonIndex;
+       }
+
+       /**
+        * Sets the index of the 'up' button in the button label array passed in the
+        * constructor. The behaviour of the button marked as the 'up' button will
+        * then behandled internally. (enable state, button invocation behaviour)
+        */
+       public void setUpButtonIndex(int upButtonIndex) {
+               Assert.isTrue(upButtonIndex < fButtonLabels.length);
+               fUpButtonIndex = upButtonIndex;
+       }
+
+       /**
+        * Sets the index of the 'down' button in the button label array passed in
+        * the constructor. The behaviour of the button marked as the 'down' button
+        * will then be handled internally. (enable state, button invocation
+        * behaviour)
+        */
+       public void setDownButtonIndex(int downButtonIndex) {
+               Assert.isTrue(downButtonIndex < fButtonLabels.length);
+               fDownButtonIndex = downButtonIndex;
+       }
+
+       /**
+        * Sets the viewerSorter.
+        * 
+        * @param viewerSorter
+        *            The viewerSorter to set
+        */
+       public void setViewerSorter(ViewerSorter viewerSorter) {
+               fViewerSorter = viewerSorter;
+       }
+
+       /**
+        * Sets the viewerSorter.
+        * 
+        * @param viewerSorter
+        *            The viewerSorter to set
+        */
+       public void setTreeExpansionLevel(int level) {
+               fTreeExpandLevel = level;
+               if (fTree != null) {
+                       fTree.expandToLevel(level);
+               }
+       }
+
+       // ------ adapter communication
+
+       private void buttonPressed(int index) {
+               if (!managedButtonPressed(index) && fTreeAdapter != null) {
+                       fTreeAdapter.customButtonPressed(this, index);
+               }
+       }
+
+       /**
+        * Checks if the button pressed is handled internally
+        * 
+        * @return Returns true if button has been handled.
+        */
+       protected boolean managedButtonPressed(int index) {
+               if (index == fRemoveButtonIndex) {
+                       remove();
+               } else if (index == fUpButtonIndex) {
+                       up();
+               } else if (index == fDownButtonIndex) {
+                       down();
+               } else {
+                       return false;
+               }
+               return true;
+       }
+
+       // ------ layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               PixelConverter converter = new PixelConverter(parent);
+
+               assertEnoughColumns(nColumns);
+
+               Label label = getLabelControl(parent);
+               GridData gd = gridDataForLabel(1);
+               gd.verticalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gd);
+
+               Control list = getTreeControl(parent);
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = false;
+               gd.verticalAlignment = GridData.FILL;
+               gd.grabExcessVerticalSpace = true;
+               gd.horizontalSpan = nColumns - 2;
+               gd.widthHint = converter.convertWidthInCharsToPixels(50);
+               gd.heightHint = converter.convertHeightInCharsToPixels(6);
+
+               list.setLayoutData(gd);
+
+               Composite buttons = getButtonBox(parent);
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = false;
+               gd.verticalAlignment = GridData.FILL;
+               gd.grabExcessVerticalSpace = true;
+               gd.horizontalSpan = 1;
+               buttons.setLayoutData(gd);
+
+               return new Control[] { label, list, buttons };
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 3;
+       }
+
+       /**
+        * Sets the minimal width of the buttons. Must be called after widget
+        * creation.
+        */
+       public void setButtonsMinWidth(int minWidth) {
+               if (fLastSeparator != null) {
+                       ((GridData) fLastSeparator.getLayoutData()).widthHint = minWidth;
+               }
+       }
+
+       // ------ ui creation
+
+       /**
+        * Returns the tree control. When called the first time, the control will be
+        * created.
+        * 
+        * @param The
+        *            parent composite when called the first time, or
+        *            <code>null</code> after.
+        */
+       public Control getTreeControl(Composite parent) {
+               if (fTreeControl == null) {
+                       assertCompositeNotNull(parent);
+
+                       fTree = createTreeViewer(parent);
+
+                       fTreeControl = (Tree) fTree.getControl();
+                       fTreeControl.addKeyListener(new KeyAdapter() {
+                               public void keyPressed(KeyEvent e) {
+                                       handleKeyPressed(e);
+                               }
+                       });
+                       fTree.setAutoExpandLevel(99);
+                       fTree.setContentProvider(fTreeViewerAdapter);
+                       fTree.setLabelProvider(fLabelProvider);
+                       fTree.addSelectionChangedListener(fTreeViewerAdapter);
+                       fTree.addDoubleClickListener(fTreeViewerAdapter);
+
+                       fTree.setInput(fParentElement);
+                       fTree.expandToLevel(fTreeExpandLevel);
+
+                       if (fViewerSorter != null) {
+                               fTree.setSorter(fViewerSorter);
+                       }
+
+                       fTreeControl.setEnabled(isEnabled());
+                       if (fSelectionWhenEnabled != null) {
+                               postSetSelection(fSelectionWhenEnabled);
+                       }
+               }
+               return fTreeControl;
+       }
+
+       /**
+        * Returns the internally used table viewer.
+        */
+       public TreeViewer getTreeViewer() {
+               return fTree;
+       }
+
+       /*
+        * Subclasses may override to specify a different style.
+        */
+       protected int getTreeStyle() {
+               int style = SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL;
+               return style;
+       }
+
+       protected TreeViewer createTreeViewer(Composite parent) {
+               Tree tree = new Tree(parent, getTreeStyle());
+               return new TreeViewer(tree);
+       }
+
+       protected Button createButton(Composite parent, String label,
+                       SelectionListener listener) {
+               Button button = new Button(parent, SWT.PUSH);
+               button.setText(label);
+               button.addSelectionListener(listener);
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.grabExcessHorizontalSpace = true;
+               gd.verticalAlignment = GridData.BEGINNING;
+               gd.heightHint = SWTUtil.getButtonHeightHint(button);
+               gd.widthHint = SWTUtil.getButtonWidthHint(button);
+
+               button.setLayoutData(gd);
+               return button;
+       }
+
+       private Label createSeparator(Composite parent) {
+               Label separator = new Label(parent, SWT.NONE);
+               separator.setVisible(false);
+               GridData gd = new GridData();
+               gd.horizontalAlignment = GridData.FILL;
+               gd.verticalAlignment = GridData.BEGINNING;
+               gd.heightHint = 4;
+               separator.setLayoutData(gd);
+               return separator;
+       }
+
+       /**
+        * Returns the composite containing the buttons. When called the first time,
+        * the control will be created.
+        * 
+        * @param The
+        *            parent composite when called the first time, or
+        *            <code>null</code> after.
+        */
+       public Composite getButtonBox(Composite parent) {
+               if (fButtonsControl == null) {
+                       assertCompositeNotNull(parent);
+
+                       SelectionListener listener = new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       doButtonSelected(e);
+                               }
+
+                               public void widgetSelected(SelectionEvent e) {
+                                       doButtonSelected(e);
+                               }
+                       };
+
+                       Composite contents = new Composite(parent, SWT.NULL);
+                       GridLayout layout = new GridLayout();
+                       layout.marginWidth = 0;
+                       layout.marginHeight = 0;
+                       contents.setLayout(layout);
+
+                       if (fButtonLabels != null) {
+                               fButtonControls = new Button[fButtonLabels.length];
+                               for (int i = 0; i < fButtonLabels.length; i++) {
+                                       String currLabel = fButtonLabels[i];
+                                       if (currLabel != null) {
+                                               fButtonControls[i] = createButton(contents, currLabel,
+                                                               listener);
+                                               fButtonControls[i].setEnabled(isEnabled()
+                                                               && fButtonsEnabled[i]);
+                                       } else {
+                                               fButtonControls[i] = null;
+                                               createSeparator(contents);
+                                       }
+                               }
+                       }
+
+                       fLastSeparator = createSeparator(contents);
+
+                       updateButtonState();
+                       fButtonsControl = contents;
+               }
+
+               return fButtonsControl;
+       }
+
+       private void doButtonSelected(SelectionEvent e) {
+               if (fButtonControls != null) {
+                       for (int i = 0; i < fButtonControls.length; i++) {
+                               if (e.widget == fButtonControls[i]) {
+                                       buttonPressed(i);
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Handles key events in the table viewer. Specifically when the delete key
+        * is pressed.
+        */
+       protected void handleKeyPressed(KeyEvent event) {
+               if (event.character == SWT.DEL && event.stateMask == 0) {
+                       if (fRemoveButtonIndex != -1
+                                       && isButtonEnabled(fTree.getSelection(), fRemoveButtonIndex)) {
+                               managedButtonPressed(fRemoveButtonIndex);
+                               return;
+                       }
+               }
+               fTreeAdapter.keyPressed(this, event);
+       }
+
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#dialogFieldChanged
+        */
+       public void dialogFieldChanged() {
+               super.dialogFieldChanged();
+               updateButtonState();
+       }
+
+       /*
+        * Updates the enable state of the all buttons
+        */
+       protected void updateButtonState() {
+               if (fButtonControls != null) {
+                       ISelection sel = fTree.getSelection();
+                       for (int i = 0; i < fButtonControls.length; i++) {
+                               Button button = fButtonControls[i];
+                               if (isOkToUse(button)) {
+                                       button.setEnabled(isButtonEnabled(sel, i));
+                               }
+                       }
+               }
+       }
+
+       protected boolean containsAttributes(List selected) {
+               for (int i = 0; i < selected.size(); i++) {
+                       if (!fElements.contains(selected.get(i))) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       protected boolean getManagedButtonState(ISelection sel, int index) {
+               List selected = getSelectedElements();
+               boolean hasAttributes = containsAttributes(selected);
+               if (index == fRemoveButtonIndex) {
+                       return !selected.isEmpty() && !hasAttributes;
+               } else if (index == fUpButtonIndex) {
+                       return !sel.isEmpty() && !hasAttributes && canMoveUp(selected);
+               } else if (index == fDownButtonIndex) {
+                       return !sel.isEmpty() && !hasAttributes && canMoveDown(selected);
+               }
+               return true;
+       }
+
+       /*
+        * @see DialogField#updateEnableState
+        */
+       protected void updateEnableState() {
+               super.updateEnableState();
+
+               boolean enabled = isEnabled();
+               if (isOkToUse(fTreeControl)) {
+                       if (!enabled) {
+                               fSelectionWhenEnabled = fTree.getSelection();
+                               selectElements(null);
+                       } else {
+                               selectElements(fSelectionWhenEnabled);
+                               fSelectionWhenEnabled = null;
+                       }
+                       fTreeControl.setEnabled(enabled);
+               }
+               updateButtonState();
+       }
+
+       /**
+        * Sets a button enabled or disabled.
+        */
+       public void enableButton(int index, boolean enable) {
+               if (fButtonsEnabled != null && index < fButtonsEnabled.length) {
+                       fButtonsEnabled[index] = enable;
+                       updateButtonState();
+               }
+       }
+
+       private boolean isButtonEnabled(ISelection sel, int index) {
+               boolean extraState = getManagedButtonState(sel, index);
+               return isEnabled() && extraState && fButtonsEnabled[index];
+       }
+
+       // ------ model access
+
+       /**
+        * Sets the elements shown in the list.
+        */
+       public void setElements(List elements) {
+               fElements = new ArrayList(elements);
+               refresh();
+               if (fTree != null) {
+                       fTree.expandToLevel(fTreeExpandLevel);
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+        * Gets the elements shown in the list. The list returned is a copy, so it
+        * can be modified by the user.
+        */
+       public List getElements() {
+               return new ArrayList(fElements);
+       }
+
+       /**
+        * Gets the element shown at the given index.
+        */
+       public Object getElement(int index) {
+               return fElements.get(index);
+       }
+
+       /**
+        * Gets the index of an element in the list or -1 if element is not in list.
+        */
+       public int getIndexOfElement(Object elem) {
+               return fElements.indexOf(elem);
+       }
+
+       /**
+        * Replace an element.
+        */
+       public void replaceElement(Object oldElement, Object newElement)
+                       throws IllegalArgumentException {
+               int idx = fElements.indexOf(oldElement);
+               if (idx != -1) {
+                       fElements.set(idx, newElement);
+                       if (fTree != null) {
+                               List selected = getSelectedElements();
+                               if (selected.remove(oldElement)) {
+                                       selected.add(newElement);
+                               }
+                               boolean isExpanded = fTree.getExpandedState(oldElement);
+                               fTree.remove(oldElement);
+                               fTree.add(fParentElement, newElement);
+                               if (isExpanded) {
+                                       fTree.expandToLevel(newElement, fTreeExpandLevel);
+                               }
+                               selectElements(new StructuredSelection(selected));
+                       }
+                       dialogFieldChanged();
+               } else {
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       /**
+        * Adds an element at the end of the tree list.
+        */
+       public void addElement(Object element) {
+               if (fElements.contains(element)) {
+                       return;
+               }
+               fElements.add(element);
+               if (fTree != null) {
+                       fTree.add(fParentElement, element);
+                       fTree.expandToLevel(element, fTreeExpandLevel);
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+        * Adds elements at the end of the tree list.
+        */
+       public void addElements(List elements) {
+               int nElements = elements.size();
+
+               if (nElements > 0) {
+                       // filter duplicated
+                       ArrayList elementsToAdd = new ArrayList(nElements);
+
+                       for (int i = 0; i < nElements; i++) {
+                               Object elem = elements.get(i);
+                               if (!fElements.contains(elem)) {
+                                       elementsToAdd.add(elem);
+                               }
+                       }
+                       fElements.addAll(elementsToAdd);
+                       if (fTree != null) {
+                               fTree.add(fParentElement, elementsToAdd.toArray());
+                               for (int i = 0; i < elementsToAdd.size(); i++) {
+                                       fTree.expandToLevel(elementsToAdd.get(i), fTreeExpandLevel);
+                               }
+                       }
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Adds an element at a position.
+        */
+       public void insertElementAt(Object element, int index) {
+               if (fElements.contains(element)) {
+                       return;
+               }
+               fElements.add(index, element);
+               if (fTree != null) {
+                       fTree.add(fParentElement, element);
+                       if (fTreeExpandLevel != -1) {
+                               fTree.expandToLevel(element, fTreeExpandLevel);
+                       }
+               }
+
+               dialogFieldChanged();
+       }
+
+       /**
+        * Adds an element at a position.
+        */
+       public void removeAllElements() {
+               if (fElements.size() > 0) {
+                       fElements.clear();
+                       refresh();
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Removes an element from the list.
+        */
+       public void removeElement(Object element) throws IllegalArgumentException {
+               if (fElements.remove(element)) {
+                       if (fTree != null) {
+                               fTree.remove(element);
+                       }
+                       dialogFieldChanged();
+               } else {
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       /**
+        * Removes elements from the list.
+        */
+       public void removeElements(List elements) {
+               if (elements.size() > 0) {
+                       fElements.removeAll(elements);
+                       if (fTree != null) {
+                               fTree.remove(elements.toArray());
+                       }
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Gets the number of elements
+        */
+       public int getSize() {
+               return fElements.size();
+       }
+
+       public void selectElements(ISelection selection) {
+               fSelectionWhenEnabled = selection;
+               if (fTree != null) {
+                       fTree.setSelection(selection, true);
+               }
+       }
+
+       public void selectFirstElement() {
+               Object element = null;
+               if (fViewerSorter != null) {
+                       Object[] arr = fElements.toArray();
+                       fViewerSorter.sort(fTree, arr);
+                       if (arr.length > 0) {
+                               element = arr[0];
+                       }
+               } else {
+                       if (fElements.size() > 0) {
+                               element = fElements.get(0);
+                       }
+               }
+               if (element != null) {
+                       selectElements(new StructuredSelection(element));
+               }
+       }
+
+       public void postSetSelection(final ISelection selection) {
+               if (isOkToUse(fTreeControl)) {
+                       Display d = fTreeControl.getDisplay();
+                       d.asyncExec(new Runnable() {
+                               public void run() {
+                                       if (isOkToUse(fTreeControl)) {
+                                               selectElements(selection);
+                                       }
+                               }
+                       });
+               }
+       }
+
+       /**
+        * Refreshes the tree.
+        */
+       public void refresh() {
+               if (fTree != null) {
+                       fTree.refresh();
+               }
+       }
+
+       /**
+        * Refreshes the tree.
+        */
+       public void refresh(Object element) {
+               if (fTree != null) {
+                       fTree.refresh(element);
+               }
+       }
+
+       // ------- list maintenance
+
+       private List moveUp(List elements, List move) {
+               int nElements = elements.size();
+               List res = new ArrayList(nElements);
+               Object floating = null;
+               for (int i = 0; i < nElements; i++) {
+                       Object curr = elements.get(i);
+                       if (move.contains(curr)) {
+                               res.add(curr);
+                       } else {
+                               if (floating != null) {
+                                       res.add(floating);
+                               }
+                               floating = curr;
+                       }
+               }
+               if (floating != null) {
+                       res.add(floating);
+               }
+               return res;
+       }
+
+       private void moveUp(List toMoveUp) {
+               if (toMoveUp.size() > 0) {
+                       setElements(moveUp(fElements, toMoveUp));
+                       fTree.reveal(toMoveUp.get(0));
+               }
+       }
+
+       private void moveDown(List toMoveDown) {
+               if (toMoveDown.size() > 0) {
+                       setElements(reverse(moveUp(reverse(fElements), toMoveDown)));
+                       fTree.reveal(toMoveDown.get(toMoveDown.size() - 1));
+               }
+       }
+
+       private List reverse(List p) {
+               List reverse = new ArrayList(p.size());
+               for (int i = p.size() - 1; i >= 0; i--) {
+                       reverse.add(p.get(i));
+               }
+               return reverse;
+       }
+
+       private void remove() {
+               removeElements(getSelectedElements());
+       }
+
+       private void up() {
+               moveUp(getSelectedElements());
+       }
+
+       private void down() {
+               moveDown(getSelectedElements());
+       }
+
+       private boolean canMoveUp(List selectedElements) {
+               if (isOkToUse(fTreeControl)) {
+                       int nSelected = selectedElements.size();
+                       int nElements = fElements.size();
+                       for (int i = 0; i < nElements && nSelected > 0; i++) {
+                               if (!selectedElements.contains(fElements.get(i))) {
+                                       return true;
+                               }
+                               nSelected--;
+                       }
+               }
+               return false;
+       }
+
+       private boolean canMoveDown(List selectedElements) {
+               if (isOkToUse(fTreeControl)) {
+                       int nSelected = selectedElements.size();
+                       for (int i = fElements.size() - 1; i >= 0 && nSelected > 0; i--) {
+                               if (!selectedElements.contains(fElements.get(i))) {
+                                       return true;
+                               }
+                               nSelected--;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Returns the selected elements.
+        */
+       public List getSelectedElements() {
+               ArrayList result = new ArrayList();
+               if (fTree != null) {
+                       ISelection selection = fTree.getSelection();
+                       if (selection instanceof IStructuredSelection) {
+                               Iterator iter = ((IStructuredSelection) selection).iterator();
+                               while (iter.hasNext()) {
+                                       result.add(iter.next());
+                               }
+                       }
+               }
+               return result;
+       }
+
+       public void expandElement(Object element, int level) {
+               if (fTree != null) {
+                       fTree.expandToLevel(element, level);
+               }
+       }
+
+       // ------- TreeViewerAdapter
+
+       private class TreeViewerAdapter implements ITreeContentProvider,
+                       ISelectionChangedListener, IDoubleClickListener {
+
+               private final Object[] NO_ELEMENTS = new Object[0];
+
+               // ------- ITreeContentProvider Interface ------------
+
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+                       // will never happen
+               }
+
+               public boolean isDeleted(Object element) {
+                       return false;
+               }
+
+               public void dispose() {
+               }
+
+               public Object[] getElements(Object obj) {
+                       return fElements.toArray();
+               }
+
+               public Object[] getChildren(Object element) {
+                       if (fTreeAdapter != null) {
+                               return fTreeAdapter.getChildren(TreeListDialogField.this,
+                                               element);
+                       }
+                       return NO_ELEMENTS;
+               }
+
+               public Object getParent(Object element) {
+                       if (!fElements.contains(element) && fTreeAdapter != null) {
+                               return fTreeAdapter
+                                               .getParent(TreeListDialogField.this, element);
+                       }
+                       return fParentElement;
+               }
+
+               public boolean hasChildren(Object element) {
+                       if (fTreeAdapter != null) {
+                               return fTreeAdapter.hasChildren(TreeListDialogField.this,
+                                               element);
+                       }
+                       return false;
+               }
+
+               // ------- ISelectionChangedListener Interface ------------
+
+               public void selectionChanged(SelectionChangedEvent event) {
+                       doListSelected(event);
+               }
+
+               /*
+                * (non-Javadoc)
+                * 
+                * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
+                */
+               public void doubleClick(DoubleClickEvent event) {
+                       doDoubleClick(event);
+               }
+
+       }
+
+       protected void doListSelected(SelectionChangedEvent event) {
+               updateButtonState();
+               if (fTreeAdapter != null) {
+                       fTreeAdapter.selectionChanged(this);
+               }
+       }
+
+       protected void doDoubleClick(DoubleClickEvent event) {
+               if (fTreeAdapter != null) {
+                       fTreeAdapter.doubleClicked(this);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/UITexts.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/UITexts.java
new file mode 100644 (file)
index 0000000..0914c0c
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+// modified for phpeclipse.de project by axelcl
+package net.sourceforge.phpdt.ltk.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * <p>
+ * provides internationalized String messages for the UI.
+ * </p>
+ * 
+ */
+public class UITexts {
+
+       private static final String BUNDLE_NAME = "net.sourceforge.phpdt.ltk.ui.uitexts"; //$NON-NLS-1$
+
+       static {
+               NLS.initializeMessages(BUNDLE_NAME, UITexts.class);
+       }
+
+       // message fields
+       public static String renameProperty_refuseDlg_title;
+
+       public static String renameProperty_refuseDlg_message;
+
+       public static String renamePropertyInputPage_lblNewName;
+
+       public static String renamePropertyInputPage_cbUpdateBundle;
+
+       public static String renamePropertyInputPage_cbAllProjects;
+
+       public static String renameLocalVariable_refuseDlg_title;
+
+       public static String renameLocalVariable_refuseDlg_message;
+
+       public static String renameLocalVariable_cbDQStrings;
+
+       public static String renameLocalVariable_cbPHPdoc;
+
+       public static String renameLocalVariable_cbOtherDoc;
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/actions/RenameLocalVariable.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/actions/RenameLocalVariable.java
new file mode 100644 (file)
index 0000000..efe11dd
--- /dev/null
@@ -0,0 +1,213 @@
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+// modified for phpeclipse.de project by axelcl
+package net.sourceforge.phpdt.ltk.ui.actions;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.core.SourceMethod;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierInfo;
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierRefactoring;
+import net.sourceforge.phpdt.ltk.core.RenameLocalVariableDelegate;
+import net.sourceforge.phpdt.ltk.core.RenamePHPProcessor;
+import net.sourceforge.phpdt.ltk.ui.UITexts;
+import net.sourceforge.phpdt.ltk.ui.wizards.RenameLocalVariableWizard;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class RenameLocalVariable implements IEditorActionDelegate {
+
+       private ISelection selection;
+
+       private IEditorPart targetEditor;
+
+       private boolean onPHPFile;
+
+       private RenameIdentifierInfo info = new RenameIdentifierInfo();
+
+       public void setActiveEditor(final IAction action,
+                       final IEditorPart targetEditor) {
+               this.targetEditor = targetEditor;
+               onPHPFile = false;
+               IFile file = getFile();
+
+               if (file != null && PHPFileUtil.isPHPFile(file)) {
+                       onPHPFile = true;
+               }
+       }
+
+       public void run(final IAction action) {
+               if (!onPHPFile) {
+                       refuse();
+               } else {
+                       if (selection != null && selection instanceof ITextSelection) {
+                               String word = null;
+                               Point point = null;
+                               if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
+                                       PHPEditor editor = (PHPEditor) targetEditor;
+                                       if (editor != null) {
+                                               ITextSelection textSelection = (ITextSelection) editor
+                                                               .getSelectionProvider().getSelection();
+                                               IDocument doc = editor.getDocumentProvider()
+                                                               .getDocument(editor.getEditorInput());
+                                               int pos = textSelection.getOffset();
+                                               point = PHPWordExtractor.findWord(doc, pos);
+                                               if (point != null) {
+                                                       try {
+                                                               word = doc.get(point.x, point.y);
+                                                               IWorkingCopyManager manager = WebUI
+                                                                               .getDefault().getWorkingCopyManager();
+                                                               ICompilationUnit unit = manager
+                                                                               .getWorkingCopy(editor.getEditorInput());
+                                                               SourceMethod method = (SourceMethod) findEnclosingElement(
+                                                                               point.x, unit, IJavaElement.METHOD);
+                                                               if (word == null || word.charAt(0) != '$'
+                                                                               || method == null
+                                                                               || !(method instanceof SourceMethod)) {
+                                                                       refuseLocalVariable();
+                                                               } else {
+                                                                       applySelection((ITextSelection) selection,
+                                                                                       word, point, method);
+                                                                       if (saveAll()) {
+                                                                               openWizard();
+                                                                       }
+                                                               }
+                                                       } catch (BadLocationException e) {
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Returns the enclosing element of a particular element type,
+        * <code>null</code> if no enclosing element of that type exists.
+        */
+       public IJavaElement findEnclosingElement(int start, ICompilationUnit cu,
+                       int elementType) {
+               if (cu == null)
+                       return null;
+
+               try {
+                       IJavaElement element = cu.getElementAt(start);
+                       if (element == null) {
+                               element = cu;
+                       }
+
+                       return element.getAncestor(elementType);
+
+               } catch (JavaModelException e) {
+                       return null;
+               }
+       }
+
+       public void selectionChanged(final IAction action,
+                       final ISelection selection) {
+               this.selection = selection;
+       }
+
+       // helping methods
+       // ////////////////
+
+       private void applySelection(final ITextSelection textSelection,
+                       String word, Point point, SourceMethod method) {
+               if (word != null) {
+                       info.setOldName(word);
+                       info.setNewName(word);
+                       info.setOffset(point.x);
+               } else {
+                       info.setOldName(textSelection.getText());
+                       info.setNewName(textSelection.getText());
+                       info.setOffset(textSelection.getOffset());
+               }
+               info.setMethod(method);
+               info.setSourceFile(getFile());
+       }
+
+       private void refuseLocalVariable() {
+               String title = UITexts.renameLocalVariable_refuseDlg_title;
+               String message = UITexts.renameLocalVariable_refuseDlg_message;
+               MessageDialog.openInformation(getShell(), title, message);
+       }
+
+       private void refuse() {
+               String title = UITexts.renameProperty_refuseDlg_title;
+               String message = UITexts.renameProperty_refuseDlg_message;
+               MessageDialog.openInformation(getShell(), title, message);
+       }
+
+       private static boolean saveAll() {
+               IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+               return IDE.saveAllEditors(new IResource[] { workspaceRoot }, false);
+       }
+
+       private void openWizard() {
+               RenameLocalVariableDelegate delegate = new RenameLocalVariableDelegate(
+                               info);
+               RefactoringProcessor processor = new RenamePHPProcessor(info, delegate);
+               RenameIdentifierRefactoring ref = new RenameIdentifierRefactoring(
+                               processor);
+               RenameLocalVariableWizard wizard = new RenameLocalVariableWizard(ref,
+                               info);
+               RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(
+                               wizard);
+               try {
+                       String titleForFailedChecks = ""; //$NON-NLS-1$
+                       op.run(getShell(), titleForFailedChecks);
+               } catch (final InterruptedException irex) {
+                       // operation was cancelled
+               }
+       }
+
+       private Shell getShell() {
+               Shell result = null;
+               if (targetEditor != null) {
+                       result = targetEditor.getSite().getShell();
+               } else {
+                       result = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                                       .getShell();
+               }
+               return result;
+       }
+
+       private final IFile getFile() {
+               IFile result = null;
+               if (targetEditor instanceof ITextEditor) {
+                       ITextEditor editor = (ITextEditor) targetEditor;
+                       IEditorInput input = editor.getEditorInput();
+                       if (input instanceof IFileEditorInput) {
+                               result = ((IFileEditorInput) input).getFile();
+                       }
+               }
+               return result;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/actions/RenamePHPIdentifier.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/actions/RenamePHPIdentifier.java
new file mode 100644 (file)
index 0000000..53d06a5
--- /dev/null
@@ -0,0 +1,175 @@
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+// modified for phpeclipse.de project by axelcl
+package net.sourceforge.phpdt.ltk.ui.actions;
+
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierDelegate;
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierInfo;
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierRefactoring;
+import net.sourceforge.phpdt.ltk.core.RenamePHPProcessor;
+import net.sourceforge.phpdt.ltk.ui.UITexts;
+import net.sourceforge.phpdt.ltk.ui.wizards.RenameIdentifierWizard;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * <p>
+ * action that is triggered from the editor context menu.
+ * </p>
+ * 
+ * <p>
+ * This action is declared in the <code>plugin.xml</code>.
+ * </p>
+ * 
+ */
+public class RenamePHPIdentifier implements IEditorActionDelegate {
+
+       private ISelection selection;
+
+       private IEditorPart targetEditor;
+
+       private boolean onPHPFile;
+
+       private RenameIdentifierInfo info = new RenameIdentifierInfo();
+
+       // interface methods of IEditorActionDelegate
+       // ///////////////////////////////////////////
+
+       public void setActiveEditor(final IAction action,
+                       final IEditorPart targetEditor) {
+               this.targetEditor = targetEditor;
+               onPHPFile = false;
+               IFile file = getFile();
+
+               if (file != null && PHPFileUtil.isPHPFile(file)) {
+                       onPHPFile = true;
+               }
+       }
+
+       public void run(final IAction action) {
+               if (!onPHPFile) {
+                       refuse();
+               } else {
+                       if (selection != null && selection instanceof ITextSelection) {
+                               String word = null;
+                               Point point = null;
+                               if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
+                                       PHPEditor editor = (PHPEditor) targetEditor;
+                                       if (editor != null) {
+                                               ITextSelection textSelection = (ITextSelection) editor
+                                                               .getSelectionProvider().getSelection();
+                                               IDocument doc = editor.getDocumentProvider()
+                                                               .getDocument(editor.getEditorInput());
+                                               int pos = textSelection.getOffset();
+                                               point = PHPWordExtractor.findWord(doc, pos);
+                                               if (point != null) {
+                                                       try {
+                                                               word = doc.get(point.x, point.y);
+                                                       } catch (BadLocationException e) {
+                                                       }
+                                               }
+                                       }
+                               }
+                               applySelection((ITextSelection) selection, word, point);
+                               if (saveAll()) {
+                                       openWizard();
+                               }
+                       }
+               }
+       }
+
+       public void selectionChanged(final IAction action,
+                       final ISelection selection) {
+               this.selection = selection;
+       }
+
+       // helping methods
+       // ////////////////
+
+       private void applySelection(final ITextSelection textSelection,
+                       String word, Point point) {
+               if (word != null) {
+                       info.setOldName(word);
+                       info.setNewName(word);
+                       info.setOffset(point.x);
+               } else {
+                       info.setOldName(textSelection.getText());
+                       info.setNewName(textSelection.getText());
+                       info.setOffset(textSelection.getOffset());
+               }
+               info.setSourceFile(getFile());
+       }
+
+       private void refuse() {
+               String title = UITexts.renameProperty_refuseDlg_title;
+               String message = UITexts.renameProperty_refuseDlg_message;
+               MessageDialog.openInformation(getShell(), title, message);
+       }
+
+       private static boolean saveAll() {
+               IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+               return IDE.saveAllEditors(new IResource[] { workspaceRoot }, false);
+       }
+
+       private void openWizard() {
+               RenameIdentifierDelegate delegate = new RenameIdentifierDelegate(info);
+               RefactoringProcessor processor = new RenamePHPProcessor(info, delegate);
+               RenameIdentifierRefactoring ref = new RenameIdentifierRefactoring(
+                               processor);
+               RenameIdentifierWizard wizard = new RenameIdentifierWizard(ref, info);
+               RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(
+                               wizard);
+               try {
+                       String titleForFailedChecks = ""; //$NON-NLS-1$
+                       op.run(getShell(), titleForFailedChecks);
+               } catch (final InterruptedException irex) {
+                       // operation was cancelled
+               }
+       }
+
+       private Shell getShell() {
+               Shell result = null;
+               if (targetEditor != null) {
+                       result = targetEditor.getSite().getShell();
+               } else {
+                       result = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                                       .getShell();
+               }
+               return result;
+       }
+
+       private final IFile getFile() {
+               IFile result = null;
+               if (targetEditor instanceof ITextEditor) {
+                       ITextEditor editor = (ITextEditor) targetEditor;
+                       IEditorInput input = editor.getEditorInput();
+                       if (input instanceof IFileEditorInput) {
+                               result = ((IFileEditorInput) input).getFile();
+                       }
+               }
+               return result;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/uitexts.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/uitexts.properties
new file mode 100644 (file)
index 0000000..219e39d
--- /dev/null
@@ -0,0 +1,11 @@
+renameProperty_refuseDlg_title=Rename PHP identifier
+renameProperty_refuseDlg_message=This refactoring is only available on PHP files.
+renamePropertyInputPage_lblNewName=New name\:
+renamePropertyInputPage_cbUpdateBundle=Update all PHP files in the same project
+renamePropertyInputPage_cbAllProjects=Update all PHP projects in the workspace (forces preview)
+
+renameLocalVariable_refuseDlg_title=Rename Local PHP variable
+renameLocalVariable_refuseDlg_message=The selected identifier is no local PHP variable.
+renameLocalVariable_cbDQStrings=Rename variable inside double quoted strings
+renameLocalVariable_cbPHPdoc=Rename variable inside PHPdoc comments
+renameLocalVariable_cbOtherDoc=Rename variable inside other PHP comments (line or block)
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameIdentifierPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameIdentifierPage.java
new file mode 100644 (file)
index 0000000..e29747b
--- /dev/null
@@ -0,0 +1,181 @@
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+package net.sourceforge.phpdt.ltk.ui.wizards;
+
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierInfo;
+import net.sourceforge.phpdt.ltk.ui.UITexts;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * <p>
+ * the input page for the Rename Property refactoring, where users can control
+ * the effects of the refactoring; to be shown in the wizard.
+ * </p>
+ * 
+ * <p>
+ * We let the user enter the new name for the property, and we let her decide
+ * whether other property files in the bundle should be affected, and whether
+ * the operation is supposed to span the entire workspace or only the current
+ * project.
+ * </p>
+ * 
+ */
+public class RenameIdentifierPage extends UserInputWizardPage {
+
+       private static final String DS_KEY = RenameIdentifierPage.class.getName();
+
+       private static final String DS_UPDATE_BUNDLE = "UPDATE_BUNDLE"; //$NON-NLS-1$
+
+       private static final String DS_ALL_PROJECTS = "ALL_PROJECTS"; //$NON-NLS-1$
+
+       private final RenameIdentifierInfo info;
+
+       private IDialogSettings dialogSettings;
+
+       private Text txtNewName;
+
+       private Button cbUpdateBundle;
+
+       private Button cbAllProjects;
+
+       public RenameIdentifierPage(final RenameIdentifierInfo info) {
+               super(RenameIdentifierPage.class.getName());
+               this.info = info;
+               initDialogSettings();
+       }
+
+       // interface methods of UserInputWizardPage
+       // /////////////////////////////////////////
+
+       public void createControl(final Composite parent) {
+               Composite composite = createRootComposite(parent);
+               setControl(composite);
+
+               createLblNewName(composite);
+               createTxtNewName(composite);
+               createCbUpdateBundle(composite);
+               createCbAllProjects(composite);
+
+               validate();
+       }
+
+       // UI creation methods
+       // ////////////////////
+
+       private Composite createRootComposite(final Composite parent) {
+               Composite result = new Composite(parent, SWT.NONE);
+               GridLayout gridLayout = new GridLayout(2, false);
+               gridLayout.marginWidth = 10;
+               gridLayout.marginHeight = 10;
+               result.setLayout(gridLayout);
+               initializeDialogUnits(result);
+               Dialog.applyDialogFont(result);
+               return result;
+       }
+
+       private void createLblNewName(final Composite composite) {
+               Label lblNewName = new Label(composite, SWT.NONE);
+               lblNewName.setText(UITexts.renamePropertyInputPage_lblNewName);
+       }
+
+       private void createTxtNewName(Composite composite) {
+               txtNewName = new Text(composite, SWT.BORDER);
+               txtNewName.setText(info.getOldName());
+               txtNewName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               txtNewName.selectAll();
+               txtNewName.addKeyListener(new KeyAdapter() {
+                       public void keyReleased(final KeyEvent e) {
+                               info.setNewName(txtNewName.getText());
+                               validate();
+                       }
+               });
+       }
+
+       private void createCbUpdateBundle(final Composite composite) {
+               String texts = UITexts.renamePropertyInputPage_cbUpdateBundle;
+               cbUpdateBundle = createCheckbox(composite, texts);
+               cbUpdateBundle.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(final SelectionEvent event) {
+                               boolean selected = cbUpdateBundle.getSelection();
+                               dialogSettings.put(DS_UPDATE_BUNDLE, selected);
+                               info.setUpdateProject(selected);
+                       }
+               });
+               initUpdateBundleOption();
+       }
+
+       private void createCbAllProjects(final Composite composite) {
+               String text = UITexts.renamePropertyInputPage_cbAllProjects;
+               cbAllProjects = createCheckbox(composite, text);
+               cbAllProjects.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(final SelectionEvent event) {
+                               boolean selected = cbAllProjects.getSelection();
+                               dialogSettings.put(DS_ALL_PROJECTS, selected);
+                               info.setAllProjects(selected);
+                               // for demonstration purposes, we enforce the preview for
+                               // refactorings
+                               // that span the entire workspace
+                               getRefactoringWizard().setForcePreviewReview(selected);
+                       }
+               });
+               initAllProjectsOption();
+       }
+
+       private Button createCheckbox(final Composite composite, final String text) {
+               Button result = new Button(composite, SWT.CHECK);
+               result.setText(text);
+
+               GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalSpan = 2;
+               result.setLayoutData(gridData);
+
+               return result;
+       }
+
+       // helping methods
+       // ////////////////
+
+       private void initDialogSettings() {
+               IDialogSettings ds = WebUI.getDefault().getDialogSettings();
+               dialogSettings = ds.getSection(DS_KEY);
+               if (dialogSettings == null) {
+                       dialogSettings = ds.addNewSection(DS_KEY);
+                       // init default values
+                       dialogSettings.put(DS_UPDATE_BUNDLE, true);
+                       dialogSettings.put(DS_ALL_PROJECTS, false);
+               }
+       }
+
+       private void validate() {
+               String txt = txtNewName.getText();
+               setPageComplete(txt.length() > 0 && !txt.equals(info.getOldName()));
+       }
+
+       private void initUpdateBundleOption() {
+               boolean updateRefs = dialogSettings.getBoolean(DS_UPDATE_BUNDLE);
+               cbUpdateBundle.setSelection(updateRefs);
+               info.setUpdateProject(updateRefs);
+       }
+
+       private void initAllProjectsOption() {
+               boolean allProjects = dialogSettings.getBoolean(DS_ALL_PROJECTS);
+               cbAllProjects.setSelection(allProjects);
+               info.setAllProjects(allProjects);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameIdentifierWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameIdentifierWizard.java
new file mode 100644 (file)
index 0000000..ca8bb68
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+package net.sourceforge.phpdt.ltk.ui.wizards;
+
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierInfo;
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierRefactoring;
+
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+
+/**
+ * <p>
+ * The wizard that is shown to the user for entering the necessary information
+ * for property renaming.
+ * </p>
+ * 
+ * <p>
+ * The wizard class is primarily needed for deciding which pages are shown to
+ * the user. The actual user interface creation goes on the pages.
+ * </p>
+ * 
+ */
+public class RenameIdentifierWizard extends RefactoringWizard {
+
+       private final RenameIdentifierInfo info;
+
+       public RenameIdentifierWizard(
+                       final RenameIdentifierRefactoring refactoring,
+                       final RenameIdentifierInfo info) {
+               super(refactoring, DIALOG_BASED_USER_INTERFACE);
+               this.info = info;
+       }
+
+       // interface methods of RefactoringWizard
+       // ///////////////////////////////////////
+
+       protected void addUserInputPages() {
+               setDefaultPageTitle(getRefactoring().getName());
+               addPage(new RenameLocalVariablePage(info));
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameLocalVariablePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameLocalVariablePage.java
new file mode 100644 (file)
index 0000000..3db9cec
--- /dev/null
@@ -0,0 +1,215 @@
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+package net.sourceforge.phpdt.ltk.ui.wizards;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierInfo;
+import net.sourceforge.phpdt.ltk.ui.UITexts;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * <p>
+ * the input page for the Rename Property refactoring, where users can control
+ * the effects of the refactoring; to be shown in the wizard.
+ * </p>
+ * 
+ * <p>
+ * We let the user enter the new name for the property, and we let her decide
+ * whether other property files in the bundle should be affected, and whether
+ * the operation is supposed to span the entire workspace or only the current
+ * project.
+ * </p>
+ * 
+ */
+public class RenameLocalVariablePage extends UserInputWizardPage {
+
+       private static final String DS_KEY = RenameLocalVariablePage.class
+                       .getName();
+
+       private static final String DS_RENAME_DQ_STRINGS = "RENAME_DQ_STRINGS"; //$NON-NLS-1$
+
+       private static final String DS_RENAME_PHPDOC = "RENAME_PHPDOC"; //$NON-NLS-1$
+
+       private static final String DS_RENAME_OTHER_COMMENTS = "RENAME_OTHER_COMMENTS"; //$NON-NLS-1$
+
+       private final RenameIdentifierInfo info;
+
+       private IDialogSettings dialogSettings;
+
+       private Text txtNewName;
+
+       private Button cbRenameDQStrings;
+
+       private Button cbRenamePHPdoc;
+
+       private Button cbRenameOtherComments;
+
+       public RenameLocalVariablePage(final RenameIdentifierInfo info) {
+               super(RenameLocalVariablePage.class.getName());
+               this.info = info;
+               initDialogSettings();
+       }
+
+       public void createControl(final Composite parent) {
+               Composite composite = createRootComposite(parent);
+               setControl(composite);
+
+               createLblNewName(composite);
+               createTxtNewName(composite);
+               createCbDQStrings(composite);
+               createCbPHPdoc(composite);
+               createCbOtherComments(composite);
+
+               validate();
+
+               // TODO check if we can leave this step out in the future
+               getRefactoringWizard().setForcePreviewReview(true);
+       }
+
+       private Composite createRootComposite(final Composite parent) {
+               Composite result = new Composite(parent, SWT.NONE);
+               GridLayout gridLayout = new GridLayout(2, false);
+               gridLayout.marginWidth = 10;
+               gridLayout.marginHeight = 10;
+               result.setLayout(gridLayout);
+               initializeDialogUnits(result);
+               Dialog.applyDialogFont(result);
+               return result;
+       }
+
+       private void createLblNewName(final Composite composite) {
+               Label lblNewName = new Label(composite, SWT.NONE);
+               lblNewName.setText(UITexts.renamePropertyInputPage_lblNewName);
+       }
+
+       private void createTxtNewName(Composite composite) {
+               txtNewName = new Text(composite, SWT.BORDER);
+               txtNewName.setText(info.getOldName());
+               txtNewName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               txtNewName.selectAll();
+               txtNewName.addKeyListener(new KeyAdapter() {
+                       public void keyReleased(final KeyEvent e) {
+                               info.setNewName(txtNewName.getText());
+                               validate();
+                       }
+               });
+       }
+
+       private void createCbDQStrings(final Composite composite) {
+               String texts = UITexts.renameLocalVariable_cbDQStrings;
+               cbRenameDQStrings = createCheckbox(composite, texts);
+               cbRenameDQStrings.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(final SelectionEvent event) {
+                               boolean selected = cbRenameDQStrings.getSelection();
+                               dialogSettings.put(DS_RENAME_DQ_STRINGS, selected);
+                               info.setRenameDQString(selected);
+                       }
+               });
+               initDQStringsOption();
+       }
+
+       private void createCbPHPdoc(final Composite composite) {
+               String texts = UITexts.renameLocalVariable_cbPHPdoc;
+               cbRenamePHPdoc = createCheckbox(composite, texts);
+               cbRenamePHPdoc.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(final SelectionEvent event) {
+                               boolean selected = cbRenamePHPdoc.getSelection();
+                               dialogSettings.put(DS_RENAME_PHPDOC, selected);
+                               info.setRenamePHPdoc(selected);
+                       }
+               });
+               initPHPdocOption();
+       }
+
+       private void createCbOtherComments(final Composite composite) {
+               String texts = UITexts.renameLocalVariable_cbOtherDoc;
+               cbRenameOtherComments = createCheckbox(composite, texts);
+               cbRenameOtherComments.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(final SelectionEvent event) {
+                               boolean selected = cbRenameOtherComments.getSelection();
+                               dialogSettings.put(DS_RENAME_OTHER_COMMENTS, selected);
+                               info.setRenameOtherComments(selected);
+                       }
+               });
+               initOtherCommentsOption();
+       }
+
+       private Button createCheckbox(final Composite composite, final String text) {
+               Button result = new Button(composite, SWT.CHECK);
+               result.setText(text);
+
+               GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalSpan = 2;
+               result.setLayoutData(gridData);
+
+               return result;
+       }
+
+       private void initDialogSettings() {
+               IDialogSettings ds = WebUI.getDefault().getDialogSettings();
+               dialogSettings = ds.getSection(DS_KEY);
+               if (dialogSettings == null) {
+                       dialogSettings = ds.addNewSection(DS_KEY);
+                       // init default values
+                       dialogSettings.put(DS_RENAME_DQ_STRINGS, true);
+                       dialogSettings.put(DS_RENAME_PHPDOC, true);
+                       dialogSettings.put(DS_RENAME_OTHER_COMMENTS, true);
+               }
+       }
+
+       private static boolean isVariable(String txt) {
+               if (txt.length() <= 1) {
+                       return false;
+               }
+               if (txt.charAt(0) != '$') {
+                       return false;
+               }
+               for (int i = 1; i < txt.length(); i++) {
+                       if (!Scanner.isPHPIdentifierPart(txt.charAt(i))) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       private void validate() {
+               String txt = txtNewName.getText();
+               Scanner s;
+               setPageComplete(isVariable(txt) && !txt.equals(info.getOldName()));
+       }
+
+       private void initDQStringsOption() {
+               boolean refs = dialogSettings.getBoolean(DS_RENAME_DQ_STRINGS);
+               cbRenameDQStrings.setSelection(refs);
+               info.setRenameDQString(refs);
+       }
+
+       private void initPHPdocOption() {
+               boolean refs = dialogSettings.getBoolean(DS_RENAME_PHPDOC);
+               cbRenamePHPdoc.setSelection(refs);
+               info.setRenamePHPdoc(refs);
+       }
+
+       private void initOtherCommentsOption() {
+               boolean refs = dialogSettings.getBoolean(DS_RENAME_OTHER_COMMENTS);
+               cbRenameOtherComments.setSelection(refs);
+               info.setRenameOtherComments(refs);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameLocalVariableWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ltk/ui/wizards/RenameLocalVariableWizard.java
new file mode 100644 (file)
index 0000000..a4f8941
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+package net.sourceforge.phpdt.ltk.ui.wizards;
+
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierInfo;
+import net.sourceforge.phpdt.ltk.core.RenameIdentifierRefactoring;
+
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+
+/**
+ * <p>
+ * The wizard that is shown to the user for entering the necessary information
+ * for property renaming of local PHP variables.
+ * </p>
+ * 
+ * <p>
+ * The wizard class is primarily needed for deciding which pages are shown to
+ * the user. The actual user interface creation goes on the pages.
+ * </p>
+ * 
+ */
+public class RenameLocalVariableWizard extends RefactoringWizard {
+
+       private final RenameIdentifierInfo info;
+
+       public RenameLocalVariableWizard(
+                       final RenameIdentifierRefactoring refactoring,
+                       final RenameIdentifierInfo info) {
+               super(refactoring, DIALOG_BASED_USER_INTERFACE);
+               this.info = info;
+       }
+
+       protected void addUserInputPages() {
+               setDefaultPageTitle(getRefactoring().getName());
+               addPage(new RenameLocalVariablePage(info));
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/CodeGeneration.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/CodeGeneration.java
new file mode 100644 (file)
index 0000000..05dacb0
--- /dev/null
@@ -0,0 +1,410 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Class that offers access to the templates contained in the 'code templates'
+ * preference page.
+ * 
+ * @since 2.1
+ */
+public class CodeGeneration {
+
+       private CodeGeneration() {
+       }
+
+       /**
+        * Returns the content for a new compilation unit using the 'new Java file'
+        * code template.
+        * 
+        * @param cu
+        *            The compilation to create the source for. The compilation unit
+        *            does not need to exist.
+        * @param typeComment
+        *            The comment for the type to be created. Used when the code
+        *            template contains a <i>${typecomment}</i> variable. Can be
+        *            <code>null</code> if no comment should be added.
+        * @param typeContent
+        *            The code of the type, including type declaration and body.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the new content or <code>null</code> if the template is
+        *         undefined or empty.
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        */
+       public static String getCompilationUnitContent(ICompilationUnit cu,
+                       String typeComment, String typeContent, String lineDelimiter)
+                       throws CoreException {
+               return StubUtility.getCompilationUnitContent(cu, typeComment,
+                               typeContent, lineDelimiter);
+       }
+
+       /**
+        * Returns the content for a new type comment using the 'type comment' code
+        * template. The returned content is unformatted and is not indented.
+        * 
+        * @param cu
+        *            The compilation where the type is contained. The compilation
+        *            unit does not need to exist.
+        * @param typeQualifiedName
+        *            The name of the type to which the comment is added. For inner
+        *            types the name must be qualified and include the outer types
+        *            names (dot separated). See
+        *            {@link net.sourceforge.phpdt.core.IType#getTypeQualifiedName(char)}.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the new content or <code>null</code> if the code
+        *         template is undefined or empty. The returned content is
+        *         unformatted and is not indented.
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        */
+       public static String getTypeComment(ICompilationUnit cu,
+                       String typeQualifiedName, String lineDelimiter)
+                       throws CoreException {
+               return StubUtility.getTypeComment(cu, typeQualifiedName, lineDelimiter);
+       }
+
+       /**
+        * Returns the content for a new field comment using the 'field comment'
+        * code template. The returned content is unformatted and is not indented.
+        * 
+        * @param cu
+        *            The compilation where the field is contained. The compilation
+        *            unit does not need to exist.
+        * @param typeName
+        *            The name of the field declared type.
+        * @param fieldName
+        *            The name of the field to which the comment is added.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the new content or <code>null</code> if the code
+        *         template is undefined or empty. The returned content is
+        *         unformatted and is not indented.
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        * @since 3.0
+        */
+       public static String getFieldComment(ICompilationUnit cu, String typeName,
+                       String fieldName, String lineDelimiter) throws CoreException {
+               return StubUtility.getFieldComment(cu, typeName, fieldName,
+                               lineDelimiter);
+       }
+
+       /**
+        * Returns the comment for a method or constructor using the comment code
+        * templates (constructor / method / overriding method). <code>null</code>
+        * is returned if the template is empty.
+        * 
+        * @param cu
+        *            The compilation unit to which the method belongs. The
+        *            compilation unit does not need to exist.
+        * @param declaringTypeName
+        *            Name of the type to which the method belongs. For inner types
+        *            the name must be qualified and include the outer types names
+        *            (dot separated). See
+        *            {@link net.sourceforge.phpdt.core.IType#getTypeQualifiedName(char)}.
+        * @param decl
+        *            The MethodDeclaration AST node that will be added as new
+        *            method. The node does not need to exist in an AST (no parent
+        *            needed) and does not need to resolve. See
+        *            {@link net.sourceforge.phpdt.core.dom.AST#newMethodDeclaration()}
+        *            for how to create such a node.
+        * @param overridden
+        *            The binding of the method that will be overridden by the
+        *            created method or <code>null</code> if no method is
+        *            overridden.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the generated method comment or <code>null</code> if
+        *         the code template is empty. The returned content is unformatted
+        *         and not indented (formatting required).
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        */
+       // public static String getMethodComment(ICompilationUnit cu, String
+       // declaringTypeName, MethodDeclaration decl, IMethodBinding overridden,
+       // String lineDelimiter) throws CoreException {
+       // return StubUtility.getMethodComment(cu, declaringTypeName, decl,
+       // overridden, lineDelimiter);
+       // }
+       /**
+        * Returns the comment for a method or constructor using the comment code
+        * templates (constructor / method / overriding method). <code>null</code>
+        * is returned if the template is empty.
+        * <p>
+        * The returned string is unformatted and not indented.
+        * <p>
+        * Exception types and return type are in signature notation. e.g. a source
+        * method declared as <code>public void foo(String text, int length)</code>
+        * would return the array <code>{"QString;","I"}</code> as parameter
+        * types. See {@link net.sourceforge.phpdt.core.Signature}.
+        * 
+        * @param cu
+        *            The compilation unit to which the method belongs. The
+        *            compilation unit does not need to exist.
+        * @param declaringTypeName
+        *            Name of the type to which the method belongs. For inner types
+        *            the name must be qualified and include the outer types names
+        *            (dot separated). See
+        *            {@link net.sourceforge.phpdt.core.IType#getTypeQualifiedName(char)}.
+        * @param methodName
+        *            Name of the method.
+        * @param paramNames
+        *            Names of the parameters for the method.
+        * @param excTypeSig
+        *            Thrown exceptions (Signature notation).
+        * @param retTypeSig
+        *            Return type (Signature notation) or <code>null</code> for
+        *            constructors.
+        * @param overridden
+        *            The method that will be overridden by the created method or
+        *            <code>null</code> for non-overriding methods. If not
+        *            <code>null</code>, the method must exist.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the constructed comment or <code>null</code> if the
+        *         comment code template is empty. The returned content is
+        *         unformatted and not indented (formatting required).
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        */
+       public static String getMethodComment(ICompilationUnit cu,
+                       String declaringTypeName, String methodName, String[] paramNames,
+                       String[] excTypeSig, String retTypeSig, IMethod overridden,
+                       String lineDelimiter) throws CoreException {
+               return StubUtility.getMethodComment(cu, declaringTypeName, methodName,
+                               paramNames, excTypeSig, retTypeSig, overridden, lineDelimiter);
+       }
+
+       /**
+        * Returns the comment for a method or constructor using the comment code
+        * templates (constructor / method / overriding method). <code>null</code>
+        * is returned if the template is empty.
+        * <p>
+        * The returned string is unformatted and not indented.
+        * 
+        * @param method
+        *            The method to be documented. The method must exist.
+        * @param overridden
+        *            The method that will be overridden by the created method or
+        *            <code>null</code> for non-overriding methods. If not
+        *            <code>null</code>, the method must exist.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the constructed comment or <code>null</code> if the
+        *         comment code template is empty. The returned string is
+        *         unformatted and and has no indent (formatting required).
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        */
+       public static String getMethodComment(IMethod method, IMethod overridden,
+                       String lineDelimiter) throws CoreException {
+               return StubUtility.getMethodComment(method, overridden, lineDelimiter);
+       }
+
+       /**
+        * Returns the content of the body for a method or constructor using the
+        * method body templates. <code>null</code> is returned if the template is
+        * empty.
+        * <p>
+        * The returned string is unformatted and not indented.
+        * 
+        * @param cu
+        *            The compilation unit to which the method belongs. The
+        *            compilation unit does not need to exist.
+        * @param declaringTypeName
+        *            Name of the type to which the method belongs. For inner types
+        *            the name must be qualified and include the outer types names
+        *            (dot separated). See
+        *            {@link net.sourceforge.phpdt.core.IType#getTypeQualifiedName(char)}.
+        * @param methodName
+        *            Name of the method.
+        * @param isConstructor
+        *            Defines if the created body is for a constructor.
+        * @param bodyStatement
+        *            The code to be entered at the place of the variable
+        *            ${body_statement}.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the constructed body content or <code>null</code> if
+        *         the comment code template is empty. The returned string is
+        *         unformatted and and has no indent (formatting required).
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        */
+       public static String getMethodBodyContent(ICompilationUnit cu,
+                       String declaringTypeName, String methodName, boolean isConstructor,
+                       String bodyStatement, String lineDelimiter) throws CoreException {
+               return StubUtility.getMethodBodyContent(isConstructor, cu
+                               .getJavaProject(), declaringTypeName, methodName,
+                               bodyStatement, lineDelimiter);
+       }
+
+       /**
+        * Returns the content of body for a getter method using the getter method
+        * body template. <code>null</code> is returned if the template is empty.
+        * <p>
+        * The returned string is unformatted and not indented.
+        * 
+        * @param cu
+        *            The compilation unit to which the method belongs. The
+        *            compilation unit does not need to exist.
+        * @param declaringTypeName
+        *            Name of the type to which the method belongs. For inner types
+        *            the name must be qualified and include the outer types names
+        *            (dot separated). See
+        *            {@link net.sourceforge.phpdt.core.IType#getTypeQualifiedName(char)}.
+        * @param methodName
+        *            The name of the getter method.
+        * @param fieldName
+        *            The name of the field to get in the getter method,
+        *            corresponding to the template variable for ${field}.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the constructed body content or <code>null</code> if
+        *         the comment code template is empty. The returned string is
+        *         unformatted and and has no indent (formatting required).
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        * @since 3.0
+        */
+       public static String getGetterMethodBodyContent(ICompilationUnit cu,
+                       String declaringTypeName, String methodName, String fieldName,
+                       String lineDelimiter) throws CoreException {
+               return StubUtility.getGetterMethodBodyContent(cu.getJavaProject(),
+                               declaringTypeName, methodName, fieldName, lineDelimiter);
+       }
+
+       /**
+        * Returns the content of body for a setter method using the setter method
+        * body template. <code>null</code> is returned if the template is empty.
+        * <p>
+        * The returned string is unformatted and not indented.
+        * 
+        * @param cu
+        *            The compilation unit to which the method belongs. The
+        *            compilation unit does not need to exist.
+        * @param declaringTypeName
+        *            Name of the type to which the method belongs. For inner types
+        *            the name must be qualified and include the outer types names
+        *            (dot separated). See
+        *            {@link net.sourceforge.phpdt.core.IType#getTypeQualifiedName(char)}.
+        * @param methodName
+        *            The name of the setter method.
+        * @param fieldName
+        *            The name of the field to be set in the setter method,
+        *            corresponding to the template variable for ${field}.
+        * @param paramName
+        *            The name of the parameter passed to the setter method,
+        *            corresponding to the template variable for $(param).
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the constructed body content or <code>null</code> if
+        *         the comment code template is empty. The returned string is
+        *         unformatted and and has no indent (formatting required).
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        * @since 3.0
+        */
+       public static String getSetterMethodBodyContent(ICompilationUnit cu,
+                       String declaringTypeName, String methodName, String fieldName,
+                       String paramName, String lineDelimiter) throws CoreException {
+               return StubUtility.getSetterMethodBodyContent(cu.getJavaProject(),
+                               declaringTypeName, methodName, fieldName, paramName,
+                               lineDelimiter);
+       }
+
+       /**
+        * Returns the comment for a getter method using the getter comment
+        * template. <code>null</code> is returned if the template is empty.
+        * <p>
+        * The returned string is unformatted and not indented.
+        * 
+        * @param cu
+        *            The compilation unit to which the method belongs. The
+        *            compilation unit does not need to exist.
+        * @param declaringTypeName
+        *            Name of the type to which the method belongs. For inner types
+        *            the name must be qualified and include the outer types names
+        *            (dot separated). See
+        *            {@link net.sourceforge.phpdt.core.IType#getTypeQualifiedName(char)}.
+        * @param methodName
+        *            Name of the method.
+        * @param fieldName
+        *            Name of the field to get.
+        * @param fieldType
+        *            The type of the field to get.
+        * @param bareFieldName
+        *            The field name without prefix or suffix.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the generated getter comment or <code>null</code> if
+        *         the code template is empty. The returned content is not indented.
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        * @since 3.0
+        */
+       public static String getGetterComment(ICompilationUnit cu,
+                       String declaringTypeName, String methodName, String fieldName,
+                       String fieldType, String bareFieldName, String lineDelimiter)
+                       throws CoreException {
+               return StubUtility.getGetterComment(cu, declaringTypeName, methodName,
+                               fieldName, fieldType, bareFieldName, lineDelimiter);
+       }
+
+       /**
+        * Returns the comment for a setter method using the setter method body
+        * template. <code>null</code> is returned if the template is empty.
+        * <p>
+        * The returned string is unformatted and not indented.
+        * 
+        * @param cu
+        *            The compilation unit to which the method belongs. The
+        *            compilation unit does not need to exist.
+        * @param declaringTypeName
+        *            Name of the type to which the method belongs. For inner types
+        *            the name must be qualified and include the outer types names
+        *            (dot separated). See
+        *            {@link net.sourceforge.phpdt.core.IType#getTypeQualifiedName(char)}.
+        * @param methodName
+        *            Name of the method.
+        * @param fieldName
+        *            Name of the field that is set.
+        * @param fieldType
+        *            The type of the field that is to set.
+        * @param paramName
+        *            The name of the parameter that used to set.
+        * @param bareFieldName
+        *            The field name without prefix or suffix.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return Returns the generated setter comment or <code>null</code> if
+        *         the code template is empty. The returned comment is not indented.
+        * @throws CoreException
+        *             Thrown when the evaluation of the code template fails.
+        * @since 3.0
+        */
+       public static String getSetterComment(ICompilationUnit cu,
+                       String declaringTypeName, String methodName, String fieldName,
+                       String fieldType, String paramName, String bareFieldName,
+                       String lineDelimiter) throws CoreException {
+               return StubUtility.getSetterComment(cu, declaringTypeName, methodName,
+                               fieldName, fieldType, paramName, bareFieldName, lineDelimiter);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IContextMenuConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IContextMenuConstants.java
new file mode 100644 (file)
index 0000000..40fcd3c
--- /dev/null
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import org.eclipse.ui.IWorkbenchActionConstants;
+
+/**
+ * Constants for menu groups used in context menus for Java views and editors.
+ * <p>
+ * This interface declares constants only; it is not intended to be implemented.
+ * </p>
+ */
+public interface IContextMenuConstants {
+
+       /**
+        * Type hierarchy view part: pop-up menu target ID for type hierarchy viewer
+        * (value
+        * <code>"net.sourceforge.phpdt.ui.TypeHierarchy.typehierarchy"</code>).
+        * 
+        * @since 2.0
+        */
+       public static final String TARGET_ID_HIERARCHY_VIEW = JavaUI.ID_TYPE_HIERARCHY
+                       + ".typehierarchy"; //$NON-NLS-1$       
+
+       /**
+        * Type hierarchy view part: pop-up menu target ID for supertype hierarchy
+        * viewer (value
+        * <code>"net.sourceforge.phpdt.ui.TypeHierarchy.supertypes"</code>).
+        * 
+        * @since 2.0
+        */
+       public static final String TARGET_ID_SUPERTYPES_VIEW = JavaUI.ID_TYPE_HIERARCHY
+                       + ".supertypes"; //$NON-NLS-1$  
+
+       /**
+        * Type hierarchy view part: Pop-up menu target ID for the subtype hierarchy
+        * viewer (value
+        * <code>"net.sourceforge.phpdt.ui.TypeHierarchy.subtypes"</code>).
+        * 
+        * @since 2.0
+        */
+       public static final String TARGET_ID_SUBTYPES_VIEW = JavaUI.ID_TYPE_HIERARCHY
+                       + ".subtypes"; //$NON-NLS-1$    
+
+       /**
+        * Type hierarchy view part: pop-up menu target ID for the meber viewer
+        * (value <code>"net.sourceforge.phpdt.ui.TypeHierarchy.members"</code>).
+        * 
+        * @since 2.0
+        */
+       public static final String TARGET_ID_MEMBERS_VIEW = JavaUI.ID_TYPE_HIERARCHY
+                       + ".members"; //$NON-NLS-1$     
+
+       /**
+        * Pop-up menu: name of group for goto actions (value
+        * <code>"group.open"</code>).
+        * <p>
+        * Examples for open actions are:
+        * <ul>
+        * <li>Go Into</li>
+        * <li>Go To</li>
+        * </ul>
+        * </p>
+        */
+       public static final String GROUP_GOTO = "group.goto"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for open actions (value
+        * <code>"group.open"</code>).
+        * <p>
+        * Examples for open actions are:
+        * <ul>
+        * <li>Open To</li>
+        * <li>Open With</li>
+        * </ul>
+        * </p>
+        */
+       public static final String GROUP_OPEN = "group.open"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for show actions (value
+        * <code>"group.show"</code>).
+        * <p>
+        * Examples for show actions are:
+        * <ul>
+        * <li>Show in Navigator</li>
+        * <li>Show in Type Hierarchy</li>
+        * </ul>
+        * </p>
+        */
+       public static final String GROUP_SHOW = "group.show"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for new actions (value
+        * <code>"group.new"</code>).
+        * <p>
+        * Examples for new actions are:
+        * <ul>
+        * <li>Create new class</li>
+        * <li>Create new interface</li>
+        * </ul>
+        * </p>
+        */
+       public static final String GROUP_NEW = "group.new"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for build actions (value
+        * <code>"group.build"</code>).
+        */
+       public static final String GROUP_BUILD = "group.build"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for reorganize actions (value
+        * <code>"group.reorganize"</code>).
+        */
+       public static final String GROUP_REORGANIZE = IWorkbenchActionConstants.GROUP_REORGANIZE;
+
+       /**
+        * Pop-up menu: name of group for code generation actions ( value
+        * <code>"group.generate"</code>).
+        */
+       public static final String GROUP_GENERATE = "group.generate"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for source actions. This is an alias for
+        * <code>GROUP_GENERATE</code> to be more consistent with main menu bar
+        * structure.
+        * 
+        * @since 2.0
+        */
+       public static final String GROUP_SOURCE = GROUP_GENERATE;
+
+       /**
+        * Pop-up menu: name of group for search actions (value
+        * <code>"group.search"</code>).
+        */
+       public static final String GROUP_SEARCH = "group.search"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for additional actions (value
+        * <code>"additions"</code>).
+        */
+       public static final String GROUP_ADDITIONS = "additions"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for viewer setup actions (value
+        * <code>"group.viewerSetup"</code>).
+        */
+       public static final String GROUP_VIEWER_SETUP = "group.viewerSetup"; //$NON-NLS-1$
+
+       /**
+        * Pop-up menu: name of group for properties actions (value
+        * <code>"group.properties"</code>).
+        */
+       public static final String GROUP_PROPERTIES = "group.properties"; //$NON-NLS-1$
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IJavaElementSearchConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IJavaElementSearchConstants.java
new file mode 100644 (file)
index 0000000..699d33e
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+/**
+ * Search scope constants for Java selection dialogs.
+ * <p>
+ * This interface declares constants only; it is not intended to be implemented.
+ * </p>
+ * 
+ * @see JavaUI
+ */
+public interface IJavaElementSearchConstants {
+
+       /**
+        * Search scope constant (bit mask) indicating that classes should be
+        * considered. Used when opening certain kinds of selection dialogs.
+        */
+       public static final int CONSIDER_CLASSES = 1 << 1;
+
+       /**
+        * Search scope constant (bit mask) indicating that interfaces should be
+        * considered. Used when opening certain kinds of selection dialogs.
+        */
+       public static final int CONSIDER_INTERFACES = 1 << 2;
+
+       /**
+        * Search scope constant (bit mask) indicating that both classes and
+        * interfaces should be considered. Equivalent to
+        * <code>CONSIDER_CLASSES | CONSIDER_INTERFACES</code>.
+        */
+       public static final int CONSIDER_TYPES = CONSIDER_CLASSES
+                       | CONSIDER_INTERFACES;
+
+       /**
+        * Search scope constant (bit mask) indicating that binaries should be
+        * considered. Used when opening certain kinds of selection dialogs.
+        */
+       public static final int CONSIDER_BINARIES = 1 << 3;
+
+       /**
+        * Search scope constant (bit mask) indicating that external JARs should be
+        * considered. Used when opening certain kinds of selection dialogs.
+        */
+       public static final int CONSIDER_EXTERNAL_JARS = 1 << 4;
+
+       /**
+        * Search scope constant (bit mask) indicating that required projects should
+        * be considered. Used when opening certain kinds of selection dialogs.
+        * 
+        * @since 2.0
+        */
+       public static final int CONSIDER_REQUIRED_PROJECTS = 1 << 5;
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IPackagesViewPart.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IPackagesViewPart.java
new file mode 100644 (file)
index 0000000..5bb16f4
--- /dev/null
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.ui.IViewPart;
+
+/**
+ * The standard Packages view presents a Java-centric view of the workspace.
+ * Within Java projects, the resource hierarchy is organized into Java packages
+ * as described by the project's classpath. Note that this view shows both Java
+ * elements and ordinary resources.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ * 
+ * @see JavaUI#ID_PACKAGES
+ */
+public interface IPackagesViewPart extends IViewPart {
+       /**
+        * Selects and reveals the given element in this packages view. The tree
+        * will be expanded as needed to show the element.
+        * 
+        * @param element
+        *            the element to be revealed
+        */
+       void selectAndReveal(Object element);
+
+       /**
+        * Returns the TreeViewer shown in the Packages view.
+        * 
+        * @return the tree viewer used in the Packages view
+        * 
+        * @since 2.0
+        */
+       TreeViewer getTreeViewer();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/ITypeHierarchyViewPart.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/ITypeHierarchyViewPart.java
new file mode 100644 (file)
index 0000000..950238d
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IType;
+
+import org.eclipse.ui.IViewPart;
+
+/**
+ * The standard type hierarchy view presents a type hierarchy for a given input
+ * class or interface. Visually, this view consists of a pair of viewers, one
+ * showing the type hierarchy, the other showing the members of the type
+ * selected in the first.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ * 
+ * @see JavaUI#ID_TYPE_HIERARCHY
+ */
+public interface ITypeHierarchyViewPart extends IViewPart {
+
+       /**
+        * Sets the input element of this type hierarchy view to a type.
+        * 
+        * @param type
+        *            the input element of this type hierarchy view, or
+        *            <code>null</code> to clear any input element
+        * @deprecated use setInputElement instead
+        */
+       public void setInput(IType type);
+
+       /**
+        * Sets the input element of this type hierarchy view. The following input
+        * types are possible <code>IMember</code> (types, methods, fields..),
+        * <code>IPackageFragment</code>, <code>IPackageFragmentRoot</code> and
+        * <code>IJavaProject</code>.
+        * 
+        * @param element
+        *            the input element of this type hierarchy view, or
+        *            <code>null</code> to clear any input
+        * 
+        * @since 2.0
+        */
+       public void setInputElement(IJavaElement element);
+
+       /**
+        * Returns the input element of this type hierarchy view.
+        * 
+        * @return the input element, or <code>null</code> if no input element is
+        *         set
+        * @see #setInput(IType)
+        * @deprecated use getInputElement instead
+        */
+       public IType getInput();
+
+       /**
+        * Returns the input element of this type hierarchy view.
+        * 
+        * @return the input element, or <code>null</code> if no input element is
+        *         set
+        * @see #setInputElement(IJavaElement)
+        * 
+        * @since 2.0
+        */
+       public IJavaElement getInputElement();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyManager.java
new file mode 100644 (file)
index 0000000..e0be2c6
--- /dev/null
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * Interface for accessing working copies of <code>ICompilationUnit</code>
+ * objects. The original compilation unit is only given indirectly by means of
+ * an <code>IEditorInput</code>. The life cycle is as follows:
+ * <ul>
+ * <li> <code>connect</code> creates and remembers a working copy of the
+ * compilation unit which is encoded in the given editor input</li>
+ * <li> <code>getWorkingCopy</code> returns the working copy remembered on
+ * <code>connect</code></li>
+ * <li> <code>disconnect</code> destroys the working copy remembered on
+ * <code>connect</code></li>
+ * </ul>
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ * 
+ * @see JavaUI#getWorkingCopyManager
+ */
+public interface IWorkingCopyManager {
+
+       /**
+        * Connects the given editor input to this manager. After calling this
+        * method, a working copy will be available for the compilation unit encoded
+        * in the given editor input (does nothing if there is no encoded
+        * compilation unit).
+        * 
+        * @param input
+        *            the editor input
+        * @exception CoreException
+        *                if the working copy cannot be created for the compilation
+        *                unit
+        */
+       void connect(IEditorInput input) throws CoreException;
+
+       /**
+        * Disconnects the given editor input from this manager. After calling this
+        * method, a working copy for the compilation unit encoded in the given
+        * editor input will no longer be available. Does nothing if there is no
+        * encoded compilation unit, or if there is no remembered working copy for
+        * the compilation unit.
+        * 
+        * @param input
+        *            the editor input
+        */
+       void disconnect(IEditorInput input);
+
+       /**
+        * Returns the working copy remembered for the compilation unit encoded in
+        * the given editor input.
+        * 
+        * @param input
+        *            the editor input
+        * @return the working copy of the compilation unit, or <code>null</code>
+        *         if the input does not encode an editor input, or if there is no
+        *         remembered working copy for this compilation unit
+        */
+       ICompilationUnit getWorkingCopy(IEditorInput input);
+
+       /**
+        * Shuts down this working copy manager. All working copies still remembered
+        * by this manager are destroyed.
+        */
+       void shutdown();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyManagerExtension.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyManagerExtension.java
new file mode 100644 (file)
index 0000000..1e354a9
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * Extension interface for <code>IWorkingCopyManager</code>.
+ * 
+ * @since 2.1
+ */
+public interface IWorkingCopyManagerExtension {
+
+       /**
+        * Sets the given working copy for the given editor input. If the given
+        * editor input is not connected to this working copy manager, this call has
+        * no effect.
+        * <p>
+        * This working copy manager does not assume the ownership of this working
+        * copy, i.e., the given working copy is not automatically be freed when
+        * this manager is shut down.
+        * 
+        * @param input
+        *            the editor input
+        * @param workingCopy
+        *            the working copy
+        */
+       void setWorkingCopy(IEditorInput input, ICompilationUnit workingCopy);
+
+       /**
+        * Removes the working copy set for the given editor input. If there is no
+        * working copy set for this input or this input is not connected to this
+        * working copy manager, this call has no effect.
+        * 
+        * @param input
+        *            the editor input
+        */
+       void removeWorkingCopy(IEditorInput input);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/IWorkingCopyProvider.java
new file mode 100644 (file)
index 0000000..7f0a3e0
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+/**
+ * Interface used for Java element content providers to indicate that the
+ * content provider can return working copy elements for members below
+ * compilation units.
+ * 
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ * 
+ * @see net.sourceforge.phpdt.ui.StandardJavaElementContentProvider
+ * @see net.sourceforge.phpdt.core.IWorkingCopy
+ * 
+ * @since 2.0
+ */
+public interface IWorkingCopyProvider {
+
+       /**
+        * Returns <code>true</code> if the content provider returns working copy
+        * elements; otherwise <code>false</code> is returned.
+        * 
+        * @return whether working copy elements are provided.
+        */
+       public boolean providesWorkingCopies();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementImageDescriptor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementImageDescriptor.java
new file mode 100644 (file)
index 0000000..e008eff
--- /dev/null
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * A JavaImageDescriptor 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 <code>setAdornments</code>.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class JavaElementImageDescriptor extends CompositeImageDescriptor {
+
+       /** Flag to render the abstract adornment */
+       public final static int ABSTRACT = 0x001;
+
+       /** Flag to render the final adornment */
+       public final static int FINAL = 0x002;
+
+       /** Flag to render the synchronized adornment */
+       public final static int SYNCHRONIZED = 0x004;
+
+       /** Flag to render the static adornment */
+       public final static int STATIC = 0x008;
+
+       /** Flag to render the runnable adornment */
+       public final static int RUNNABLE = 0x010;
+
+       /** Flag to render the waring adornment */
+       public final static int WARNING = 0x020;
+
+       /** Flag to render the error adornment */
+       public final static int ERROR = 0x040;
+
+       /** Flag to render the 'override' adornment */
+       public final static int OVERRIDES = 0x080;
+
+       /** Flag to render the 'implements' adornment */
+       public final static int IMPLEMENTS = 0x100;
+
+       /** Flag to render the 'constructor' adornment */
+       public final static int CONSTRUCTOR = 0x200;
+
+       private ImageDescriptor fBaseImage;
+
+       private int fFlags;
+
+       private Point fSize;
+
+       /**
+        * Creates a new JavaElementImageDescriptor.
+        * 
+        * @param baseImage
+        *            an image descriptor used as the base image
+        * @param flags
+        *            flags indicating which adornments are to be rendered. See
+        *            <code>setAdornments</code> for valid values.
+        * @param size
+        *            the size of the resulting image
+        * @see #setAdornments(int)
+        */
+       public JavaElementImageDescriptor(ImageDescriptor baseImage, int flags,
+                       Point size) {
+               fBaseImage = baseImage;
+               Assert.isNotNull(fBaseImage);
+               fFlags = flags;
+               Assert.isTrue(fFlags >= 0);
+               fSize = size;
+               Assert.isNotNull(fSize);
+       }
+
+       /**
+        * Sets the descriptors adornments. Valid values are: <code>ABSTRACT</code>,
+        * <code>FINAL</code>, <code>SYNCHRONIZED</code>, </code>STATIC<code>,
+        * </code>RUNNABLE<code>, </code>WARNING<code>, </code>ERROR<code>,
+        * </code>OVERRIDDES<code>, <code>IMPLEMENTS</code>,
+        * <code>CONSTRUCTOR</code>, or any combination of those.
+        * 
+        * @param adornments
+        *            the image descritpors adornments
+        */
+       public void setAdornments(int adornments) {
+               Assert.isTrue(adornments >= 0);
+               fFlags = adornments;
+       }
+
+       /**
+        * Returns the current adornments.
+        * 
+        * @return the current adornments
+        */
+       public int getAdronments() {
+               return fFlags;
+       }
+
+       /**
+        * Sets the size of the image created by calling <code>createImage()</code>.
+        * 
+        * @param size
+        *            the size of the image returned from calling
+        *            <code>createImage()</code>
+        * @see ImageDescriptor#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
+        * <code>createImage()</code>.
+        * 
+        * @return the size of the image created by calling
+        *         <code>createImage()</code>
+        * @see ImageDescriptor#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
+                               || !JavaElementImageDescriptor.class.equals(object.getClass()))
+                       return false;
+
+               JavaElementImageDescriptor other = (JavaElementImageDescriptor) 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;
+               if ((bg = fBaseImage.getImageData()) == null)
+                       bg = DEFAULT_IMAGE_DATA;
+
+               drawImage(bg, 0, 0);
+               drawTopRight();
+               drawBottomRight();
+               drawBottomLeft();
+       }
+
+       private void drawTopRight() {
+               int x = getSize().x;
+               ImageData data = null;
+               if ((fFlags & ABSTRACT) != 0) {
+                       data = PHPUiImages.DESC_OVR_ABSTRACT.getImageData();
+                       x -= data.width;
+                       drawImage(data, x, 0);
+               }
+               if ((fFlags & CONSTRUCTOR) != 0) {
+                       data = PHPUiImages.DESC_OVR_CONSTRUCTOR.getImageData();
+                       x -= data.width;
+                       drawImage(data, x, 0);
+               }
+               if ((fFlags & FINAL) != 0) {
+                       data = PHPUiImages.DESC_OVR_FINAL.getImageData();
+                       x -= data.width;
+                       drawImage(data, x, 0);
+               }
+               if ((fFlags & STATIC) != 0) {
+                       data = PHPUiImages.DESC_OVR_STATIC.getImageData();
+                       x -= data.width;
+                       drawImage(data, x, 0);
+               }
+       }
+
+       private void drawBottomRight() {
+               Point size = getSize();
+               int x = size.x;
+               ImageData data = null;
+               if ((fFlags & OVERRIDES) != 0) {
+                       data = PHPUiImages.DESC_OVR_OVERRIDES.getImageData();
+                       x -= data.width;
+                       drawImage(data, x, size.y - data.height);
+               }
+               if ((fFlags & IMPLEMENTS) != 0) {
+                       data = PHPUiImages.DESC_OVR_IMPLEMENTS.getImageData();
+                       x -= data.width;
+                       drawImage(data, x, size.y - data.height);
+               }
+               if ((fFlags & SYNCHRONIZED) != 0) {
+                       data = PHPUiImages.DESC_OVR_SYNCH.getImageData();
+                       x -= data.width;
+                       drawImage(data, x, size.y - data.height);
+               }
+               if ((fFlags & RUNNABLE) != 0) {
+                       data = PHPUiImages.DESC_OVR_RUN.getImageData();
+                       x -= data.width;
+                       drawImage(data, x, size.y - data.height);
+               }
+       }
+
+       private void drawBottomLeft() {
+               Point size = getSize();
+               int x = 0;
+               ImageData data = null;
+               if ((fFlags & ERROR) != 0) {
+                       data = PHPUiImages.DESC_OVR_ERROR.getImageData();
+                       drawImage(data, x, size.y - data.height);
+                       x += data.width;
+               }
+               if ((fFlags & WARNING) != 0) {
+                       data = PHPUiImages.DESC_OVR_WARNING.getImageData();
+                       drawImage(data, x, size.y - data.height);
+                       x += data.width;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementLabelProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementLabelProvider.java
new file mode 100644 (file)
index 0000000..44eb464
--- /dev/null
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementImageProvider;
+import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementLabels;
+import net.sourceforge.phpdt.internal.ui.viewsupport.StorageLabelProvider;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Standard label provider for Java elements. Use this class when you want to
+ * present the Java elements in a viewer.
+ * <p>
+ * The implementation also handles non-Java elements by forwarding the requests
+ * to the <code>IWorkbenchAdapter</code> of the element.
+ * </p>
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ */
+public class JavaElementLabelProvider extends LabelProvider {
+
+       /**
+        * Flag (bit mask) indicating that methods labels include the method return
+        * type. (appended)
+        */
+       public final static int SHOW_RETURN_TYPE = 0x001;
+
+       /**
+        * Flag (bit mask) indicating that method label include method parameter
+        * types.
+        */
+       public final static int SHOW_PARAMETERS = 0x002;
+
+       /**
+        * Flag (bit mask) indicating that the label of a member should include the
+        * container. For example, include the name of the type enclosing a field.
+        * 
+        * @deprecated Use SHOW_QUALIFIED or SHOW_ROOT instead
+        */
+       public final static int SHOW_CONTAINER = 0x004;
+
+       /**
+        * Flag (bit mask) indicating that the label of a type should be fully
+        * qualified. For example, include the fully qualified name of the type
+        * enclosing a type.
+        * 
+        * @deprecated Use SHOW_QUALIFIED instead
+        */
+       public final static int SHOW_CONTAINER_QUALIFICATION = 0x008;
+
+       /**
+        * Flag (bit mask) indicating that the label should include overlay icons
+        * for element type and modifiers.
+        */
+       public final static int SHOW_OVERLAY_ICONS = 0x010;
+
+       /**
+        * Flag (bit mask) indicating thata field label should include the declared
+        * type.
+        */
+       public final static int SHOW_TYPE = 0x020;
+
+       /**
+        * Flag (bit mask) indicating that the label should include the name of the
+        * package fragment root (appended).
+        */
+       public final static int SHOW_ROOT = 0x040;
+
+       /**
+        * Flag (bit mask) indicating that the label qualification of a type should
+        * be shown after the name.
+        * 
+        * @deprecated SHOW_POST_QUALIFIED instead
+        */
+       public final static int SHOW_POSTIFIX_QUALIFICATION = 0x080;
+
+       /**
+        * Flag (bit mask) indicating that the label should show the icons with no
+        * space reserved for overlays.
+        */
+       public final static int SHOW_SMALL_ICONS = 0x100;
+
+       /**
+        * Flag (bit mask) indicating that the packagefragment roots from variables
+        * should be rendered with the variable in the name
+        */
+       public final static int SHOW_VARIABLE = 0x200;
+
+       /**
+        * Flag (bit mask) indicating that Complation Units, Class Files, Types,
+        * Declarations and Members should be rendered qualified. Examples:
+        * java.lang.String, java.util.Vector.size()
+        * 
+        * @since 2.0
+        */
+       public final static int SHOW_QUALIFIED = 0x400;
+
+       /**
+        * Flag (bit mask) indicating that Complation Units, Class Files, Types,
+        * Declarations and Members should be rendered qualified. The qualifcation
+        * is appended Examples: String - java.lang, size() - java.util.Vector
+        * 
+        * @since 2.0
+        */
+       public final static int SHOW_POST_QUALIFIED = 0x800;
+
+       /**
+        * Constant (value <code>0</code>) indicating that the label should show
+        * the basic images only.
+        */
+       public final static int SHOW_BASICS = 0x000;
+
+       /**
+        * Constant indicating the default label rendering. Currently the default is
+        * equivalent to <code>SHOW_PARAMETERS | SHOW_OVERLAY_ICONS</code>.
+        */
+       public final static int SHOW_DEFAULT = new Integer(SHOW_PARAMETERS
+                       | SHOW_OVERLAY_ICONS).intValue();
+
+       private JavaElementImageProvider fImageLabelProvider;
+
+       private StorageLabelProvider fStorageLabelProvider;
+
+       private int fFlags;
+
+       private int fImageFlags;
+
+       private int fTextFlags;
+
+       /**
+        * Creates a new label provider with <code>SHOW_DEFAULT</code> flag.
+        * 
+        * @see #SHOW_DEFAULT
+        * @since 2.0
+        */
+       public JavaElementLabelProvider() {
+               this(SHOW_DEFAULT);
+       }
+
+       /**
+        * Creates a new label provider.
+        * 
+        * @param flags
+        *            the initial options; a bitwise OR of <code>SHOW_* </code>
+        *            constants
+        */
+       public JavaElementLabelProvider(int flags) {
+               fImageLabelProvider = new JavaElementImageProvider();
+               fStorageLabelProvider = new StorageLabelProvider();
+               fFlags = flags;
+               updateImageProviderFlags();
+               updateTextProviderFlags();
+       }
+
+       private boolean getFlag(int flag) {
+               return (fFlags & flag) != 0;
+       }
+
+       /**
+        * Turns on the rendering options specified in the given flags.
+        * 
+        * @param flags
+        *            the options; a bitwise OR of <code>SHOW_* </code> constants
+        */
+       public void turnOn(int flags) {
+               fFlags |= flags;
+               updateImageProviderFlags();
+               updateTextProviderFlags();
+       }
+
+       /**
+        * Turns off the rendering options specified in the given flags.
+        * 
+        * @param flags
+        *            the initial options; a bitwise OR of <code>SHOW_* </code>
+        *            constants
+        */
+       public void turnOff(int flags) {
+               fFlags &= (~flags);
+               updateImageProviderFlags();
+               updateTextProviderFlags();
+       }
+
+       private void updateImageProviderFlags() {
+               fImageFlags = 0;
+               if (getFlag(SHOW_OVERLAY_ICONS)) {
+                       fImageFlags |= JavaElementImageProvider.OVERLAY_ICONS;
+               }
+               if (getFlag(SHOW_SMALL_ICONS)) {
+                       fImageFlags |= JavaElementImageProvider.SMALL_ICONS;
+               }
+       }
+
+       private void updateTextProviderFlags() {
+               fTextFlags = 0;
+               if (getFlag(SHOW_RETURN_TYPE)) {
+                       fTextFlags |= JavaElementLabels.M_APP_RETURNTYPE;
+               }
+               if (getFlag(SHOW_PARAMETERS)) {
+                       fTextFlags |= JavaElementLabels.M_PARAMETER_TYPES;
+               }
+               if (getFlag(SHOW_CONTAINER)) {
+                       fTextFlags |= JavaElementLabels.P_POST_QUALIFIED
+                                       | JavaElementLabels.T_POST_QUALIFIED
+                                       | JavaElementLabels.CF_POST_QUALIFIED
+                                       | JavaElementLabels.CU_POST_QUALIFIED
+                                       | JavaElementLabels.M_POST_QUALIFIED
+                                       | JavaElementLabels.F_POST_QUALIFIED;
+               }
+               if (getFlag(SHOW_POSTIFIX_QUALIFICATION)) {
+                       fTextFlags |= (JavaElementLabels.T_POST_QUALIFIED
+                                       | JavaElementLabels.CF_POST_QUALIFIED | JavaElementLabels.CU_POST_QUALIFIED);
+               } else if (getFlag(SHOW_CONTAINER_QUALIFICATION)) {
+                       fTextFlags |= (JavaElementLabels.T_FULLY_QUALIFIED
+                                       | JavaElementLabels.CF_QUALIFIED | JavaElementLabels.CU_QUALIFIED);
+               }
+               if (getFlag(SHOW_TYPE)) {
+                       fTextFlags |= JavaElementLabels.F_APP_TYPE_SIGNATURE;
+               }
+               if (getFlag(SHOW_ROOT)) {
+                       fTextFlags |= JavaElementLabels.APPEND_ROOT_PATH;
+               }
+               if (getFlag(SHOW_VARIABLE)) {
+                       fTextFlags |= JavaElementLabels.ROOT_VARIABLE;
+               }
+               if (getFlag(SHOW_QUALIFIED)) {
+                       fTextFlags |= (JavaElementLabels.F_FULLY_QUALIFIED
+                                       | JavaElementLabels.M_FULLY_QUALIFIED
+                                       | JavaElementLabels.I_FULLY_QUALIFIED
+                                       | JavaElementLabels.T_FULLY_QUALIFIED
+                                       | JavaElementLabels.D_QUALIFIED
+                                       | JavaElementLabels.CF_QUALIFIED | JavaElementLabels.CU_QUALIFIED);
+               }
+               if (getFlag(SHOW_POST_QUALIFIED)) {
+                       fTextFlags |= (JavaElementLabels.F_POST_QUALIFIED
+                                       | JavaElementLabels.M_POST_QUALIFIED
+                                       | JavaElementLabels.I_POST_QUALIFIED
+                                       | JavaElementLabels.T_POST_QUALIFIED
+                                       | JavaElementLabels.D_POST_QUALIFIED
+                                       | JavaElementLabels.CF_POST_QUALIFIED | JavaElementLabels.CU_POST_QUALIFIED);
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see ILabelProvider#getImage
+        */
+       public Image getImage(Object element) {
+               Image result = fImageLabelProvider.getImageLabel(element, fImageFlags);
+               if (result != null) {
+                       return result;
+               }
+
+               if (element instanceof IStorage)
+                       return fStorageLabelProvider.getImage(element);
+
+               return result;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see ILabelProvider#getText
+        */
+       public String getText(Object element) {
+               String text = JavaElementLabels.getTextLabel(element, fTextFlags);
+               if (text.length() > 0) {
+                       return text;
+               }
+
+               if (element instanceof IStorage)
+                       return fStorageLabelProvider.getText(element);
+
+               return text;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IBaseLabelProvider#dispose
+        */
+       public void dispose() {
+               fStorageLabelProvider.dispose();
+               fImageLabelProvider.dispose();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementSorter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaElementSorter.java
new file mode 100644 (file)
index 0000000..2d66b7d
--- /dev/null
@@ -0,0 +1,353 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import java.text.Collator;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IField;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.Signature;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+import net.sourceforge.phpdt.internal.corext.util.JdtFlags;
+import net.sourceforge.phpdt.internal.ui.preferences.MembersOrderPreferenceCache;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.ContentViewer;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+
+/**
+ * Sorter for Java elements. Ordered by element category, then by element name.
+ * Package fragment roots are sorted as ordered on the classpath.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class JavaElementSorter extends ViewerSorter {
+
+       private static final int PROJECTS = 1;
+
+       private static final int PACKAGEFRAGMENTROOTS = 2;
+
+       private static final int PACKAGEFRAGMENT = 3;
+
+       private static final int COMPILATIONUNITS = 4;
+
+       private static final int CLASSFILES = 5;
+
+       private static final int RESOURCEFOLDERS = 7;
+
+       private static final int RESOURCES = 8;
+
+       private static final int STORAGE = 9;
+
+       private static final int PACKAGE_DECL = 10;
+
+       private static final int IMPORT_CONTAINER = 11;
+
+       private static final int IMPORT_DECLARATION = 12;
+
+       // Includes all categories ordered using the OutlineSortOrderPage:
+       // types, initializers, methods & fields
+       private static final int MEMBERSOFFSET = 15;
+
+       private static final int JAVAELEMENTS = 50;
+
+       private static final int OTHERS = 51;
+
+       private MembersOrderPreferenceCache fMemberOrderCache;
+
+       /**
+        * Constructor.
+        */
+       public JavaElementSorter() {
+               super(null); // delay initialization of collator
+               fMemberOrderCache = WebUI.getDefault()
+                               .getMemberOrderPreferenceCache();
+       }
+
+       /**
+        * @deprecated Bug 22518. Method never used: does not override
+        *             ViewerSorter#isSorterProperty(Object, String). Method could
+        *             be removed, but kept for API compatibility.
+        */
+       public boolean isSorterProperty(Object element, Object property) {
+               return true;
+       }
+
+       /*
+        * @see ViewerSorter#category
+        */
+       public int category(Object element) {
+               if (element instanceof IJavaElement) {
+                       try {
+                               IJavaElement je = (IJavaElement) element;
+
+                               switch (je.getElementType()) {
+                               case IJavaElement.METHOD: {
+                                       IMethod method = (IMethod) je;
+                                       if (method.isConstructor()) {
+                                               return getMemberCategory(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX);
+                                       }
+                                       int flags = method.getFlags();
+                                       if (Flags.isStatic(flags))
+                                               return getMemberCategory(MembersOrderPreferenceCache.STATIC_METHODS_INDEX);
+                                       else
+                                               return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX);
+                               }
+                               case IJavaElement.FIELD: {
+                                       int flags = ((IField) je).getFlags();
+                                       if (Flags.isStatic(flags))
+                                               return getMemberCategory(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX);
+                                       else
+                                               return getMemberCategory(MembersOrderPreferenceCache.FIELDS_INDEX);
+                               }
+                                       // case IJavaElement.INITIALIZER :
+                                       // {
+                                       // int flags= ((IInitializer) je).getFlags();
+                                       // if (Flags.isStatic(flags))
+                                       // return
+                                       // getMemberCategory(MembersOrderPreferenceCache.STATIC_INIT_INDEX);
+                                       // else
+                                       // return
+                                       // getMemberCategory(MembersOrderPreferenceCache.INIT_INDEX);
+                                       // }
+                               case IJavaElement.TYPE:
+                                       return getMemberCategory(MembersOrderPreferenceCache.TYPE_INDEX);
+                               case IJavaElement.PACKAGE_DECLARATION:
+                                       return PACKAGE_DECL;
+                               case IJavaElement.IMPORT_CONTAINER:
+                                       return IMPORT_CONTAINER;
+                               case IJavaElement.IMPORT_DECLARATION:
+                                       return IMPORT_DECLARATION;
+                               case IJavaElement.PACKAGE_FRAGMENT:
+                                       IPackageFragment pack = (IPackageFragment) je;
+                                       if (pack.getParent().getResource() instanceof IProject) {
+                                               return PACKAGEFRAGMENTROOTS;
+                                       }
+                                       return PACKAGEFRAGMENT;
+                               case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+                                       return PACKAGEFRAGMENTROOTS;
+                               case IJavaElement.JAVA_PROJECT:
+                                       return PROJECTS;
+                               case IJavaElement.CLASS_FILE:
+                                       return CLASSFILES;
+                               case IJavaElement.COMPILATION_UNIT:
+                                       return COMPILATIONUNITS;
+                               }
+
+                       } catch (JavaModelException e) {
+                               if (!e.isDoesNotExist())
+                                       PHPeclipsePlugin.log(e);
+                       }
+                       return JAVAELEMENTS;
+               } else if (element instanceof IFile) {
+                       return RESOURCES;
+               } else if (element instanceof IProject) {
+                       return PROJECTS;
+               } else if (element instanceof IContainer) {
+                       return RESOURCEFOLDERS;
+               } else if (element instanceof IStorage) {
+                       return STORAGE;
+               }
+               // else if (element instanceof ClassPathContainer) {
+               // return PACKAGEFRAGMENTROOTS;
+               // }
+               return OTHERS;
+       }
+
+       private int getMemberCategory(int kind) {
+               int offset = fMemberOrderCache.getCategoryIndex(kind);
+               return offset + MEMBERSOFFSET;
+       }
+
+       /*
+        * @see ViewerSorter#compare
+        */
+       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 == PROJECTS) {
+                       IWorkbenchAdapter a1 = (IWorkbenchAdapter) ((IAdaptable) e1)
+                                       .getAdapter(IWorkbenchAdapter.class);
+                       IWorkbenchAdapter a2 = (IWorkbenchAdapter) ((IAdaptable) e2)
+                                       .getAdapter(IWorkbenchAdapter.class);
+                       return getCollator().compare(a1.getLabel(e1), a2.getLabel(e2));
+               }
+
+               if (cat1 == PACKAGEFRAGMENTROOTS) {
+                       IPackageFragmentRoot root1 = getPackageFragmentRoot(e1);
+                       IPackageFragmentRoot root2 = getPackageFragmentRoot(e2);
+                       if (root1 == null) {
+                               if (root2 == null) {
+                                       return 0;
+                               } else {
+                                       return 1;
+                               }
+                       } else if (root2 == null) {
+                               return -1;
+                       }
+                       if (!root1.getPath().equals(root2.getPath())) {
+                               int p1 = getClassPathIndex(root1);
+                               int p2 = getClassPathIndex(root2);
+                               if (p1 != p2) {
+                                       return p1 - p2;
+                               }
+                       }
+                       e1 = root1; // normalize classpath container to root
+                       e2 = root2;
+               }
+               // non - java resources are sorted using the label from the viewers
+               // label provider
+               if (cat1 == PROJECTS || cat1 == RESOURCES || cat1 == RESOURCEFOLDERS
+                               || cat1 == STORAGE || cat1 == OTHERS) {
+                       return compareWithLabelProvider(viewer, e1, e2);
+               }
+
+               if (e1 instanceof IMember) {
+                       if (fMemberOrderCache.isSortByVisibility()) {
+                               try {
+                                       int flags1 = JdtFlags.getVisibilityCode((IMember) e1);
+                                       int flags2 = JdtFlags.getVisibilityCode((IMember) e2);
+                                       int vis = fMemberOrderCache.getVisibilityIndex(flags1)
+                                                       - fMemberOrderCache.getVisibilityIndex(flags2);
+                                       if (vis != 0) {
+                                               return vis;
+                                       }
+                               } catch (JavaModelException ignore) {
+                               }
+                       }
+               }
+
+               String name1 = ((IJavaElement) e1).getElementName();
+               String name2 = ((IJavaElement) e2).getElementName();
+
+               if (e1 instanceof IType) { // handle anonymous types
+                       if (name1.length() == 0) {
+                               if (name2.length() == 0) {
+                                       try {
+                                               return getCollator().compare(
+                                                               ((IType) e1).getSuperclassName(),
+                                                               ((IType) e2).getSuperclassName());
+                                       } catch (JavaModelException e) {
+                                               return 0;
+                                       }
+                               } else {
+                                       return 1;
+                               }
+                       } else if (name2.length() == 0) {
+                               return -1;
+                       }
+               }
+
+               int cmp = getCollator().compare(name1, name2);
+               if (cmp != 0) {
+                       return cmp;
+               }
+
+               if (e1 instanceof IMethod) {
+                       String[] params1 = ((IMethod) e1).getParameterTypes();
+                       String[] params2 = ((IMethod) e2).getParameterTypes();
+                       int len = Math.min(params1.length, params2.length);
+                       for (int i = 0; i < len; i++) {
+                               cmp = getCollator().compare(Signature.toString(params1[i]),
+                                               Signature.toString(params2[i]));
+                               if (cmp != 0) {
+                                       return cmp;
+                               }
+                       }
+                       return params1.length - params2.length;
+               }
+               return 0;
+       }
+
+       private IPackageFragmentRoot getPackageFragmentRoot(Object element) {
+               // if (element instanceof ClassPathContainer) {
+               // // return first package fragment root from the container
+               // ClassPathContainer cp= (ClassPathContainer)element;
+               // Object[] roots= cp.getPackageFragmentRoots();
+               // if (roots.length > 0)
+               // return (IPackageFragmentRoot)roots[0];
+               // // non resolvable - return null
+               // return null;
+               // }
+               return JavaModelUtil.getPackageFragmentRoot((IJavaElement) element);
+       }
+
+       private int compareWithLabelProvider(Viewer viewer, Object e1, Object e2) {
+               if (viewer == null || !(viewer instanceof ContentViewer)) {
+                       IBaseLabelProvider prov = ((ContentViewer) viewer)
+                                       .getLabelProvider();
+                       if (prov instanceof ILabelProvider) {
+                               ILabelProvider lprov = (ILabelProvider) prov;
+                               String name1 = lprov.getText(e1);
+                               String name2 = lprov.getText(e2);
+                               if (name1 != null && name2 != null) {
+                                       return getCollator().compare(name1, name2);
+                               }
+                       }
+               }
+               return 0; // can't compare
+       }
+
+       private int getClassPathIndex(IPackageFragmentRoot root) {
+               try {
+                       IPath rootPath = root.getPath();
+                       IPackageFragmentRoot[] roots = root.getJavaProject()
+                                       .getPackageFragmentRoots();
+                       for (int i = 0; i < roots.length; i++) {
+                               if (roots[i].getPath().equals(rootPath)) {
+                                       return i;
+                               }
+                       }
+               } catch (JavaModelException e) {
+               }
+
+               return Integer.MAX_VALUE;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.viewers.ViewerSorter#getCollator()
+        */
+       public final Collator getCollator() {
+               if (collator == null) {
+                       collator = Collator.getInstance();
+               }
+               return collator;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaUI.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/JavaUI.java
new file mode 100644 (file)
index 0000000..ae2fecf
--- /dev/null
@@ -0,0 +1,809 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.core.IBufferFactory;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IWorkingCopy;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.EditorUtility;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.internal.SharedImages;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+
+/**
+ * Central access point for the Java UI plug-in (id
+ * <code>"net.sourceforge.phpdt.ui"</code>). This class provides static
+ * methods for:
+ * <ul>
+ * <li> creating various kinds of selection dialogs to present a collection of
+ * Java elements to the user and let them make a selection.</li>
+ * <li> opening a Java editor on a compilation unit.</li>
+ * </ul>
+ * <p>
+ * This class provides static methods and fields only; it is not intended to be
+ * instantiated or subclassed by clients.
+ * </p>
+ */
+public final class JavaUI {
+
+       private static ISharedImages fgSharedImages = null;
+
+       private JavaUI() {
+               // prevent instantiation of JavaUI.
+       }
+
+       /**
+        * The id of the Java plugin (value <code>"net.sourceforge.phpdt.ui"</code>).
+        */
+       // public static final String ID_PLUGIN= "net.sourceforge.phpdt.ui";
+       // //$NON-NLS-1$
+       /**
+        * The id of the Java perspective (value
+        * <code>"net.sourceforge.phpdt.ui.JavaPerspective"</code>).
+        */
+        public static final String ID_PERSPECTIVE=
+        "net.sourceforge.phpdt.ui.JavaPerspective"; //$NON-NLS-1$
+       /**
+        * The id of the Java hierarchy perspective (value
+        * <code>"net.sourceforge.phpdt.ui.JavaHierarchyPerspective"</code>).
+        */
+       // public static final String ID_HIERARCHYPERSPECTIVE=
+       // "net.sourceforge.phpdt.ui.JavaHierarchyPerspective"; //$NON-NLS-1$
+       /**
+        * The id of the Java action set (value
+        * <code>"net.sourceforge.phpdt.ui.JavaActionSet"</code>).
+        */
+       // public static final String ID_ACTION_SET=
+       // "net.sourceforge.phpdt.ui.JavaActionSet"; //$NON-NLS-1$
+       /**
+        * The id of the Java Element Creation action set (value
+        * <code>"net.sourceforge.phpdt.ui.JavaElementCreationActionSet"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static final String ID_ELEMENT_CREATION_ACTION_SET=
+       // "net.sourceforge.phpdt.ui.JavaElementCreationActionSet"; //$NON-NLS-1$
+       /**
+        * The id of the Java Coding action set (value
+        * <code>"net.sourceforge.phpdt.ui.CodingActionSet"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static final String ID_CODING_ACTION_SET=
+       // "net.sourceforge.phpdt.ui.CodingActionSet"; //$NON-NLS-1$
+       /**
+        * The id of the Java action set for open actions (value
+        * <code>"net.sourceforge.phpdt.ui.A_OpenActionSet"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static final String ID_OPEN_ACTION_SET=
+       // "net.sourceforge.phpdt.ui.A_OpenActionSet"; //$NON-NLS-1$
+       /**
+        * The id of the Java Search action set (value
+        * <code>net.sourceforge.phpdt.ui.SearchActionSet"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static final String ID_SEARCH_ACTION_SET=
+       // "net.sourceforge.phpdt.ui.SearchActionSet"; //$NON-NLS-1$
+       /**
+        * The editor part id of the editor that presents Java compilation units
+        * (value <code>"net.sourceforge.phpdt.ui.CompilationUnitEditor"</code>).
+        */
+       // public static final String ID_CU_EDITOR=
+       // "net.sourceforge.phpdt.ui.PHPUnitEditor"; //$NON-NLS-1$
+       /**
+        * The editor part id of the editor that presents Java binary class files
+        * (value <code>"net.sourceforge.phpdt.ui.ClassFileEditor"</code>).
+        */
+       // public static final String ID_CF_EDITOR=
+       // "net.sourceforge.phpdt.ui.ClassFileEditor"; //$NON-NLS-1$
+       /**
+        * The editor part id of the code snippet editor (value
+        * <code>"net.sourceforge.phpdt.ui.SnippetEditor"</code>).
+        */
+       // public static final String ID_SNIPPET_EDITOR=
+       // "net.sourceforge.phpdt.ui.SnippetEditor"; //$NON-NLS-1$
+       /**
+        * The view part id of the Packages view (value
+        * <code>"net.sourceforge.phpdt.ui.PackageExplorer"</code>).
+        * <p>
+        * When this id is used to access a view part with
+        * <code>IWorkbenchPage.findView</code> or <code>showView</code>, the
+        * returned <code>IViewPart</code> can be safely cast to an
+        * <code>IPackagesViewPart</code>.
+        * </p>
+        * 
+        * @see IPackagesViewPart
+        * @see org.eclipse.ui.IWorkbenchPage#findView(java.lang.String)
+        * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String)
+        */
+       public static final String ID_PACKAGES = "net.sourceforge.phpdt.ui.PackageExplorer"; //$NON-NLS-1$
+
+       /**
+        * The view part id of the type hierarchy part. (value
+        * <code>"net.sourceforge.phpdt.ui.TypeHierarchy"</code>).
+        * <p>
+        * When this id is used to access a view part with
+        * <code>IWorkbenchPage.findView</code> or <code>showView</code>, the
+        * returned <code>IViewPart</code> can be safely cast to an
+        * <code>ITypeHierarchyViewPart</code>.
+        * </p>
+        * 
+        * @see ITypeHierarchyViewPart
+        * @see org.eclipse.ui.IWorkbenchPage#findView(java.lang.String)
+        * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String)
+        */
+       public static final String ID_TYPE_HIERARCHY = "net.sourceforge.phpdt.ui.TypeHierarchy"; //$NON-NLS-1$
+
+       /**
+        * The id of the Java Browsing Perspective (value
+        * <code>"net.sourceforge.phpdt.ui.JavaBrowsingPerspective"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static String ID_BROWSING_PERSPECTIVE=
+       // "net.sourceforge.phpdt.ui.JavaBrowsingPerspective"; //$NON-NLS-1$
+       /**
+        * The view part id of the Java Browsing Projects view (value
+        * <code>"net.sourceforge.phpdt.ui.ProjectsView"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static String ID_PROJECTS_VIEW=
+       // "net.sourceforge.phpdt.ui.ProjectsView"; //$NON-NLS-1$
+       /**
+        * The view part id of the Java Browsing Packages view (value
+        * <code>"net.sourceforge.phpdt.ui.PackagesView"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static String ID_PACKAGES_VIEW=
+       // "net.sourceforge.phpdt.ui.PackagesView"; //$NON-NLS-1$
+       /**
+        * The view part id of the Java Browsing Types view (value
+        * <code>"net.sourceforge.phpdt.ui.TypesView"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static String ID_TYPES_VIEW= "net.sourceforge.phpdt.ui.TypesView";
+       // //$NON-NLS-1$
+       /**
+        * The view part id of the Java Browsing Members view (value
+        * <code>"net.sourceforge.phpdt.ui.MembersView"</code>).
+        * 
+        * @since 2.0
+        */
+       // public static String ID_MEMBERS_VIEW=
+       // "net.sourceforge.phpdt.ui.MembersView"; //$NON-NLS-1$
+       /**
+        * The class org.eclipse.debug.core.model.IProcess allows attaching String
+        * properties to processes. The Java UI contributes a property page for
+        * IProcess that will show the contents of the property with this key. The
+        * intent of this property is to show the command line a process was
+        * launched with.
+        * 
+        * @deprecated
+        */
+       // public final static String ATTR_CMDLINE=
+       // "net.sourceforge.phpdt.ui.launcher.cmdLine"; //$NON-NLS-1$
+       /**
+        * Returns the shared images for the Java UI.
+        * 
+        * @return the shared images manager
+        */
+       public static ISharedImages getSharedImages() {
+               if (fgSharedImages == null)
+                       fgSharedImages = new SharedImages();
+
+               return fgSharedImages;
+       }
+
+       /**
+        * Creates a selection dialog that lists all packages of the given Java
+        * project. The caller is responsible for opening the dialog with
+        * <code>Window.open</code>, and subsequently extracting the selected
+        * package (of type <code>IPackageFragment</code>) via
+        * <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param project
+        *            the Java project
+        * @param style
+        *            flags defining the style of the dialog; the valid flags are:
+        *            <code>IJavaElementSearchConstants.CONSIDER_BINARIES</code>,
+        *            indicating that packages from binary package fragment roots
+        *            should be included in addition to those from source package
+        *            fragment roots;
+        *            <code>IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS</code>,
+        *            indicating that packages from required projects should be
+        *            included as well.
+        * @param filter
+        *            the initial pattern to filter the set of packages. For example
+        *            "com" shows all packages starting with "com". The meta
+        *            character '?' representing any character and '*' representing
+        *            any string are supported. Clients can pass an empty string if
+        *            no filtering is required.
+        * @return a new selection dialog
+        * @exception JavaModelException
+        *                if the selection dialog could not be opened
+        * 
+        * @since 2.0
+        */
+       // public static SelectionDialog createPackageDialog(Shell parent,
+       // IJavaProject project, int style, String filter) throws JavaModelException
+       // {
+       // Assert.isTrue((style | IJavaElementSearchConstants.CONSIDER_BINARIES |
+       // IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS) ==
+       // (IJavaElementSearchConstants.CONSIDER_BINARIES |
+       // IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS));
+       //
+       // IPackageFragmentRoot[] roots= null;
+       // if ((style & IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS) !=
+       // 0) {
+       // roots= project.getAllPackageFragmentRoots();
+       // } else {
+       // roots= project.getPackageFragmentRoots();
+       // }
+       //              
+       // List consideredRoots= null;
+       // if ((style & IJavaElementSearchConstants.CONSIDER_BINARIES) != 0) {
+       // consideredRoots= Arrays.asList(roots);
+       // } else {
+       // consideredRoots= new ArrayList(roots.length);
+       // for (int i= 0; i < roots.length; i++) {
+       // IPackageFragmentRoot root= roots[i];
+       // if (root.getKind() != IPackageFragmentRoot.K_BINARY)
+       // consideredRoots.add(root);
+       //                                      
+       // }
+       // }
+       //              
+       // int flags= JavaElementLabelProvider.SHOW_DEFAULT;
+       // if (consideredRoots.size() > 1)
+       // flags= flags | JavaElementLabelProvider.SHOW_ROOT;
+       //
+       // List packages= new ArrayList();
+       // Iterator iter= consideredRoots.iterator();
+       // while(iter.hasNext()) {
+       // IPackageFragmentRoot root= (IPackageFragmentRoot)iter.next();
+       // packages.addAll(Arrays.asList(root.getChildren()));
+       // }
+       // ElementListSelectionDialog dialog= new ElementListSelectionDialog(parent,
+       // new JavaElementLabelProvider(flags));
+       // dialog.setIgnoreCase(false);
+       // dialog.setElements(packages.toArray()); // XXX inefficient
+       // dialog.setFilter(filter);
+       // return dialog;
+       // }
+       /**
+        * Creates a selection dialog that lists all packages of the given Java
+        * project. The caller is responsible for opening the dialog with
+        * <code>Window.open</code>, and subsequently extracting the selected
+        * package (of type <code>IPackageFragment</code>) via
+        * <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param project
+        *            the Java project
+        * @param style
+        *            flags defining the style of the dialog; the valid flags are:
+        *            <code>IJavaElementSearchConstants.CONSIDER_BINARIES</code>,
+        *            indicating that packages from binary package fragment roots
+        *            should be included in addition to those from source package
+        *            fragment roots;
+        *            <code>IJavaElementSearchConstants.CONSIDER_REQUIRED_PROJECTS</code>,
+        *            indicating that packages from required projects should be
+        *            included as well.
+        * @return a new selection dialog
+        * @exception JavaModelException
+        *                if the selection dialog could not be opened
+        */
+       // public static SelectionDialog createPackageDialog(Shell parent,
+       // IJavaProject project, int style) throws JavaModelException {
+       // return createPackageDialog(parent, project, style, ""); //$NON-NLS-1$
+       // }
+       /**
+        * Creates a selection dialog that lists all packages under the given
+        * package fragment root. The caller is responsible for opening the dialog
+        * with <code>Window.open</code>, and subsequently extracting the
+        * selected package (of type <code>IPackageFragment</code>) via
+        * <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param root
+        *            the package fragment root
+        * @param filter
+        *            the initial pattern to filter the set of packages. For example
+        *            "com" shows all packages starting with "com". The meta
+        *            character '?' representing any character and '*' representing
+        *            any string are supported. Clients can pass an empty string if
+        *            no filtering is required.
+        * @return a new selection dialog
+        * @exception JavaModelException
+        *                if the selection dialog could not be opened
+        * 
+        * @since 2.0
+        */
+       // public static SelectionDialog createPackageDialog(Shell parent,
+       // IPackageFragmentRoot root, String filter) throws JavaModelException {
+       // ElementListSelectionDialog dialog= new ElementListSelectionDialog(parent,
+       // new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT));
+       // dialog.setIgnoreCase(false);
+       // dialog.setElements(root.getChildren());
+       // dialog.setFilter(filter);
+       // return dialog;
+       // }
+       /**
+        * Creates a selection dialog that lists all packages under the given
+        * package fragment root. The caller is responsible for opening the dialog
+        * with <code>Window.open</code>, and subsequently extracting the
+        * selected package (of type <code>IPackageFragment</code>) via
+        * <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param root
+        *            the package fragment root
+        * @return a new selection dialog
+        * @exception JavaModelException
+        *                if the selection dialog could not be opened
+        */
+       // public static SelectionDialog createPackageDialog(Shell parent,
+       // IPackageFragmentRoot root) throws JavaModelException {
+       // return createPackageDialog(parent, root, ""); //$NON-NLS-1$
+       // }
+       /**
+        * Creates a selection dialog that lists all types in the given scope. The
+        * caller is responsible for opening the dialog with
+        * <code>Window.open</code>, and subsequently extracting the selected
+        * type(s) (of type <code>IType</code>) via
+        * <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param context
+        *            the runnable context used to show progress when the dialog is
+        *            being populated
+        * @param scope
+        *            the scope that limits which types are included
+        * @param style
+        *            flags defining the style of the dialog; the only valid values
+        *            are <code>IJavaElementSearchConstants.CONSIDER_CLASSES</code>,
+        *            <code>CONSIDER_INTERFACES</code>, or their bitwise OR
+        *            (equivalent to <code>CONSIDER_TYPES</code>)
+        * @param multipleSelection
+        *            <code>true</code> if multiple selection is allowed
+        * @param filter
+        *            the initial pattern to filter the set of types. For example
+        *            "Abstract" shows all types starting with "abstract". The meta
+        *            character '?' representing any character and '*' representing
+        *            any string are supported. Clients can pass an empty string if
+        *            no filtering is required.
+        * @exception JavaModelException
+        *                if the selection dialog could not be opened
+        * 
+        * @since 2.0
+        */
+       // public static SelectionDialog createTypeDialog(Shell parent,
+       // IRunnableContext context, IJavaSearchScope scope, int style, boolean
+       // multipleSelection, String filter) throws JavaModelException {
+       // int elementKinds= 0;
+       // if (style == IJavaElementSearchConstants.CONSIDER_TYPES) {
+       // elementKinds= IJavaSearchConstants.TYPE;
+       // } else if (style == IJavaElementSearchConstants.CONSIDER_INTERFACES) {
+       // elementKinds= IJavaSearchConstants.INTERFACE;
+       // } else if (style == IJavaElementSearchConstants.CONSIDER_CLASSES) {
+       // elementKinds= IJavaSearchConstants.CLASS;
+       // } else {
+       // Assert.isTrue(false, "illegal style"); //$NON-NLS-1$
+       // }
+       // if (multipleSelection) {
+       // MultiTypeSelectionDialog dialog= new MultiTypeSelectionDialog(parent,
+       // context, elementKinds, scope);
+       // dialog.setMessage(JavaUIMessages.getString("JavaUI.defaultDialogMessage"));
+       // //$NON-NLS-1$
+       // dialog.setFilter(filter);
+       // return dialog;
+       // } else {
+       // TypeSelectionDialog dialog= new TypeSelectionDialog(parent, context,
+       // elementKinds, scope);
+       // dialog.setMessage(JavaUIMessages.getString("JavaUI.defaultDialogMessage"));
+       // //$NON-NLS-1$
+       // dialog.setFilter(filter);
+       // return dialog;
+       // }
+       // }
+       /**
+        * Creates a selection dialog that lists all types in the given scope. The
+        * caller is responsible for opening the dialog with
+        * <code>Window.open</code>, and subsequently extracting the selected
+        * type(s) (of type <code>IType</code>) via
+        * <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param context
+        *            the runnable context used to show progress when the dialog is
+        *            being populated
+        * @param scope
+        *            the scope that limits which types are included
+        * @param style
+        *            flags defining the style of the dialog; the only valid values
+        *            are <code>IJavaElementSearchConstants.CONSIDER_CLASSES</code>,
+        *            <code>CONSIDER_INTERFACES</code>, or their bitwise OR
+        *            (equivalent to <code>CONSIDER_TYPES</code>)
+        * @param multipleSelection
+        *            <code>true</code> if multiple selection is allowed
+        * @return a new selection dialog
+        * @exception JavaModelException
+        *                if the selection dialog could not be opened
+        */
+       // public static SelectionDialog createTypeDialog(Shell parent,
+       // IRunnableContext context, IJavaSearchScope scope, int style, boolean
+       // multipleSelection) throws JavaModelException {
+       // return createTypeDialog(parent, context, scope, style, multipleSelection,
+       // "");//$NON-NLS-1$
+       // }
+       /**
+        * Creates a selection dialog that lists all types in the given scope
+        * containing a standard <code>main</code> method. The caller is
+        * responsible for opening the dialog with <code>Window.open</code>, and
+        * subsequently extracting the selected type(s) (of type <code>IType</code>)
+        * via <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param context
+        *            the runnable context used to show progress when the dialog is
+        *            being populated
+        * @param scope
+        *            the scope that limits which types are included
+        * @param style
+        *            flags defining the style of the dialog; the only valid values
+        *            are <code>IJavaElementSearchConstants.CONSIDER_BINARIES</code>,
+        *            <code>CONSIDER_EXTERNAL_JARS</code>, or their bitwise OR,
+        *            or <code>0</code>
+        * @param multipleSelection
+        *            <code>true</code> if multiple selection is allowed
+        * @param filter
+        *            the initial pattern to filter the set of types containg a main
+        *            method. For example "App" shows all types starting with "app".
+        *            The meta character '?' representing any character and '*'
+        *            representing any string are supported. Clients can pass an
+        *            empty string if no filtering is required.
+        * @return a new selection dialog
+        * 
+        * @since 2.0
+        */
+       // public static SelectionDialog createMainTypeDialog(Shell parent,
+       // IRunnableContext context, IJavaSearchScope scope, int style, boolean
+       // multipleSelection, String filter) {
+       // if (multipleSelection) {
+       // MultiMainTypeSelectionDialog dialog= new
+       // MultiMainTypeSelectionDialog(parent, context, scope, style);
+       // dialog.setFilter(filter);
+       // return dialog;
+       // } else {
+       // MainTypeSelectionDialog dialog= new MainTypeSelectionDialog(parent,
+       // context, scope, style);
+       // dialog.setFilter(filter);
+       // return dialog;
+       // }
+       // }
+       /**
+        * Creates a selection dialog that lists all types in the given scope
+        * containing a standard <code>main</code> method. The caller is
+        * responsible for opening the dialog with <code>Window.open</code>, and
+        * subsequently extracting the selected type(s) (of type <code>IType</code>)
+        * via <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param context
+        *            the runnable context used to show progress when the dialog is
+        *            being populated
+        * @param scope
+        *            the scope that limits which types are included
+        * @param style
+        *            flags defining the style of the dialog; the only valid values
+        *            are <code>IJavaElementSearchConstants.CONSIDER_BINARIES</code>,
+        *            <code>CONSIDER_EXTERNAL_JARS</code>, or their bitwise OR,
+        *            or <code>0</code>
+        * @param multipleSelection
+        *            <code>true</code> if multiple selection is allowed
+        * @return a new selection dialog
+        */
+       // public static SelectionDialog createMainTypeDialog(Shell parent,
+       // IRunnableContext context, IJavaSearchScope scope, int style, boolean
+       // multipleSelection) {
+       // return createMainTypeDialog(parent, context, scope, style,
+       // multipleSelection, "");//$NON-NLS-1$
+       // }
+       /**
+        * Creates a selection dialog that lists all types in the given project. The
+        * caller is responsible for opening the dialog with
+        * <code>Window.open</code>, and subsequently extracting the selected
+        * type(s) (of type <code>IType</code>) via
+        * <code>SelectionDialog.getResult</code>.
+        * 
+        * @param parent
+        *            the parent shell of the dialog to be created
+        * @param context
+        *            the runnable context used to show progress when the dialog is
+        *            being populated
+        * @param project
+        *            the Java project
+        * @param style
+        *            flags defining the style of the dialog; the only valid values
+        *            are <code>IJavaElementSearchConstants.CONSIDER_CLASSES</code>,
+        *            <code>CONSIDER_INTERFACES</code>, or their bitwise OR
+        *            (equivalent to <code>CONSIDER_TYPES</code>)
+        * @param multipleSelection
+        *            <code>true</code> if multiple selection is allowed
+        * @return a new selection dialog
+        * @exception JavaModelException
+        *                if the selection dialog could not be opened
+        */
+       // public static SelectionDialog createTypeDialog(Shell parent,
+       // IRunnableContext context, IProject project, int style, boolean
+       // multipleSelection) throws JavaModelException {
+       // IJavaSearchScope scope= SearchEngine.createJavaSearchScope(new
+       // IJavaProject[] { JavaCore.create(project) });
+       // return createTypeDialog(parent, context, scope, style,
+       // multipleSelection);
+       // }
+       /**
+        * Opens a Java editor on the given Java element. The element can be a
+        * compilation unit or class file. If there already is an open Java editor
+        * for the given element, it is returned.
+        * 
+        * @param element
+        *            the input element; either a compilation unit (<code>ICompilationUnit</code>)
+        *            or a class file (</code>IClassFile</code>)
+        * @return the editor, or </code>null</code> if wrong element type or
+        *         opening failed
+        * @exception PartInitException
+        *                if the editor could not be initialized
+        * @exception JavaModelException
+        *                if this element does not exist or if an exception occurs
+        *                while accessing its underlying resource
+        */
+       public static IEditorPart openInEditor(IJavaElement element)
+                       throws JavaModelException, PartInitException {
+               return EditorUtility.openInEditor(element);
+       }
+
+       /**
+        * Reveals the source range of the given source reference element in the
+        * given editor. No checking is done if the editor displays a compilation
+        * unit or class file that contains the given source reference. The editor
+        * simply reveals the source range denoted by the given source reference.
+        * 
+        * @param part
+        *            the editor displaying the compilation unit or class file
+        * @param element
+        *            the source reference element defining the source range to be
+        *            revealed
+        * 
+        * @deprecated use <code>revealInEditor(IEditorPart, IJavaElement)</code>
+        *             instead
+        */
+       // public static void revealInEditor(IEditorPart part, ISourceReference
+       // element) {
+       // if (element instanceof IJavaElement)
+       // revealInEditor(part, (IJavaElement) element);
+       // }
+       /**
+        * Reveals the given java element in the given editor. If the element is not
+        * an instance of <code>ISourceReference</code> this method result in a
+        * NOP. If it is a source reference no checking is done if the editor
+        * displays a compilation unit or class file that contains the source
+        * reference element. The editor simply reveals the source range denoted by
+        * the given element.
+        * 
+        * @param part
+        *            the editor displaying a compilation unit or class file
+        * @param element
+        *            the element to be revealed
+        * 
+        * @since 2.0
+        */
+       // public static void revealInEditor(IEditorPart part, IJavaElement element)
+       // {
+       // EditorUtility.revealInEditor(part, element);
+       // }
+       /**
+        * Returns the working copy manager for the Java UI plug-in.
+        * 
+        * @return the working copy manager for the Java UI plug-in
+        */
+       public static IWorkingCopyManager getWorkingCopyManager() {
+               return WebUI.getDefault().getWorkingCopyManager();
+       }
+
+       /**
+        * Answers the shared working copies currently registered for the Java
+        * plug-in. Note that the returned array can include working copies that are
+        * not on the class path of a Java project.
+        * 
+        * @return the list of shared working copies
+        * 
+        * @see net.sourceforge.phpdt.core.JavaCore#getSharedWorkingCopies(net.sourceforge.phpdt.core.IBufferFactory)
+        * @since 2.0
+        */
+       public static IWorkingCopy[] getSharedWorkingCopies() {
+               return JavaCore.getSharedWorkingCopies(getBufferFactory());
+       }
+
+       /**
+        * Answers the shared working copies that are on the class path of a Java
+        * project currently registered for the Java plug-in.
+        * 
+        * 
+        * @return the list of shared working copies
+        * 
+        * @see #getSharedWorkingCopies()
+        * @since 2.1
+        */
+       // public static IWorkingCopy[] getSharedWorkingCopiesOnClasspath() {
+       // IWorkingCopy[] wcs= getSharedWorkingCopies();
+       // List result= new ArrayList(wcs.length);
+       // for (int i = 0; i < wcs.length; i++) {
+       // IWorkingCopy wc= wcs[i];
+       // if (wc instanceof IJavaElement) {
+       // IJavaElement je= (IJavaElement)wc;
+       // if (je.getJavaProject().isOnClasspath(je)) {
+       // result.add(wc);
+       // }
+       // }
+       // }
+       // return (IWorkingCopy[])result.toArray(new IWorkingCopy[result.size()]);
+       // }
+       /**
+        * Returns the BufferFactory for the Java UI plug-in.
+        * 
+        * @return the BufferFactory for the Java UI plug-in
+        * 
+        * @see net.sourceforge.phpdt.core.IBufferFactory
+        * @since 2.0
+        * @deprecated {@link IBufferFactory} has been replaced by
+        *             {@link net.sourceforge.phpdt.core.WorkingCopyOwner}. The
+        *             Java UI plug-in uses the <i>primary working copy owner</i>
+        *             that can be accessed with <code>null</code> in API's that
+        *             require an owner
+        */
+       public static IBufferFactory getBufferFactory() {
+               return PHPeclipsePlugin.getDefault().getBufferFactory();
+       }
+
+       /**
+        * Returns the DocumentProvider used for Java compilation units.
+        * 
+        * @return the DocumentProvider for Java compilation units.
+        * 
+        * @see IDocumentProvider
+        * @since 2.0
+        */
+       public static IDocumentProvider getDocumentProvider() {
+               return WebUI.getDefault()
+                               .getCompilationUnitDocumentProvider();
+       }
+
+       /**
+        * Sets the Javadoc location for an archive with the given path.
+        * 
+        * @param archivePath
+        *            the path of the library; this can be an workspace path or an
+        *            external path in case of an external library.
+        * @param url
+        *            The Javadoc location to set. This location should contain
+        *            index.html and a file 'package-list'. <code>null</code>
+        *            clears the current documentation location.
+        * 
+        * @since 2.0
+        */
+       // public static void setLibraryJavadocLocation(IPath archivePath, URL url)
+       // {
+       // JavaDocLocations.setLibraryJavadocLocation(archivePath, url);
+       // }
+       /**
+        * Returns the Javadoc location for an archive or <code>null</code> if no
+        * location is available.
+        * 
+        * @param archivePath
+        *            the path of the library. This can be an workspace path or an
+        *            external path in case of an external library.
+        * 
+        * @since 2.0
+        */
+       // public static URL getLibraryJavadocLocation(IPath archivePath) {
+       // return JavaDocLocations.getLibraryJavadocLocation(archivePath);
+       // }
+       /**
+        * Sets the Javadoc location for a Java project. This location is used for
+        * all types located in the project's source folders.
+        * 
+        * @param project
+        *            the project
+        * @param url
+        *            The Javadoc location to set. This location should contain
+        *            index.html and a file 'package-list'. <code>null</code>
+        *            clears the current documentation location.
+        * 
+        * @since 2.1
+        */
+       // public static void setProjectJavadocLocation(IJavaProject project, URL
+       // url) {
+       // JavaDocLocations.setProjectJavadocLocation(project, url);
+       // }
+       /**
+        * Returns the Javadoc location for a Java project or <code>null</code> if
+        * no location is available. This location is used for all types located in
+        * the project's source folders.
+        * 
+        * @param project
+        *            the project
+        * 
+        * @since 2.1
+        */
+       // public static URL getProjectJavadocLocation(IJavaProject project) {
+       // return JavaDocLocations.getProjectJavadocLocation(project);
+       // }
+       /**
+        * Returns the Javadoc base URL for an element. The base location contains
+        * the index file. This location doesn't have to exist. Returns
+        * <code>null</code> if no javadoc location has been attached to the
+        * element's library or project. Example of a returned URL is <i>http://www.
+        * junit. org/junit/javadoc</i>.
+        * 
+        * @param The
+        *            element for which the doc URL is requested.
+        * 
+        * @since 2.0
+        */
+       // public static URL getJavadocBaseLocation(IJavaElement element) throws
+       // JavaModelException {
+       // return JavaDocLocations.getJavadocBaseLocation(element);
+       // }
+       /**
+        * Returns the Javadoc URL for an element. Example of a returned URL is
+        * <i>http://www.junit.org/junit/javadoc/junit/extensions/TestSetup.html</i>.
+        * This returned location doesn't have to exist. Returns <code>null</code>
+        * if no javadoc location has been attached to the element's library or
+        * project.
+        * 
+        * @param The
+        *            element for which the doc URL is requested.
+        * @param includeAnchor
+        *            If set, the URL contains an anchor for member references:
+        *            <i>http://www.junit.org/junit/javadoc/junit/extensions/TestSetup.html#run(junit.framework.TestResult)</i>.
+        *            Note that this involves type resolving and is a more expensive
+        *            call than without anchor.
+        * 
+        * @since 2.0
+        */
+       // public static URL getJavadocLocation(IJavaElement element, boolean
+       // includeAnchor) throws JavaModelException {
+       // return JavaDocLocations.getJavadocLocation(element, includeAnchor);
+       // }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/OverrideIndicatorLabelDecorator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/OverrideIndicatorLabelDecorator.java
new file mode 100644 (file)
index 0000000..db7385e
--- /dev/null
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ImageImageDescriptor;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * LabelDecorator that decorates an method's image with override or implements
+ * overlays. The viewer using this decorator is responsible for updating the
+ * images on element changes.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class OverrideIndicatorLabelDecorator implements ILabelDecorator,
+               ILightweightLabelDecorator {
+
+       private ImageDescriptorRegistry fRegistry;
+
+       private boolean fUseNewRegistry = false;
+
+       /**
+        * Creates a decorator. The decorator creates an own image registry to cache
+        * images.
+        */
+       public OverrideIndicatorLabelDecorator() {
+               this(null);
+               fUseNewRegistry = true;
+       }
+
+       /*
+        * Creates decorator with a shared image registry.
+        * 
+        * @param registry The registry to use or <code>null</code> to use the
+        * Java plugin's image registry.
+        */
+       /**
+        * Note: This constructor is for internal use only. Clients should not call
+        * this constructor.
+        */
+       public OverrideIndicatorLabelDecorator(ImageDescriptorRegistry registry) {
+               fRegistry = registry;
+       }
+
+       private ImageDescriptorRegistry getRegistry() {
+               if (fRegistry == null) {
+                       fRegistry = fUseNewRegistry ? new ImageDescriptorRegistry()
+                                       : WebUI.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 element) {
+               int adornmentFlags = computeAdornmentFlags(element);
+               if (adornmentFlags != 0) {
+                       ImageDescriptor baseImage = new ImageImageDescriptor(image);
+                       Rectangle bounds = image.getBounds();
+                       return getRegistry().get(
+                                       new JavaElementImageDescriptor(baseImage, adornmentFlags,
+                                                       new Point(bounds.width, bounds.height)));
+               }
+               return image;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       public int computeAdornmentFlags(Object element) {
+               if (element instanceof IMethod) {
+                       if (!PreferenceConstants.getPreferenceStore().getBoolean(
+                                       PreferenceConstants.APPEARANCE_OVERRIDE_INDICATOR)) {
+                               return 0;
+                       }
+
+                       try {
+                               IMethod method = (IMethod) element;
+                               // if (!method.getJavaProject().isOnClasspath(method)) {
+                               // return 0;
+                               // }
+
+                               int flags = method.getFlags();
+                               IType type = method.getDeclaringType();// jsurfer INSERT
+                               if (type != null && type.isClass() && !method.isConstructor()
+                                               && !Flags.isPrivate(flags) && !Flags.isStatic(flags)) {
+                                       return getOverrideIndicators(method);
+                               }
+                       } catch (JavaModelException e) {
+                               if (!e.isDoesNotExist()) {
+                                       PHPeclipsePlugin.log(e);
+                               }
+                       }
+               }
+               return 0;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected int getOverrideIndicators(IMethod method)
+                       throws JavaModelException {
+               IType type = method.getDeclaringType();
+               // ITypeHierarchy hierarchy=
+               // SuperTypeHierarchyCache.getTypeHierarchy(type);
+               // if (hierarchy != null) {
+               // return findInHierarchy(type, hierarchy, method.getElementName(),
+               // method.getParameterTypes());
+               // }
+               return 0;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       // protected int findInHierarchy(IType type, ITypeHierarchy hierarchy,
+       // String name, String[] paramTypes) throws JavaModelException {
+       // IMethod impl= JavaModelUtil.findMethodDeclarationInHierarchy(hierarchy,
+       // type, name, paramTypes, false);
+       // if (impl != null) {
+       // IMethod overridden=
+       // JavaModelUtil.findMethodImplementationInHierarchy(hierarchy, type, name,
+       // paramTypes, false);
+       // if (overridden != null) {
+       // return JavaElementImageDescriptor.OVERRIDES;
+       // } else {
+       // return JavaElementImageDescriptor.IMPLEMENTS;
+       // }
+       // }
+       // return 0;
+       // }
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IBaseLabelProvider#addListener(ILabelProviderListener)
+        */
+       public void addListener(ILabelProviderListener listener) {
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IBaseLabelProvider#dispose()
+        */
+       public void dispose() {
+               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#removeListener(ILabelProviderListener)
+        */
+       public void removeListener(ILabelProviderListener listener) {
+       }
+
+       /*
+        * (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 != 0) {
+                       decoration.addOverlay(PHPUiImages.DESC_OVR_OVERRIDES);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/PreferenceConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/PreferenceConstants.java
new file mode 100644 (file)
index 0000000..41a16c8
--- /dev/null
@@ -0,0 +1,3071 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import net.sourceforge.phpdt.core.IClasspathEntry;
+import net.sourceforge.phpdt.internal.ui.text.spelling.SpellCheckEngine;
+import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckPreferenceKeys;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+//
+// import org.phpeclipse.phpdt.internal.ui.JavaPlugin;
+// import
+// org.phpeclipse.phpdt.internal.ui.preferences.NewJavaProjectPreferencePage;
+
+/**
+ * Preference constants used in the JDT-UI preference store. Clients should only
+ * read the JDT-UI preference store using these values. Clients are not allowed
+ * to modify the preference store programmatically.
+ * 
+ * @since 2.0
+ */
+public class PreferenceConstants {
+
+       private PreferenceConstants() {
+       }
+
+       /**
+        * A named preference that controls return type rendering of methods in the
+        * UI.
+        * <p>
+        * Value is of type <code>Boolean</code>: if <code>true</code> return
+        * types are rendered
+        * </p>
+        */
+       public static final String APPEARANCE_METHOD_RETURNTYPE = "net.sourceforge.phpdt.ui.methodreturntype"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if override indicators are rendered in
+        * the UI.
+        * <p>
+        * Value is of type <code>Boolean</code>: if <code>true</code> override
+        * indicators are rendered
+        * </p>
+        */
+       public static final String APPEARANCE_OVERRIDE_INDICATOR = "net.sourceforge.phpdt.ui.overrideindicator"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the pattern used for package name
+        * compression.
+        * <p>
+        * Value is of type <code>String</code>. For example foe the given
+        * package name 'net.sourceforge.phpdt' pattern '.' will compress it to
+        * '..jdt', '1~' to 'o~.e~.jdt'.
+        * </p>
+        */
+       public static final String APPEARANCE_PKG_NAME_PATTERN_FOR_PKG_VIEW = "PackagesView.pkgNamePatternForPackagesView"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if package name compression is turned on
+        * or off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @see #APPEARANCE_PKG_NAME_PATTERN_FOR_PKG_VIEW
+        */
+       public static final String APPEARANCE_COMPRESS_PACKAGE_NAMES = "net.sourceforge.phpdt.ui.compresspackagenames"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if empty inner packages are folded in
+        * the hierarchical mode of the package explorer.
+        * <p>
+        * Value is of type <code>Boolean</code>: if <code>true</code> empty
+        * inner packages are folded.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public static final String APPEARANCE_FOLD_PACKAGES_IN_PACKAGE_EXPLORER = "net.sourceforge.phpdt.ui.flatPackagesInPackageExplorer"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines how member elements are ordered by the
+        * Java views using the <code>JavaElementSorter</code>.
+        * <p>
+        * Value is of type <code>String</code>: A comma separated list of the
+        * following entries. Each entry must be in the list, no duplication. List
+        * order defines the sort order.
+        * <ul>
+        * <li><b>T </b>: Types</li>
+        * <li><b>C </b>: Constructors</li>
+        * <li><b>I </b>: Initializers</li>
+        * <li><b>M </b>: Methods</li>
+        * <li><b>F </b>: Fields</li>
+        * <li><b>SI </b>: Static Initializers</li>
+        * <li><b>SM </b>: Static Methods</li>
+        * <li><b>SF </b>: Static Fields</li>
+        * </ul>
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public static final String APPEARANCE_MEMBER_SORT_ORDER = "outlinesortoption"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines how member elements are ordered by
+        * visibility in the Java views using the <code>JavaElementSorter</code>.
+        * <p>
+        * Value is of type <code>String</code>: A comma separated list of the
+        * following entries. Each entry must be in the list, no duplication. List
+        * order defines the sort order.
+        * <ul>
+        * <li><b>B </b>: Public</li>
+        * <li><b>V </b>: Private</li>
+        * <li><b>R </b>: Protected</li>
+        * <li><b>D </b>: Default</li>
+        * </ul>
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String APPEARANCE_VISIBILITY_SORT_ORDER = "net.sourceforge.phpdt.ui.visibility.order"; //$NON-NLS-1$
+
+       /**
+        * A named preferences that controls if Java elements are also sorted by
+        * visibility.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String APPEARANCE_ENABLE_VISIBILITY_SORT_ORDER = "net.sourceforge.phpdt.ui.enable.visibility.order"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if prefix removal during setter/getter
+        * generation is turned on or off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String CODEGEN_USE_GETTERSETTER_PREFIX = "net.sourceforge.phpdt.ui.gettersetter.prefix.enable"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds a list of prefixes to be removed from a
+        * local variable to compute setter and gettter names.
+        * <p>
+        * Value is of type <code>String</code>: comma separated list of prefixed
+        * </p>
+        * 
+        * @see #CODEGEN_USE_GETTERSETTER_PREFIX
+        */
+       public static final String CODEGEN_GETTERSETTER_PREFIX = "net.sourceforge.phpdt.ui.gettersetter.prefix.list"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if suffix removal during setter/getter
+        * generation is turned on or off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String CODEGEN_USE_GETTERSETTER_SUFFIX = "net.sourceforge.phpdt.ui.gettersetter.suffix.enable"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds a list of suffixes to be removed from a
+        * local variable to compute setter and getter names.
+        * <p>
+        * Value is of type <code>String</code>: comma separated list of suffixes
+        * </p>
+        * 
+        * @see #CODEGEN_USE_GETTERSETTER_SUFFIX
+        */
+       public static final String CODEGEN_GETTERSETTER_SUFFIX = "net.sourceforge.phpdt.ui.gettersetter.suffix.list"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the keyword "this" will be added
+        * automatically to field accesses in generated methods.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String CODEGEN_KEYWORD_THIS = "org.eclipse.jdt.ui.keywordthis"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether to use the prefix "is" or the
+        * prefix "get" for automatically created getters which return a boolean
+        * field.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String CODEGEN_IS_FOR_GETTERS = "org.eclipse.jdt.ui.gettersetter.use.is"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the preferred variable names for
+        * exceptions in catch clauses.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String CODEGEN_EXCEPTION_VAR_NAME = "org.eclipse.jdt.ui.exception.name"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if comment stubs will be added
+        * automatically to newly created types and methods.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public static final String CODEGEN_ADD_COMMENTS = "net.sourceforge.phpdt.ui.phpdoc"; //$NON-NLS-1$
+
+       /**
+        * A name preference that controls if a JavaDoc stub gets added to newly
+        * created types and methods.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @deprecated Use CODEGEN_ADD_COMMENTS instead (Name is more precise).
+        */
+       // public static final String CODEGEN__JAVADOC_STUBS = CODEGEN_ADD_COMMENTS;
+       // //$NON-NLS-1$
+       /**
+        * A named preference that controls if a non-phpdoc comment gets added to
+        * methods generated via the "Override Methods" operation.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String CODEGEN__NON_JAVADOC_COMMENTS = "net.sourceforge.phpdt.ui.seecomments"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if a file comment gets added to newly
+        * created files.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String CODEGEN__FILE_COMMENTS = "net.sourceforge.phpdt.ui.filecomments"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds a list of comma separated package names.
+        * The list specifies the import order used by the "Organize Imports"
+        * opeation.
+        * <p>
+        * Value is of type <code>String</code>: semicolon separated list of
+        * package names
+        * </p>
+        */
+       // public static final String ORGIMPORTS_IMPORTORDER =
+       // "net.sourceforge.phpdt.ui.importorder"; //$NON-NLS-1$
+       /**
+        * A named preference that specifies the number of imports added before a
+        * star-import declaration is used.
+        * <p>
+        * Value is of type <code>Int</code>: positive value specifing the number
+        * of non star-import is used
+        * </p>
+        */
+       public static final String ORGIMPORTS_ONDEMANDTHRESHOLD = "net.sourceforge.phpdt.ui.ondemandthreshold"; //$NON-NLS-1$
+
+       /**
+        * A named preferences that controls if types that start with a lower case
+        * letters get added by the "Organize Import" operation.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String ORGIMPORTS_IGNORELOWERCASE = "net.sourceforge.phpdt.ui.ignorelowercasenames"; //$NON-NLS-1$
+
+       /**
+        * A named preference that speficies whether children of a compilation unit
+        * are shown in the package explorer.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String SHOW_CU_CHILDREN = "net.sourceforge.phpdt.ui.packages.cuchildren"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the package explorer's selection
+        * is linked to the active editor.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String LINK_PACKAGES_TO_EDITOR = "net.sourceforge.phpdt.ui.packages.linktoeditor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the hierarchy view's selection
+        * is linked to the active editor.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String LINK_TYPEHIERARCHY_TO_EDITOR = "net.sourceforge.phpdt.ui.packages.linktypehierarchytoeditor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the browsing view's selection is
+        * linked to the active editor.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public static final String LINK_BROWSING_VIEW_TO_EDITOR = "net.sourceforge.phpdt.ui.browsing.linktoeditor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether new projects are generated using
+        * source and output folder.
+        * <p>
+        * Value is of type <code>Boolean</code>. if <code>true</code> new
+        * projects are created with a source and output folder. If
+        * <code>false</code> source and output folder equals to the project.
+        * </p>
+        */
+       public static final String SRCBIN_FOLDERS_IN_NEWPROJ = "net.sourceforge.phpdt.ui.wizards.srcBinFoldersInNewProjects"; //$NON-NLS-1$
+
+       /**
+        * A named preference that specifies the source folder name used when
+        * creating a new Java project. Value is inactive if
+        * <code>SRCBIN_FOLDERS_IN_NEWPROJ</code> is set to <code>false</code>.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        * 
+        * @see #SRCBIN_FOLDERS_IN_NEWPROJ
+        */
+       public static final String SRCBIN_SRCNAME = "net.sourceforge.phpdt.ui.wizards.srcBinFoldersSrcName"; //$NON-NLS-1$
+
+       /**
+        * A named preference that specifies the output folder name used when
+        * creating a new Java project. Value is inactive if
+        * <code>SRCBIN_FOLDERS_IN_NEWPROJ</code> is set to <code>false</code>.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        * 
+        * @see #SRCBIN_FOLDERS_IN_NEWPROJ
+        */
+       public static final String SRCBIN_BINNAME = "net.sourceforge.phpdt.ui.wizards.srcBinFoldersBinName"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds a list of possible JRE libraries used by
+        * the New Java Project wizard. An library consists of a description and an
+        * arbitrary number of <code>IClasspathEntry</code>s, that will represent
+        * the JRE on the new project's classpath.
+        * <p>
+        * Value is of type <code>String</code>: a semicolon separated list of
+        * encoded JRE libraries. <code>NEWPROJECT_JRELIBRARY_INDEX</code> defines
+        * the currently used library. Clients should use the method
+        * <code>encodeJRELibrary</code> to encode a JRE library into a string and
+        * the methods <code>decodeJRELibraryDescription(String)</code> and <code>
+        * decodeJRELibraryClasspathEntries(String)</code>
+        * to decode the description and the array of classpath entries from an
+        * encoded string.
+        * </p>
+        * 
+        * @see #NEWPROJECT_JRELIBRARY_INDEX
+        * @see #encodeJRELibrary(String, IClasspathEntry[])
+        * @see #decodeJRELibraryDescription(String)
+        * @see #decodeJRELibraryClasspathEntries(String)
+        */
+       public static final String NEWPROJECT_JRELIBRARY_LIST = "net.sourceforge.phpdt.ui.wizards.jre.list"; //$NON-NLS-1$
+
+       /**
+        * A named preferences that specifies the current active JRE library.
+        * <p>
+        * Value is of type <code>Int</code>: an index into the list of possible
+        * JRE libraries.
+        * </p>
+        * 
+        * @see #NEWPROJECT_JRELIBRARY_LIST
+        */
+       public static final String NEWPROJECT_JRELIBRARY_INDEX = "net.sourceforge.phpdt.ui.wizards.jre.index"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if a new type hierarchy gets opened in a
+        * new type hierarchy perspective or inside the type hierarchy view part.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * OPEN_TYPE_HIERARCHY_IN_PERSPECTIVE</code>
+        * or <code>
+        * OPEN_TYPE_HIERARCHY_IN_VIEW_PART</code>.
+        * </p>
+        * 
+        * @see #OPEN_TYPE_HIERARCHY_IN_PERSPECTIVE
+        * @see #OPEN_TYPE_HIERARCHY_IN_VIEW_PART
+        */
+       public static final String OPEN_TYPE_HIERARCHY = "net.sourceforge.phpdt.ui.openTypeHierarchy"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>OPEN_TYPE_HIERARCHY</code>.
+        * 
+        * @see #OPEN_TYPE_HIERARCHY
+        */
+       public static final String OPEN_TYPE_HIERARCHY_IN_PERSPECTIVE = "perspective"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>OPEN_TYPE_HIERARCHY</code>.
+        * 
+        * @see #OPEN_TYPE_HIERARCHY
+        */
+       public static final String OPEN_TYPE_HIERARCHY_IN_VIEW_PART = "viewPart"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the behaviour when double clicking on a
+        * container in the packages view.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * DOUBLE_CLICK_GOES_INTO</code>
+        * or <code>
+        * DOUBLE_CLICK_EXPANDS</code>.
+        * </p>
+        * 
+        * @see #DOUBLE_CLICK_EXPANDS
+        * @see #DOUBLE_CLICK_GOES_INTO
+        */
+       public static final String DOUBLE_CLICK = "packageview.doubleclick"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference <code>DOUBLE_CLICK</code>.
+        * 
+        * @see #DOUBLE_CLICK
+        */
+       public static final String DOUBLE_CLICK_GOES_INTO = "packageview.gointo"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference <code>DOUBLE_CLICK</code>.
+        * 
+        * @see #DOUBLE_CLICK
+        */
+       public static final String DOUBLE_CLICK_EXPANDS = "packageview.doubleclick.expands"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether Java views update their
+        * presentation while editing or when saving the content of an editor.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * UPDATE_ON_SAVE</code>
+        * or <code>
+        * UPDATE_WHILE_EDITING</code>.
+        * </p>
+        * 
+        * @see #UPDATE_ON_SAVE
+        * @see #UPDATE_WHILE_EDITING
+        */
+       public static final String UPDATE_JAVA_VIEWS = "JavaUI.update"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>UPDATE_JAVA_VIEWS</code>
+        * 
+        * @see #UPDATE_JAVA_VIEWS
+        */
+       public static final String UPDATE_ON_SAVE = "JavaUI.update.onSave"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>UPDATE_JAVA_VIEWS</code>
+        * 
+        * @see #UPDATE_JAVA_VIEWS
+        */
+       public static final String UPDATE_WHILE_EDITING = "JavaUI.update.whileEditing"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the path of the Javadoc command used by the
+        * Javadoc creation wizard.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        */
+       public static final String JAVADOC_COMMAND = "command"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines whether hint to make hover sticky should
+        * be shown.
+        * 
+        * @see JavaUI
+        * @since 3.0
+        */
+       public static final String EDITOR_SHOW_TEXT_HOVER_AFFORDANCE = "PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the key for the hover modifiers.
+        * 
+        * @see JavaUI
+        * @since 2.1
+        */
+       public static final String EDITOR_TEXT_HOVER_MODIFIERS = "hoverModifiers"; //$NON-NLS-1$
+
+       /**
+        * The id of the best match hover contributed for extension point
+        * <code>javaEditorTextHovers</code>.
+        * 
+        * @since 2.1
+        */
+       public static String ID_BESTMATCH_HOVER = "net.sourceforge.phpdt.ui.BestMatchHover"; //$NON-NLS-1$
+
+       /**
+        * The id of the source code hover contributed for extension point
+        * <code>javaEditorTextHovers</code>.
+        * 
+        * @since 2.1
+        */
+       public static String ID_SOURCE_HOVER = "net.sourceforge.phpdt.ui.JavaSourceHover"; //$NON-NLS-1$
+
+       /**
+        * The id of the problem hover contributed for extension point
+        * <code>javaEditorTextHovers</code>.
+        * 
+        * @since 2.1
+        */
+       public static String ID_PROBLEM_HOVER = "net.sourceforge.phpdt.ui.ProblemHover"; //$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 final static 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 final static String EDITOR_MATCHING_BRACKETS_COLOR = "matchingBracketsColor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the current line highlighting is
+        * turned on or off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_CURRENT_LINE = "currentLine"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used to highlight the current
+        * line.
+        * <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 final static String EDITOR_CURRENT_LINE_COLOR = "currentLineColor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the print margin is turned on or
+        * off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_PRINT_MARGIN = "printMargin"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used to render the print margin.
+        * <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 final static String EDITOR_PRINT_MARGIN_COLOR = "printMarginColor"; //$NON-NLS-1$
+
+       /**
+        * Print margin column. Int value.
+        */
+       public final static String EDITOR_PRINT_MARGIN_COLUMN = "printMarginColumn"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used for the find/replace scope.
+        * <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 final static String EDITOR_FIND_SCOPE_COLOR = AbstractTextEditor.PREFERENCE_COLOR_FIND_SCOPE;
+
+       /**
+        * A named preference that specifies if the editor uses spaces for tabs.
+        * <p>
+        * Value is of type <code>Boolean</code>. If <code>true</code> spaces
+        * instead of tabs are used in the editor. If <code>false</code> the
+        * editor inserts a tab character when pressing the tab key.
+        * </p>
+        */
+       public final static String EDITOR_SPACES_FOR_TABS = "spacesForTabs"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the number of spaces used per tab in the
+        * editor.
+        * <p>
+        * Value is of type <code>Int</code>: positive int value specifying the
+        * number of spaces per tab.
+        * </p>
+        */
+       public final static String EDITOR_TAB_WIDTH = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH; // "net.sourceforge.phpdt.ui.editor.tab.width";
+
+       // //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the outline view selection
+        * should stay in sync with with the element at the current cursor position.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE = "JavaEditor.SyncOutlineOnCursorMove"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if correction indicators are shown in
+        * the UI.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_CORRECTION_INDICATION = "JavaEditor.ShowTemporaryProblem"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the editor shows problem
+        * indicators in text (squiggly lines).
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       // public final static String EDITOR_PROBLEM_INDICATION =
+       // "problemIndication"; //$NON-NLS-1$
+       /**
+        * A named preference that holds the color used to render problem
+        * indicators.
+        * <p>
+        * Value is of type <code>String</code>. A RGB color value encoded as a
+        * string using class <code>PreferenceConverter</code>
+        * </p>
+        * 
+        * @see #EDITOR_PROBLEM_INDICATION
+        * @see org.eclipse.jface.resource.StringConverter
+        * @see org.eclipse.jface.preference.PreferenceConverter
+        */
+       // public final static String EDITOR_PROBLEM_INDICATION_COLOR =
+       // "problemIndicationColor"; //$NON-NLS-1$
+       /**
+        * PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR; A named preference
+        * that controls whether the editor shows warning indicators in text
+        * (squiggly lines).
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       // public final static String EDITOR_WARNING_INDICATION =
+       // "warningIndication"; //$NON-NLS-1$
+       /**
+        * A named preference that holds the color used to render warning
+        * indicators.
+        * <p>
+        * Value is of type <code>String</code>. A RGB color value encoded as a
+        * string using class <code>PreferenceConverter</code>
+        * </p>
+        * 
+        * @see #EDITOR_WARNING_INDICATION
+        * @see org.eclipse.jface.resource.StringConverter
+        * @see org.eclipse.jface.preference.PreferenceConverter
+        */
+       // public final static String EDITOR_WARNING_INDICATION_COLOR =
+       // "warningIndicationColor"; //$NON-NLS-1$
+       /**
+        * A named preference that controls whether the editor shows task indicators
+        * in text (squiggly lines).
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_TASK_INDICATION = "taskIndication"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used to render task indicators.
+        * <p>
+        * Value is of type <code>String</code>. A RGB color value encoded as a
+        * string using class <code>PreferenceConverter</code>
+        * </p>
+        * 
+        * @see #EDITOR_TASK_INDICATION
+        * @see org.eclipse.jface.resource.StringConverter
+        * @see org.eclipse.jface.preference.PreferenceConverter
+        */
+       public final static String EDITOR_TASK_INDICATION_COLOR = "taskIndicationColor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the editor shows bookmark
+        * indicators in text (squiggly lines).
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_BOOKMARK_INDICATION = "bookmarkIndication"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used to render bookmark
+        * indicators.
+        * <p>
+        * Value is of type <code>String</code>. A RGB color value encoded as a
+        * string using class <code>PreferenceConverter</code>
+        * </p>
+        * 
+        * @see #EDITOR_BOOKMARK_INDICATION
+        * @see org.eclipse.jface.resource.StringConverter
+        * @see org.eclipse.jface.preference.PreferenceConverter
+        * @since 2.1
+        */
+       public final static String EDITOR_BOOKMARK_INDICATION_COLOR = "bookmarkIndicationColor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the editor shows search
+        * indicators in text (squiggly lines).
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_SEARCH_RESULT_INDICATION = "searchResultIndication"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used to render search indicators.
+        * <p>
+        * Value is of type <code>String</code>. A RGB color value encoded as a
+        * string using class <code>PreferenceConverter</code>
+        * </p>
+        * 
+        * @see #EDITOR_SEARCH_RESULT_INDICATION
+        * @see org.eclipse.jface.resource.StringConverter
+        * @see org.eclipse.jface.preference.PreferenceConverter
+        * @since 2.1
+        */
+       public final static String EDITOR_SEARCH_RESULT_INDICATION_COLOR = "searchResultIndicationColor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the editor shows unknown
+        * indicators in text (squiggly lines).
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_UNKNOWN_INDICATION = "othersIndication"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used to render unknown
+        * indicators.
+        * <p>
+        * Value is of type <code>String</code>. A RGB color value encoded as a
+        * string using class <code>PreferenceConverter</code>
+        * </p>
+        * 
+        * @see #EDITOR_UNKNOWN_INDICATION
+        * @see org.eclipse.jface.resource.StringConverter
+        * @see org.eclipse.jface.preference.PreferenceConverter
+        * @since 2.1
+        */
+       public final static String EDITOR_UNKNOWN_INDICATION_COLOR = "othersIndicationColor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the overview ruler shows error
+        * indicators.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER = "errorIndicationInOverviewRuler"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the overview ruler shows warning
+        * indicators.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER = "warningIndicationInOverviewRuler"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the overview ruler shows task
+        * indicators.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER = "taskIndicationInOverviewRuler"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the overview ruler shows
+        * bookmark indicators.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER = "bookmarkIndicationInOverviewRuler"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the overview ruler shows search
+        * result indicators.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = "searchResultIndicationInOverviewRuler"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the overview ruler shows unknown
+        * indicators.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER = "othersIndicationInOverviewRuler"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'close strings' feature is
+        * enabled in PHP mode
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_CLOSE_STRINGS_DQ_PHP = "closeStringsPHPDQ"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'close strings' feature is
+        * enabled in PHP mode
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_CLOSE_STRINGS_SQ_PHP = "closeStringsPHPSQ"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'close brackets' feature is
+        * enabled in PHP mode
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_CLOSE_BRACKETS_PHP = "closeBracketsPHP"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'wrap words' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_WRAP_WORDS = "wrapWords"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'wrap strings' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_WRAP_STRINGS_DQ = "wrapStringsDQ"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'escape strings' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String EDITOR_ESCAPE_STRINGS_DQ = "escapeStringsDQ"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'wrap strings' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_WRAP_STRINGS_SQ = "wrapStringsSQ"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'escape strings' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String EDITOR_ESCAPE_STRINGS_SQ = "escapeStringsSQ"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if content assist inserts the common
+        * prefix of all proposals before presenting choices.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String CODEASSIST_PREFIX_COMPLETION = "content_assist_prefix_completion"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'close braces' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_CLOSE_BRACES = "closeBraces"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'close php docs' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_CLOSE_JAVADOCS = "closeJavaDocs"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'add JavaDoc tags' feature
+        * is enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_ADD_JAVADOC_TAGS = "addJavaDocTags"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'format Javadoc tags'
+        * feature is enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_FORMAT_JAVADOCS = "formatJavaDocs"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'smart paste' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_SMART_PASTE = "smartPaste"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'close strings' feature is
+        * enabled in HTML mode
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_CLOSE_STRINGS_HTML = "closeStringsHTML"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'close brackets' feature is
+        * enabled in HTML mode
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_CLOSE_BRACKETS_HTML = "closeBracketsHTML"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the 'smart home-end' feature is
+        * enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_SMART_HOME_END = AbstractTextEditor.PREFERENCE_NAVIGATION_SMART_HOME_END;
+
+       /**
+        * A named preference that controls whether the 'sub-word navigation'
+        * feature is enabled.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_SUB_WORD_NAVIGATION = "subWordNavigation"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if temporary problems are evaluated and
+        * shown in the UI.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_EVALUTE_TEMPORARY_PROBLEMS = "handleTemporaryProblems"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if the overview ruler is shown in the
+        * UI.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_OVERVIEW_RULER = "overviewRuler"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used to render linked positions
+        * inside code templates.
+        * <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 final static String EDITOR_LINKED_POSITION_COLOR = "linkedPositionColor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used as the text foreground.
+        * <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 final static String EDITOR_FOREGROUND_COLOR = AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND;
+
+       /**
+        * A named preference that describes if the system default foreground color
+        * is used as the text foreground.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_FOREGROUND_DEFAULT_COLOR = AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT;
+
+       /**
+        * A named preference that holds the color used as the text background.
+        * <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 final static String EDITOR_BACKGROUND_COLOR = AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND;
+
+       /**
+        * A named preference that describes if the system default background color
+        * is used as the text foreground.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_BACKGROUND_DEFAULT_COLOR = AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT;
+
+       /**
+        * Preference key suffix for bold text style preference keys.
+        */
+       public static final String EDITOR_BOLD_SUFFIX = "_bold"; //$NON-NLS-1$
+
+       /**
+        * Preference key suffix for bold text style preference keys.
+        */
+       public static final String EDITOR_ITALIC_SUFFIX = "_italic"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the color used to render multi line
+        * comments.
+        * <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 final static String EDITOR_MULTI_LINE_COMMENT_COLOR = IPreferenceConstants.PHP_MULTILINE_COMMENT;
+
+       /**
+        * The symbolic font name for the Java editor text font (value
+        * <code>"net.sourceforge.phpdt.ui.editors.textfont"</code>).
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_TEXT_FONT = "net.sourceforge.phpdt.ui.editors.textfont"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether multi line comments are rendered
+        * in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>. If <code>true</code> multi
+        * line comments are rendered in bold. If <code>false</code> the are
+        * rendered using no font style attribute.
+        * </p>
+        */
+       public final static String EDITOR_MULTI_LINE_COMMENT_BOLD = IPreferenceConstants.PHP_MULTILINE_COMMENT
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render single line
+        * comments.
+        * <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 final static String EDITOR_SINGLE_LINE_COMMENT_COLOR = IPreferenceConstants.PHP_SINGLELINE_COMMENT;
+
+       /**
+        * A named preference that controls whether sinle line comments are rendered
+        * in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>. If <code>true</code> single
+        * line comments are rendered in bold. If <code>false</code> the are
+        * rendered using no font style attribute.
+        * </p>
+        */
+       public final static String EDITOR_SINGLE_LINE_COMMENT_BOLD = IPreferenceConstants.PHP_SINGLELINE_COMMENT
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render operators and
+        * 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
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_OPERATOR_COLOR = IPreferenceConstants.PHP_OPERATOR;
+
+       /**
+        * A named preference that controls whether operators and brackets are
+        * rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_OPERATOR_BOLD = IPreferenceConstants.PHP_OPERATOR
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that controls whether operators and brackets are
+        * rendered in italic.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_OPERATOR_ITALIC = IPreferenceConstants.PHP_OPERATOR
+                       + EDITOR_ITALIC_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render operators and
+        * 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
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_BRACE_OPERATOR_COLOR = IPreferenceConstants.PHP_BRACE_OPERATOR;
+
+       /**
+        * A named preference that controls whether operators and brackets are
+        * rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_BRACE_OPERATOR_BOLD = IPreferenceConstants.PHP_BRACE_OPERATOR
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that controls whether operators and brackets are
+        * rendered in italic.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_BRACE_OPERATOR_ITALIC = IPreferenceConstants.PHP_BRACE_OPERATOR
+                       + EDITOR_ITALIC_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render the 'return'
+        * keyword.
+        * <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
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_KEYWORD_RETURN_COLOR = IPreferenceConstants.PHP_KEYWORD_RETURN;
+
+       /**
+        * A named preference that controls whether 'return' keyword is rendered in
+        * bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_KEYWORD_RETURN_BOLD = IPreferenceConstants.PHP_KEYWORD_RETURN
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that controls whether 'return' keyword is rendered in
+        * italic.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String EDITOR_PHP_KEYWORD_RETURN_ITALIC = IPreferenceConstants.PHP_KEYWORD_RETURN
+                       + EDITOR_ITALIC_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render php start and stop
+        * tags.
+        * <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 final static String EDITOR_PHP_TAG_COLOR = IPreferenceConstants.PHP_TAG;
+
+       /**
+        * A named preference that controls whether php start and stop tags are
+        * rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_PHP_TAG_BOLD = IPreferenceConstants.PHP_TAG
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render php keywords.
+        * <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 final static String EDITOR_JAVA_KEYWORD_COLOR = IPreferenceConstants.PHP_KEYWORD;
+
+       /**
+        * A named preference that controls whether keywords are rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_JAVA_KEYWORD_BOLD = IPreferenceConstants.PHP_KEYWORD
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render predefined php
+        * function names.
+        * <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 final static String EDITOR_PHP_FUNCTIONNAME_COLOR = IPreferenceConstants.PHP_FUNCTIONNAME;
+
+       /**
+        * A named preference that controls whether function names are rendered in
+        * bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_PHP_FUNCTIONNAME_BOLD = IPreferenceConstants.PHP_FUNCTIONNAME
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render php variables with
+        * prefix '$_'.
+        * <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 final static String EDITOR_PHP_VARIABLE_DOLLAR_COLOR = IPreferenceConstants.PHP_VARIABLE_DOLLAR;
+
+       /**
+        * A named preference that controls whether variables with prefix '$_' are
+        * rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_PHP_VARIABLE_DOLLAR_BOLD = IPreferenceConstants.PHP_VARIABLE_DOLLAR
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render php variables.
+        * <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 final static String EDITOR_PHP_VARIABLE_COLOR = IPreferenceConstants.PHP_VARIABLE;
+
+       /**
+        * A named preference that controls whether variables are rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_PHP_VARIABLE_BOLD = IPreferenceConstants.PHP_VARIABLE
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render php constants.
+        * <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 final static String EDITOR_PHP_CONSTANT_COLOR = IPreferenceConstants.PHP_CONSTANT;
+
+       /**
+        * A named preference that controls whether constants are rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_PHP_CONSTANT_BOLD = IPreferenceConstants.PHP_CONSTANT
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render php types.
+        * <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 final static String EDITOR_PHP_TYPE_COLOR = IPreferenceConstants.PHP_TYPE;
+
+       /**
+        * A named preference that controls whether types are rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_PHP_TYPE_BOLD = IPreferenceConstants.PHP_TYPE
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render string constants.
+        * <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 final static String EDITOR_STRING_COLOR_DQ = IPreferenceConstants.PHP_STRING_DQ;
+
+       /**
+        * A named preference that controls whether string constants are rendered in
+        * bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_STRING_BOLD_DQ = IPreferenceConstants.PHP_STRING_DQ
+                       + EDITOR_BOLD_SUFFIX;
+
+       public final static String EDITOR_STRING_COLOR_SQ = IPreferenceConstants.PHP_STRING_SQ;
+
+       /**
+        * A named preference that controls whether string constants are rendered in
+        * bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_STRING_BOLD_SQ = IPreferenceConstants.PHP_STRING_SQ
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render php default text.
+        * <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 final static String EDITOR_JAVA_DEFAULT_COLOR = IPreferenceConstants.PHP_DEFAULT;
+
+       /**
+        * A named preference that controls whether Java default text is rendered in
+        * bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_JAVA_DEFAULT_BOLD = IPreferenceConstants.PHP_DEFAULT
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render task tags.
+        * <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
+        * @since 2.1
+        */
+       public final static String EDITOR_TASK_TAG_COLOR = IPreferenceConstants.TASK_TAG;
+
+       /**
+        * A named preference that controls whether task tags are rendered in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String EDITOR_TASK_TAG_BOLD = IPreferenceConstants.TASK_TAG
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render phpdoc keywords.
+        * <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 final static String EDITOR_JAVADOC_KEYWORD_COLOR = IPreferenceConstants.PHPDOC_KEYWORD;
+
+       /**
+        * A named preference that controls whether phpdoc keywords are rendered in
+        * bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_JAVADOC_KEYWORD_BOLD = IPreferenceConstants.PHPDOC_KEYWORD
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render phpdoc tags.
+        * <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 final static String EDITOR_JAVADOC_TAG_COLOR = IPreferenceConstants.PHPDOC_TAG;
+
+       /**
+        * A named preference that controls whether phpdoc tags are rendered in
+        * bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_JAVADOC_TAG_BOLD = IPreferenceConstants.PHPDOC_TAG
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render phpdoc links.
+        * <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 final static String EDITOR_JAVADOC_LINKS_COLOR = IPreferenceConstants.PHPDOC_LINK;
+
+       /**
+        * A named preference that controls whether phpdoc links are rendered in
+        * bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_JAVADOC_LINKS_BOLD = IPreferenceConstants.PHPDOC_LINK
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used to render phpdoc default
+        * text.
+        * <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 final static String EDITOR_JAVADOC_DEFAULT_COLOR = IPreferenceConstants.PHPDOC_DEFAULT;
+
+       /**
+        * A named preference that controls whether phpdoc default text is rendered
+        * in bold.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String EDITOR_JAVADOC_DEFAULT_BOLD = IPreferenceConstants.PHPDOC_DEFAULT
+                       + EDITOR_BOLD_SUFFIX;
+
+       /**
+        * A named preference that holds the color used for 'linked-mode' underline.
+        * <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
+        * @since 2.1
+        */
+       public final static String EDITOR_LINK_COLOR = "linkColor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether hover tooltips in the editor are
+        * turned on or off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String EDITOR_SHOW_HOVER = "net.sourceforge.phpdt.ui.editor.showHover"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the hover shown when no control key is
+        * pressed.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * EDITOR_NO_HOVER_CONFIGURED_ID</code>
+        * or <code>EDITOR_DEFAULT_HOVER_CONFIGURED_ID</code> or the hover id of a
+        * hover contributed as <code>phpEditorTextHovers</code>.
+        * </p>
+        * 
+        * @see #EDITOR_NO_HOVER_CONFIGURED_ID
+        * @see #EDITOR_DEFAULT_HOVER_CONFIGURED_ID
+        * @see JavaUI
+        * @since 2.1
+        */
+       public static final String EDITOR_NONE_HOVER = "noneHover"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the hover shown when the
+        * <code>CTRL</code> modifier key is pressed.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * EDITOR_NO_HOVER_CONFIGURED_ID</code>
+        * or <code>EDITOR_DEFAULT_HOVER_CONFIGURED_ID</code> or the hover id of a
+        * hover contributed as <code>phpEditorTextHovers</code>.
+        * </p>
+        * 
+        * @see #EDITOR_NO_HOVER_CONFIGURED_ID
+        * @see #EDITOR_DEFAULT_HOVER_CONFIGURED_ID
+        * @see JavaUI
+        * @since 2.1
+        */
+       public static final String EDITOR_CTRL_HOVER = "ctrlHover"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the hover shown when the
+        * <code>SHIFT</code> modifier key is pressed.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * EDITOR_NO_HOVER_CONFIGURED_ID</code>
+        * or <code>EDITOR_DEFAULT_HOVER_CONFIGURED_ID</code> or the hover id of a
+        * hover contributed as <code>phpEditorTextHovers</code>.
+        * </p>
+        * 
+        * @see #EDITOR_NO_HOVER_CONFIGURED_ID
+        * @see #EDITOR_DEFAULT_HOVER_CONFIGURED_ID
+        * @see JavaUI ID_*_HOVER
+        * @since 2.1
+        */
+       public static final String EDITOR_SHIFT_HOVER = "shiftHover"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the hover shown when the
+        * <code>CTRL + ALT</code> modifier keys is pressed.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * EDITOR_NO_HOVER_CONFIGURED_ID</code>
+        * or <code>EDITOR_DEFAULT_HOVER_CONFIGURED_ID</code> or the hover id of a
+        * hover contributed as <code>phpEditorTextHovers</code>.
+        * </p>
+        * 
+        * @see #EDITOR_NO_HOVER_CONFIGURED_ID
+        * @see #EDITOR_DEFAULT_HOVER_CONFIGURED_ID
+        * @see JavaUI ID_*_HOVER
+        * @since 2.1
+        */
+       public static final String EDITOR_CTRL_ALT_HOVER = "ctrlAltHover"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the hover shown when the
+        * <code>CTRL + ALT + SHIFT</code> modifier keys is pressed.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * EDITOR_NO_HOVER_CONFIGURED_ID</code>
+        * or <code>EDITOR_DEFAULT_HOVER_CONFIGURED_ID</code> or the hover id of a
+        * hover contributed as <code>phpEditorTextHovers</code>.
+        * </p>
+        * 
+        * @see #EDITOR_NO_HOVER_CONFIGURED_ID
+        * @see #EDITOR_DEFAULT_HOVER_CONFIGURED_ID
+        * @see JavaUI ID_*_HOVER
+        * @since 2.1
+        */
+       public static final String EDITOR_CTRL_ALT_SHIFT_HOVER = "ctrlAltShiftHover"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the hover shown when the
+        * <code>CTRL + SHIFT</code> modifier keys is pressed.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * EDITOR_NO_HOVER_CONFIGURED_ID</code>
+        * or <code>EDITOR_DEFAULT_HOVER_CONFIGURED_ID</code> or the hover id of a
+        * hover contributed as <code>phpEditorTextHovers</code>.
+        * </p>
+        * 
+        * @see #EDITOR_NO_HOVER_CONFIGURED_ID
+        * @see #EDITOR_DEFAULT_HOVER_CONFIGURED_ID
+        * @see JavaUI ID_*_HOVER
+        * @since 2.1
+        */
+       public static final String EDITOR_CTRL_SHIFT_HOVER = "ctrlShiftHover"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the hover shown when the <code>ALT</code>
+        * modifier key is pressed.
+        * <p>
+        * Value is of type <code>String</code>: possible values are <code>
+        * EDITOR_NO_HOVER_CONFIGURED_ID</code>,
+        * <code>EDITOR_DEFAULT_HOVER_CONFIGURED_ID</code> or the hover id of a
+        * hover contributed as <code>phpEditorTextHovers</code>.
+        * </p>
+        * 
+        * @see #EDITOR_NO_HOVER_CONFIGURED_ID
+        * @see #EDITOR_DEFAULT_HOVER_CONFIGURED_ID
+        * @see JavaUI ID_*_HOVER
+        * @since 2.1
+        */
+       public static final String EDITOR_ALT_SHIFT_HOVER = "altShiftHover"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preferences for hover configuration to
+        * descibe that no hover should be shown for the given key modifiers.
+        * 
+        * @since 2.1
+        */
+       public static final String EDITOR_NO_HOVER_CONFIGURED_ID = "noHoverConfiguredId"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preferences for hover configuration to
+        * descibe that the default hover should be shown for the given key
+        * modifiers. The default hover is described by the
+        * <code>EDITOR_DEFAULT_HOVER</code> property.
+        * 
+        * @since 2.1
+        */
+       public static final String EDITOR_DEFAULT_HOVER_CONFIGURED_ID = "defaultHoverConfiguredId"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the hover named the 'default hover'.
+        * Value is of type <code>String</code>: possible values are <code>
+        * EDITOR_NO_HOVER_CONFIGURED_ID</code>
+        * or <code> the hover id of a hover
+        * contributed as <code>phpEditorTextHovers</code>.
+        * </p>
+        *@since 2.1
+        */
+       public static final String EDITOR_DEFAULT_HOVER = "defaultHover"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if segmented view (show selected element
+        * only) is turned on or off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String EDITOR_SHOW_SEGMENTS = "net.sourceforge.phpdt.ui.editor.showSegments"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if browser like links are turned on or
+        * off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public static final String EDITOR_BROWSER_LIKE_LINKS = "browserLikeLinks"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the key modifier for browser like links.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public static final String EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER = "browserLikeLinksKeyModifier"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether occurrences are marked in the
+        * editor.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_MARK_OCCURRENCES = "markOccurrences"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether occurrences are sticky in the
+        * editor.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_STICKY_OCCURRENCES = "stickyOccurrences"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls disabling of the overwrite mode.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_DISABLE_OVERWRITE_MODE = "disable_overwrite_mode"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls saving of a file on loss of editor focus.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_SAVE_ON_BLUR = "save_on_blur"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the "smart semicolon" smart typing
+        * handler
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_SMART_SEMICOLON = "smart_semicolon"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the smart backspace behavior.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_SMART_BACKSPACE = "smart_backspace"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the "smart opening brace" smart typing
+        * handler
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_SMART_OPENING_BRACE = "smart_opening_brace"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the smart tab behaviour.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_SMART_TAB = "smart_tab"; //$NON-NLS-1$
+
+       public static final String EDITOR_P_RTRIM_ON_SAVE = "editor_p_trim_on_save"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether Java comments should be
+        * spell-checked.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_CHECK_SPELLING = ISpellCheckPreferenceKeys.SPELLING_CHECK_SPELLING;
+
+       /**
+        * A named preference that controls whether words containing digits should
+        * be skipped during spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_IGNORE_DIGITS = ISpellCheckPreferenceKeys.SPELLING_IGNORE_DIGITS;
+
+       /**
+        * A named preference that controls whether mixed case words should be
+        * skipped during spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_IGNORE_MIXED = ISpellCheckPreferenceKeys.SPELLING_IGNORE_MIXED;
+
+       /**
+        * A named preference that controls whether sentence capitalization should
+        * be ignored during spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_IGNORE_SENTENCE = ISpellCheckPreferenceKeys.SPELLING_IGNORE_SENTENCE;
+
+       /**
+        * A named preference that controls whether upper case words should be
+        * skipped during spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_IGNORE_UPPER = ISpellCheckPreferenceKeys.SPELLING_IGNORE_UPPER;
+
+       /**
+        * A named preference that controls whether urls should be ignored during
+        * spell-checking.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_IGNORE_URLS = ISpellCheckPreferenceKeys.SPELLING_IGNORE_URLS;
+
+       /**
+        * A named preference that controls the locale used for spell-checking.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_LOCALE = ISpellCheckPreferenceKeys.SPELLING_LOCALE;
+
+       /**
+        * A named preference that controls the number of proposals offered during
+        * spell-checking.
+        * <p>
+        * Value is of type <code>Integer</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_PROPOSAL_THRESHOLD = ISpellCheckPreferenceKeys.SPELLING_PROPOSAL_THRESHOLD;
+
+       /**
+        * A named preference that specifies the workspace user dictionary.
+        * <p>
+        * Value is of type <code>Integer</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_USER_DICTIONARY = ISpellCheckPreferenceKeys.SPELLING_USER_DICTIONARY;
+
+       /**
+        * A named preference that specifies whether spelling dictionaries are
+        * available to content assist.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String SPELLING_ENABLE_CONTENTASSIST = ISpellCheckPreferenceKeys.SPELLING_ENABLE_CONTENTASSIST;
+
+       /**
+        * A named preference that controls whether code snippets are formatted in
+        * Javadoc comments.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_FORMATSOURCE = "comment_format_source_code"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether description of Javadoc
+        * parameters are indented.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_INDENTPARAMETERDESCRIPTION = "comment_indent_parameter_description"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether the header comment of a Java
+        * source file is formatted.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_FORMATHEADER = "comment_format_header"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether Javadoc root tags are indented.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_INDENTROOTTAGS = "comment_indent_root_tags"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether Javadoc comments are formatted
+        * by the content formatter.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_FORMAT = "comment_format_comments"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether a new line is inserted after
+        * Javadoc root tag parameters.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_NEWLINEFORPARAMETER = "comment_new_line_for_parameter"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether an empty line is inserted before
+        * the Javadoc root tag block.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_SEPARATEROOTTAGS = "comment_separate_root_tags"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether blank lines are cleared during
+        * formatting
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_CLEARBLANKLINES = "comment_clear_blank_lines"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the line length of comments.
+        * <p>
+        * Value is of type <code>Integer</code>. The value must be at least 4
+        * for reasonable formatting.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_LINELENGTH = "comment_line_length"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether html tags are formatted.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public final static String FORMATTER_COMMENT_FORMATHTML = "comment_format_html"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if the Java code assist gets auto
+        * activated.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String CODEASSIST_AUTOACTIVATION = "content_assist_autoactivation"; //$NON-NLS-1$
+
+       /**
+        * A name preference that holds the auto activation delay time in milli
+        * seconds.
+        * <p>
+        * Value is of type <code>Int</code>.
+        * </p>
+        */
+       public final static String CODEASSIST_AUTOACTIVATION_DELAY = "content_assist_autoactivation_delay"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if code assist contains only visible
+        * proposals.
+        * <p>
+        * Value is of type <code>Boolean</code>. if
+        * <code>true<code> code assist only contains visible members. If
+        * <code>false</code> all members are included.
+        * </p>
+        */
+       public final static String CODEASSIST_SHOW_VISIBLE_PROPOSALS = "content_assist_show_visible_proposals"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if the Java code assist inserts a
+        * proposal automatically if only one proposal is available.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String CODEASSIST_AUTOINSERT = "content_assist_autoinsert"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if the Java code assist adds import
+        * statements.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String CODEASSIST_ADDIMPORT = "content_assist_add_import"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if the Java code assist only inserts
+        * completions. If set to false the proposals can also _replace_ code.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String CODEASSIST_INSERT_COMPLETION = "content_assist_insert_completion"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether code assist proposals filtering
+        * is case sensitive or not.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String CODEASSIST_CASE_SENSITIVITY = "content_assist_case_sensitivity"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines if code assist proposals are sorted in
+        * alphabetical order.
+        * <p>
+        * Value is of type <code>Boolean</code>. If <code>true</code> that are
+        * sorted in alphabetical order. If <code>false</code> that are unsorted.
+        * </p>
+        */
+       public final static String CODEASSIST_ORDER_PROPOSALS = "content_assist_order_proposals"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if argument names are filled in when a
+        * method is selected from as list of code assist proposal.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public final static String CODEASSIST_FILL_ARGUMENT_NAMES = "content_assist_fill_method_arguments"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if method arguments are guessed when a
+        * method is selected from as list of code assist proposal.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public final static String CODEASSIST_GUESS_METHOD_ARGUMENTS = "content_assist_guess_method_arguments"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the characters that auto activate code
+        * assist in PHP code.
+        * <p>
+        * Value is of type <code>Sring</code>. All characters that trigger auto
+        * code assist in PHP code.
+        * </p>
+        */
+       public final static String CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVA = "content_assist_autoactivation_triggers_php"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the characters that auto activate code
+        * assist in PHPDoc.
+        * <p>
+        * Value is of type <code>Sring</code>. All characters that trigger auto
+        * code assist in PHPDoc.
+        * </p>
+        */
+       public final static String CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVADOC = "content_assist_autoactivation_triggers_phpdoc"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the characters that auto activate code
+        * assist in HTML.
+        * <p>
+        * Value is of type <code>Sring</code>. All characters that trigger auto
+        * code assist in HTML.
+        * </p>
+        */
+       public final static String CODEASSIST_AUTOACTIVATION_TRIGGERS_HTML = "content_assist_autoactivation_triggers_html"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the background color used in the code
+        * assist selection dialog.
+        * <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 final static String CODEASSIST_PROPOSALS_BACKGROUND = "content_assist_proposals_background"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the foreground color used in the code
+        * assist selection dialog.
+        * <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 final static String CODEASSIST_PROPOSALS_FOREGROUND = "content_assist_proposals_foreground"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the background color used for parameter
+        * hints.
+        * <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 final static String CODEASSIST_PARAMETERS_BACKGROUND = "content_assist_parameters_background"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the foreground color used in the code
+        * assist selection dialog
+        * <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 final static String CODEASSIST_PARAMETERS_FOREGROUND = "content_assist_parameters_foreground"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the background color used in the code
+        * assist selection dialog to mark replaced code.
+        * <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
+        * @since 2.1
+        */
+       public final static String CODEASSIST_REPLACEMENT_BACKGROUND = "content_assist_completion_replacement_background"; //$NON-NLS-1$
+
+       /**
+        * A named preference that holds the foreground color used in the code
+        * assist selection dialog to mark replaced code.
+        * <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
+        * @since 2.1
+        */
+       public final static String CODEASSIST_REPLACEMENT_FOREGROUND = "content_assist_completion_replacement_foreground"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the behaviour of the refactoring wizard
+        * for showing the error page.
+        * <p>
+        * Value is of type <code>String</code>. Valid values are:
+        * <code>REFACTOR_FATAL_SEVERITY</code>,
+        * <code>REFACTOR_ERROR_SEVERITY</code>,<code>REFACTOR_WARNING_SEVERITY</code>
+        * <code>REFACTOR_INFO_SEVERITY</code>,
+        * <code>REFACTOR_OK_SEVERITY</code>.
+        * </p>
+        * 
+        * @see #REFACTOR_FATAL_SEVERITY
+        * @see #REFACTOR_ERROR_SEVERITY
+        * @see #REFACTOR_WARNING_SEVERITY
+        * @see #REFACTOR_INFO_SEVERITY
+        * @see #REFACTOR_OK_SEVERITY
+        */
+       public static final String REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD = "Refactoring.ErrorPage.severityThreshold"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD</code>.
+        * 
+        * @see #REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD
+        */
+       public static final String REFACTOR_FATAL_SEVERITY = "4"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD</code>.
+        * 
+        * @see #REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD
+        */
+       public static final String REFACTOR_ERROR_SEVERITY = "3"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD</code>.
+        * 
+        * @see #REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD
+        */
+       public static final String REFACTOR_WARNING_SEVERITY = "2"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD</code>.
+        * 
+        * @see #REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD
+        */
+       public static final String REFACTOR_INFO_SEVERITY = "1"; //$NON-NLS-1$
+
+       /**
+        * A string value used by the named preference
+        * <code>REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD</code>.
+        * 
+        * @see #REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD
+        */
+       public static final String REFACTOR_OK_SEVERITY = "0"; //$NON-NLS-1$
+
+       /**
+        * A named preference thet controls whether all dirty editors are
+        * automatically saved before a refactoring is executed.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        */
+       public static final String REFACTOR_SAVE_ALL_EDITORS = "Refactoring.savealleditors"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if the Java Browsing views are linked to
+        * the active editor.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @see #LINK_PACKAGES_TO_EDITOR
+        */
+       public static final String BROWSING_LINK_VIEW_TO_EDITOR = "net.sourceforge.phpdt.ui.browsing.linktoeditor"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the layout of the Java Browsing views
+        * vertically. Boolean value.
+        * <p>
+        * Value is of type <code>Boolean</code>. If
+        * <code>true<code> the views are stacked vertical.
+        * If <code>false</code> they are stacked horizontal.
+        * </p>
+        */
+       public static final String BROWSING_STACK_VERTICALLY = "net.sourceforge.phpdt.ui.browsing.stackVertically"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls if templates are formatted when applied.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+       public static final String TEMPLATES_USE_CODEFORMATTER = "net.sourceforge.phpdt.ui.template.format"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether annotation roll over is used or
+        * not.
+        * <p>
+        * Value is of type <code>Boolean</code>. If
+        * <code>true<code> the annotation ruler column
+        * uses a roll over to display multiple annotations
+        * </p>
+        *
+        * @since 3.0
+        */
+       public static final String EDITOR_ANNOTATION_ROLL_OVER = "editor_annotation_roll_over"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls the key modifier mask for browser like
+        * links. The value is only used if the value of
+        * <code>EDITOR_BROWSER_LIKE_LINKS</code> cannot be resolved to valid SWT
+        * modifier bits.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        * 
+        * @see #EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER
+        * @since 2.1.1
+        */
+       public static final String EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = "browserLikeLinksKeyModifierMask"; //$NON-NLS-1$
+
+       /**
+        * A named preference that defines the key for the hover modifier state
+        * masks. The value is only used if the value of
+        * <code>EDITOR_TEXT_HOVER_MODIFIERS</code> cannot be resolved to valid
+        * SWT modifier bits.
+        * 
+        * @see JavaUI
+        * @see #EDITOR_TEXT_HOVER_MODIFIERS
+        * @since 2.1.1
+        */
+       public static final String EDITOR_TEXT_HOVER_MODIFIER_MASKS = "hoverModifierMasks"; //$NON-NLS-1$
+
+       /**
+        * A named preference that controls whether folding is enabled in the Java
+        * editor.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_FOLDING_ENABLED = "editor_folding_enabled"; //$NON-NLS-1$
+
+       /**
+        * A named preference that stores the configured folding provider.
+        * <p>
+        * Value is of type <code>String</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_FOLDING_PROVIDER = "editor_folding_provider"; //$NON-NLS-1$
+
+       /**
+        * A named preference that stores the value for Javadoc folding for the
+        * default folding provider.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_FOLDING_JAVADOC = "editor_folding_default_javadoc"; //$NON-NLS-1$
+
+       /**
+        * A named preference that stores the value for inner type folding for the
+        * default folding provider.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_FOLDING_INNERTYPES = "editor_folding_default_innertypes"; //$NON-NLS-1$
+
+       /**
+        * A named preference that stores the value for method folding for the
+        * default folding provider.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_FOLDING_METHODS = "editor_folding_default_methods"; //$NON-NLS-1$
+
+       /**
+        * A named preference that stores the value for imports folding for the
+        * default folding provider.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       // public static final String EDITOR_FOLDING_IMPORTS =
+       // "editor_folding_default_imports"; //$NON-NLS-1$
+       /**
+        * A named preference that stores the value for header comment folding for
+        * the default folding provider.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 3.1
+        */
+       public static final String EDITOR_FOLDING_HEADERS = "editor_folding_default_headers"; //$NON-NLS-1$
+
+       public static void initializeDefaultValues(IPreferenceStore store) {
+               store.setDefault(PreferenceConstants.EDITOR_SHOW_SEGMENTS, false);
+
+               // JavaBasePreferencePage
+               store.setDefault(PreferenceConstants.LINK_PACKAGES_TO_EDITOR, true);
+               store.setDefault(PreferenceConstants.LINK_TYPEHIERARCHY_TO_EDITOR,
+                               false);
+               store
+                               .setDefault(PreferenceConstants.LINK_BROWSING_VIEW_TO_EDITOR,
+                                               true);
+               store.setDefault(PreferenceConstants.OPEN_TYPE_HIERARCHY,
+                               PreferenceConstants.OPEN_TYPE_HIERARCHY_IN_VIEW_PART);
+               store.setDefault(PreferenceConstants.DOUBLE_CLICK,
+                               PreferenceConstants.DOUBLE_CLICK_EXPANDS);
+               store.setDefault(PreferenceConstants.UPDATE_JAVA_VIEWS,
+                               PreferenceConstants.UPDATE_WHILE_EDITING);
+
+               // AppearancePreferencePage
+               store.setDefault(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES,
+                               false);
+               store.setDefault(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE,
+                               false);
+               store.setDefault(PreferenceConstants.SHOW_CU_CHILDREN, true);
+               store.setDefault(PreferenceConstants.APPEARANCE_OVERRIDE_INDICATOR,
+                               true);
+               store.setDefault(PreferenceConstants.BROWSING_STACK_VERTICALLY, false);
+               store.setDefault(
+                               PreferenceConstants.APPEARANCE_PKG_NAME_PATTERN_FOR_PKG_VIEW,
+                               ""); //$NON-NLS-1$
+               store
+                               .setDefault(
+                                               PreferenceConstants.APPEARANCE_FOLD_PACKAGES_IN_PACKAGE_EXPLORER,
+                                               true);
+
+               // ImportOrganizePreferencePage
+               // store.setDefault(PreferenceConstants.ORGIMPORTS_IMPORTORDER,
+               // "php;phpx;org;com"); //$NON-NLS-1$
+               store.setDefault(PreferenceConstants.ORGIMPORTS_ONDEMANDTHRESHOLD, 99);
+               store.setDefault(PreferenceConstants.ORGIMPORTS_IGNORELOWERCASE, true);
+
+               // ClasspathVariablesPreferencePage
+               // CodeFormatterPreferencePage
+               // CompilerPreferencePage
+               // no initialization needed
+
+               // RefactoringPreferencePage
+               store.setDefault(
+                               PreferenceConstants.REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD,
+                               PreferenceConstants.REFACTOR_ERROR_SEVERITY);
+               store.setDefault(PreferenceConstants.REFACTOR_SAVE_ALL_EDITORS, false);
+               store.setDefault("RefactoringUI", "dialog");
+
+               // TemplatePreferencePage
+               store.setDefault(PreferenceConstants.TEMPLATES_USE_CODEFORMATTER, true);
+
+               // CodeGenerationPreferencePage
+               store.setDefault(PreferenceConstants.CODEGEN_USE_GETTERSETTER_PREFIX,
+                               false);
+               store.setDefault(PreferenceConstants.CODEGEN_USE_GETTERSETTER_SUFFIX,
+                               false);
+               store.setDefault(PreferenceConstants.CODEGEN_GETTERSETTER_PREFIX,
+                               "fg, f, _$, _, m_"); //$NON-NLS-1$
+               store.setDefault(PreferenceConstants.CODEGEN_GETTERSETTER_SUFFIX, "_"); //$NON-NLS-1$
+
+               store.setDefault(PreferenceConstants.CODEGEN_KEYWORD_THIS, false);
+               store.setDefault(PreferenceConstants.CODEGEN_IS_FOR_GETTERS, true);
+               store.setDefault(PreferenceConstants.CODEGEN_EXCEPTION_VAR_NAME, "e"); //$NON-NLS-1$
+               store.setDefault(PreferenceConstants.CODEGEN_ADD_COMMENTS, true);
+               store.setDefault(PreferenceConstants.CODEGEN__NON_JAVADOC_COMMENTS,
+                               false);
+               store.setDefault(PreferenceConstants.CODEGEN__FILE_COMMENTS, false);
+
+               // MembersOrderPreferencePage
+               store.setDefault(PreferenceConstants.APPEARANCE_MEMBER_SORT_ORDER,
+                               "T,SF,SI,SM,I,F,C,M"); //$NON-NLS-1$
+               store.setDefault(PreferenceConstants.APPEARANCE_VISIBILITY_SORT_ORDER,
+                               "B,V,R,D"); //$NON-NLS-1$
+               store.setDefault(
+                               PreferenceConstants.APPEARANCE_ENABLE_VISIBILITY_SORT_ORDER,
+                               false);
+               // must add here to guarantee that it is the first in the listener list
+               store.addPropertyChangeListener(WebUI.getDefault()
+                               .getMemberOrderPreferenceCache());
+
+               store.setDefault(PreferenceConstants.EDITOR_MATCHING_BRACKETS, true);
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR, new RGB(
+                                               192, 192, 192));
+
+               store.setDefault(PreferenceConstants.EDITOR_CURRENT_LINE, true);
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_CURRENT_LINE_COLOR, new RGB(225,
+                                               235, 224));
+
+               store.setDefault(PreferenceConstants.EDITOR_PRINT_MARGIN, false);
+               store.setDefault(PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN, 80);
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR, new RGB(176,
+                                               180, 185));
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_FIND_SCOPE_COLOR, new RGB(185, 176,
+                                               180));
+
+               // store.setDefault(PreferenceConstants.EDITOR_PROBLEM_INDICATION,
+               // true);
+               // PreferenceConverter.setDefault(store,
+               // PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR, new RGB(255, 0,
+               // 128));
+               // store.setDefault(PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER,
+               // true);
+               //
+               // store.setDefault(PreferenceConstants.EDITOR_WARNING_INDICATION,
+               // true);
+               // PreferenceConverter.setDefault(store,
+               // PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR, new RGB(244,
+               // 200, 45));
+               // store.setDefault(PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER,
+               // true);
+               //
+               // store.setDefault(PreferenceConstants.EDITOR_TASK_INDICATION, false);
+               // PreferenceConverter.setDefault(store,
+               // PreferenceConstants.EDITOR_TASK_INDICATION_COLOR, new RGB(0, 128,
+               // 255));
+               // store.setDefault(PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER,
+               // false);
+               //
+               // store.setDefault(PreferenceConstants.EDITOR_BOOKMARK_INDICATION,
+               // false);
+               // PreferenceConverter.setDefault(store,
+               // PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR, new RGB(34,
+               // 164, 99));
+               // store.setDefault(PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER,
+               // false);
+               //
+               // store.setDefault(PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION,
+               // false);
+               // PreferenceConverter.setDefault(store,
+               // PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR, new
+               // RGB(192, 192, 192));
+               // store.setDefault(PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER,
+               // false);
+               //
+               // store.setDefault(PreferenceConstants.EDITOR_UNKNOWN_INDICATION,
+               // false);
+               // PreferenceConverter.setDefault(store,
+               // PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR, new RGB(0, 0,
+               // 0));
+               // store.setDefault(PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER,
+               // false);
+
+               store
+                               .setDefault(PreferenceConstants.EDITOR_CORRECTION_INDICATION,
+                                               true);
+               store.setDefault(
+                               PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE, true);
+
+               store.setDefault(PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS,
+                               true);
+
+               store.setDefault(PreferenceConstants.EDITOR_OVERVIEW_RULER, true);
+
+               // WorkbenchChainedTextFontFieldEditor.startPropagate(store,
+               // JFaceResources.TEXT_FONT);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_LINKED_POSITION_COLOR, new RGB(0,
+                                               200, 100));
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_LINK_COLOR, new RGB(0, 0, 255));
+
+               store.setDefault(PreferenceConstants.EDITOR_FOREGROUND_DEFAULT_COLOR,
+                               true);
+
+               store.setDefault(PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR,
+                               true);
+
+               store.setDefault(PreferenceConstants.EDITOR_TAB_WIDTH, 4);
+               store.setDefault(PreferenceConstants.EDITOR_SPACES_FOR_TABS, false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_COLOR, new RGB(
+                                               63, 127, 95));
+               store.setDefault(PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_BOLD,
+                               false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR, new RGB(
+                                               63, 127, 95));
+               store.setDefault(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD,
+                               false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_PHP_TAG_COLOR, new RGB(255, 0, 128));
+               store.setDefault(PreferenceConstants.EDITOR_PHP_TAG_BOLD, true);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR, new RGB(127, 0,
+                                               85));
+               store.setDefault(PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD, true);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_COLOR, new RGB(127,
+                                               127, 159));
+               store.setDefault(PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_BOLD,
+                               false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_PHP_VARIABLE_COLOR, new RGB(127,
+                                               159, 191));
+               store.setDefault(PreferenceConstants.EDITOR_PHP_VARIABLE_BOLD, false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_PHP_VARIABLE_DOLLAR_COLOR, new RGB(
+                                               127, 159, 191));
+               store.setDefault(PreferenceConstants.EDITOR_PHP_VARIABLE_DOLLAR_BOLD,
+                               false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_PHP_CONSTANT_COLOR, new RGB(127, 0,
+                                               85));
+               store.setDefault(PreferenceConstants.EDITOR_PHP_CONSTANT_BOLD, false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_PHP_TYPE_COLOR, new RGB(127, 0, 85));
+               store.setDefault(PreferenceConstants.EDITOR_PHP_TYPE_BOLD, false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_STRING_COLOR_DQ,
+                               PHPColorProvider.STRING_DQ);
+               store.setDefault(PreferenceConstants.EDITOR_STRING_BOLD_DQ, false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_STRING_COLOR_SQ,
+                               PHPColorProvider.STRING_SQ);
+               store.setDefault(PreferenceConstants.EDITOR_STRING_BOLD_SQ, true);
+
+               PreferenceConverter
+                               .setDefault(store,
+                                               PreferenceConstants.EDITOR_JAVA_DEFAULT_COLOR, new RGB(
+                                                               0, 0, 0));
+               store.setDefault(PreferenceConstants.EDITOR_JAVA_DEFAULT_BOLD, false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_JAVADOC_KEYWORD_COLOR, new RGB(127,
+                                               159, 191));
+               store.setDefault(PreferenceConstants.EDITOR_JAVADOC_KEYWORD_BOLD, true);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_JAVADOC_TAG_COLOR, new RGB(127, 127,
+                                               159));
+               store.setDefault(PreferenceConstants.EDITOR_JAVADOC_TAG_BOLD, false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_JAVADOC_LINKS_COLOR, new RGB(63, 63,
+                                               191));
+               store.setDefault(PreferenceConstants.EDITOR_JAVADOC_LINKS_BOLD, false);
+
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.EDITOR_JAVADOC_DEFAULT_COLOR, new RGB(63,
+                                               95, 191));
+               store
+                               .setDefault(PreferenceConstants.EDITOR_JAVADOC_DEFAULT_BOLD,
+                                               false);
+
+               store.setDefault(PreferenceConstants.CODEASSIST_AUTOACTIVATION, true);
+               store.setDefault(PreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY,
+                               500);
+
+               store.setDefault(PreferenceConstants.CODEASSIST_AUTOINSERT, true);
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND, new RGB(
+                                               254, 241, 233));
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND, new RGB(0,
+                                               0, 0));
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.CODEASSIST_PARAMETERS_BACKGROUND, new RGB(
+                                               254, 241, 233));
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.CODEASSIST_PARAMETERS_FOREGROUND, new RGB(
+                                               0, 0, 0));
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND, new RGB(
+                                               255, 255, 0));
+               PreferenceConverter.setDefault(store,
+                               PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND, new RGB(
+                                               255, 0, 0));
+               store.setDefault(
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVA,
+                               "$>"); //$NON-NLS-1$
+               store.setDefault(
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVADOC,
+                               "@"); //$NON-NLS-1$
+               store.setDefault(
+                               PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_HTML,
+                               "<&#"); //$NON-NLS-1$
+               store.setDefault(PreferenceConstants.CODEASSIST_SHOW_VISIBLE_PROPOSALS,
+                               true);
+               store
+                               .setDefault(PreferenceConstants.CODEASSIST_CASE_SENSITIVITY,
+                                               false);
+               store.setDefault(PreferenceConstants.CODEASSIST_ORDER_PROPOSALS, false);
+               store.setDefault(PreferenceConstants.CODEASSIST_ADDIMPORT, true);
+               store
+                               .setDefault(PreferenceConstants.CODEASSIST_INSERT_COMPLETION,
+                                               true);
+               store.setDefault(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES,
+                               false);
+               store.setDefault(PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS,
+                               true);
+               store.setDefault(PreferenceConstants.CODEASSIST_PREFIX_COMPLETION,
+                               false);
+
+               store.setDefault(PreferenceConstants.EDITOR_SMART_HOME_END, true);
+               store.setDefault(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION, true);
+               store.setDefault(PreferenceConstants.EDITOR_SMART_PASTE, true);
+               store.setDefault(PreferenceConstants.EDITOR_CLOSE_STRINGS_DQ_PHP, true);
+               store.setDefault(PreferenceConstants.EDITOR_CLOSE_STRINGS_SQ_PHP, true);
+               store.setDefault(PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP, true);
+               store.setDefault(PreferenceConstants.EDITOR_CLOSE_BRACES, true);
+               store.setDefault(PreferenceConstants.EDITOR_CLOSE_JAVADOCS, true);
+               store.setDefault(PreferenceConstants.EDITOR_WRAP_WORDS, false);
+               store.setDefault(PreferenceConstants.EDITOR_WRAP_STRINGS_DQ, true);
+               store.setDefault(PreferenceConstants.EDITOR_ESCAPE_STRINGS_DQ, false);
+               store.setDefault(PreferenceConstants.EDITOR_WRAP_STRINGS_SQ, true);
+               store.setDefault(PreferenceConstants.EDITOR_ESCAPE_STRINGS_SQ, false);
+               store.setDefault(PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS, true);
+               store.setDefault(PreferenceConstants.EDITOR_FORMAT_JAVADOCS, false);
+               store.setDefault(PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE,
+                               false);
+
+               store.setDefault(PreferenceConstants.EDITOR_CLOSE_STRINGS_HTML, true);
+               store.setDefault(PreferenceConstants.EDITOR_CLOSE_BRACKETS_HTML, true);
+
+               // store.setDefault(PreferenceConstants.EDITOR_DEFAULT_HOVER,
+               // JavaPlugin.ID_BESTMATCH_HOVER);
+               store.setDefault(PreferenceConstants.EDITOR_NONE_HOVER,
+                               PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID);
+               // store.setDefault(PreferenceConstants.EDITOR_CTRL_HOVER,
+               // JavaPlugin.ID_SOURCE_HOVER);
+               store.setDefault(PreferenceConstants.EDITOR_SHIFT_HOVER,
+                               PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID);
+               store.setDefault(PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER,
+                               PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID);
+               store.setDefault(PreferenceConstants.EDITOR_CTRL_ALT_HOVER,
+                               PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID);
+               store.setDefault(PreferenceConstants.EDITOR_ALT_SHIFT_HOVER,
+                               PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID);
+               store.setDefault(PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER,
+                               PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID);
+
+               int modifier = SWT.CTRL;
+               if (Platform.getOS().equals(Platform.OS_MACOSX))
+                       modifier = SWT.COMMAND;
+               String ctrl = Action.findModifierString(modifier);
+               store
+                               .setDefault(
+                                               PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS,
+                                               "net.sourceforge.phpdt.ui.BestMatchHover;0;net.sourceforge.phpdt.ui.JavaSourceHover;" + ctrl); //$NON-NLS-1$
+               store
+                               .setDefault(
+                                               PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS,
+                                               "net.sourceforge.phpdt.ui.BestMatchHover;0;net.sourceforge.phpdt.ui.JavaSourceHover;" + modifier); //$NON-NLS-1$
+               store.setDefault(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE,
+                               true);
+
+               store.setDefault(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS, true);
+               store.setDefault(
+                               PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER,
+                               ctrl);
+               store
+                               .setDefault(
+                                               PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK,
+                                               modifier);
+
+               // mark occurrences
+               store.setDefault(PreferenceConstants.EDITOR_MARK_OCCURRENCES, true);
+               store.setDefault(PreferenceConstants.EDITOR_STICKY_OCCURRENCES, true);
+               // store.setDefault(PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES,
+               // true);
+               // store.setDefault(PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES,
+               // true);
+               // store.setDefault(PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES,
+               // true);
+               // store.setDefault(PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES,
+               // true);
+               // store.setDefault(PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES,
+               // true);
+               // store.setDefault(PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES,
+               // true);
+               // store.setDefault(PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS,
+               // true);
+               // store.setDefault(PreferenceConstants.EDITOR_MARK_IMPLEMENTORS, true);
+
+               // spell checking
+               store.setDefault(PreferenceConstants.SPELLING_CHECK_SPELLING, false);
+               store.setDefault(PreferenceConstants.SPELLING_LOCALE, SpellCheckEngine
+                               .getDefaultLocale().toString());
+               store.setDefault(PreferenceConstants.SPELLING_IGNORE_DIGITS, true);
+               store.setDefault(PreferenceConstants.SPELLING_IGNORE_MIXED, true);
+               store.setDefault(PreferenceConstants.SPELLING_IGNORE_SENTENCE, true);
+               store.setDefault(PreferenceConstants.SPELLING_IGNORE_UPPER, true);
+               store.setDefault(PreferenceConstants.SPELLING_IGNORE_URLS, true);
+               store.setDefault(PreferenceConstants.SPELLING_USER_DICTIONARY, ""); //$NON-NLS-1$
+               store.setDefault(PreferenceConstants.SPELLING_PROPOSAL_THRESHOLD, 20);
+               store.setDefault(PreferenceConstants.SPELLING_ENABLE_CONTENTASSIST,
+                               false);
+
+               // folding
+               store.setDefault(PreferenceConstants.EDITOR_FOLDING_ENABLED, true);
+               store.setDefault(PreferenceConstants.EDITOR_FOLDING_PROVIDER,
+                               "net.sourceforge.phpdt.ui.text.defaultFoldingProvider"); //$NON-NLS-1$
+               store.setDefault(PreferenceConstants.EDITOR_FOLDING_JAVADOC, true);
+               store.setDefault(PreferenceConstants.EDITOR_FOLDING_INNERTYPES, true);
+               store.setDefault(PreferenceConstants.EDITOR_FOLDING_METHODS, false);
+               // store.setDefault(PreferenceConstants.EDITOR_FOLDING_IMPORTS, false);
+               store.setDefault(PreferenceConstants.EDITOR_FOLDING_HEADERS, true);
+
+               store.setDefault(PreferenceConstants.EDITOR_SMART_BACKSPACE, true);
+               store.setDefault(PreferenceConstants.EDITOR_P_RTRIM_ON_SAVE, false);
+               // do more complicated stuff
+               // NewJavaProjectPreferencePage.initDefaults(store);
+       }
+
+       /**
+        * Returns the JDT-UI preference store.
+        * 
+        * @return the JDT-UI preference store
+        */
+       public static IPreferenceStore getPreferenceStore() {
+               return WebUI.getDefault().getPreferenceStore();
+       }
+
+       // /**
+       // * Encodes a JRE library to be used in the named preference
+       // <code>NEWPROJECT_JRELIBRARY_LIST</code>.
+       // *
+       // * @param description a string value describing the JRE library. The
+       // description is used
+       // * to indentify the JDR library in the UI
+       // * @param entries an array of classpath entries to be encoded
+       // *
+       // * @return the encoded string.
+       // */
+       // public static String encodeJRELibrary(String description,
+       // IClasspathEntry[] entries) {
+       // return NewJavaProjectPreferencePage.encodeJRELibrary(description,
+       // entries);
+       // }
+       //
+       // /**
+       // * Decodes an encoded JRE library and returns its description string.
+       // *
+       // * @return the description of an encoded JRE library
+       // *
+       // * @see #encodeJRELibrary(String, IClasspathEntry[])
+       // */
+       // public static String decodeJRELibraryDescription(String encodedLibrary) {
+       // return
+       // NewJavaProjectPreferencePage.decodeJRELibraryDescription(encodedLibrary);
+       // }
+       //
+       // /**
+       // * Decodes an encoded JRE library and returns its classpath entries.
+       // *
+       // * @return the array of classpath entries of an encoded JRE library.
+       // *
+       // * @see #encodeJRELibrary(String, IClasspathEntry[])
+       // */
+       // public static IClasspathEntry[] decodeJRELibraryClasspathEntries(String
+       // encodedLibrary) {
+       // return
+       // NewJavaProjectPreferencePage.decodeJRELibraryClasspathEntries(encodedLibrary);
+       // }
+       //
+       // /**
+       // * Returns the current configuration for the JRE to be used as default in
+       // new Java projects.
+       // * This is a convenience method to access the named preference
+       // <code>NEWPROJECT_JRELIBRARY_LIST
+       // * </code> with the index defined by <code>
+       // NEWPROJECT_JRELIBRARY_INDEX</code>.
+       // *
+       // * @return the current default set of classpath entries
+       // *
+       // * @see #NEWPROJECT_JRELIBRARY_LIST
+       // * @see #NEWPROJECT_JRELIBRARY_INDEX
+       // */
+       // public static IClasspathEntry[] getDefaultJRELibrary() {
+       // return NewJavaProjectPreferencePage.getDefaultJRELibrary();
+       // }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/ProblemsLabelDecorator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/ProblemsLabelDecorator.java
new file mode 100644 (file)
index 0000000..2a48670
--- /dev/null
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.viewsupport.IProblemChangedListener;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ImageImageDescriptor;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.util.ListenerList;
+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.ILightweightLabelDecorator;
+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.part.FileEditorInput;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+/**
+ * LabelDecorator that decorates an element's image with error and warning
+ * overlays that represent the severity of markers attached to the element's
+ * underlying resource. To see a problem decoration for a marker, the marker
+ * needs to be a subtype of <code>IMarker.PROBLEM</code>.
+ * <p>
+ * Note: Only images for elements in Java projects are currently updated on
+ * marker changes.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class ProblemsLabelDecorator implements ILabelDecorator,
+               ILightweightLabelDecorator {
+
+       /**
+        * This is a special <code>LabelProviderChangedEvent</code> carring
+        * additional information whether the event orgins from a maker change.
+        * <p>
+        * <code>ProblemsLabelChangedEvent</code>s are only generated by <code>
+        * ProblemsLabelDecorator</code>s.
+        * </p>
+        */
+       public static class ProblemsLabelChangedEvent extends
+                       LabelProviderChangedEvent {
+
+               private boolean fMarkerChange;
+
+               /**
+                * Note: This constructor is for internal use only. Clients should not
+                * call this constructor.
+                */
+               public ProblemsLabelChangedEvent(IBaseLabelProvider source,
+                               IResource[] changedResource, boolean isMarkerChange) {
+                       super(source, 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 = JavaElementImageDescriptor.WARNING;
+
+       private static final int ERRORTICK_ERROR = JavaElementImageDescriptor.ERROR;
+
+       private ImageDescriptorRegistry fRegistry;
+
+       private boolean fUseNewRegistry = false;
+
+       private IProblemChangedListener fProblemChangedListener;
+
+       private ListenerList fListeners;
+
+       /**
+        * Creates a new <code>ProblemsLabelDecorator</code>.
+        */
+       public ProblemsLabelDecorator() {
+               this(null);
+               fUseNewRegistry = true;
+       }
+
+       /*
+        * Creates decorator with a shared image registry.
+        * 
+        * @param registry The registry to use or <code>null</code> to use the
+        * Java plugin's image registry.
+        */
+       /**
+        * Note: This constructor is for internal use only. Clients should not call
+        * this constructor.
+        */
+       public ProblemsLabelDecorator(ImageDescriptorRegistry registry) {
+               fRegistry = registry;
+               fProblemChangedListener = null;
+       }
+
+       private ImageDescriptorRegistry getRegistry() {
+               if (fRegistry == null) {
+                       fRegistry = fUseNewRegistry ? new ImageDescriptorRegistry()
+                                       : WebUI.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();
+                       return getRegistry().get(
+                                       new JavaElementImageDescriptor(baseImage, adornmentFlags,
+                                                       new Point(bounds.width, bounds.height)));
+               }
+               return image;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected int computeAdornmentFlags(Object obj) {
+               try {
+                       if (obj instanceof IJavaElement) {
+                               IJavaElement element = (IJavaElement) obj;
+                               int type = element.getElementType();
+                               switch (type) {
+                               case IJavaElement.JAVA_PROJECT:
+                               case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+                                       return getErrorTicksFromMarkers(element.getResource(),
+                                                       IResource.DEPTH_INFINITE, null);
+                               case IJavaElement.PACKAGE_FRAGMENT:
+                               case IJavaElement.CLASS_FILE:
+                                       return getErrorTicksFromMarkers(element.getResource(),
+                                                       IResource.DEPTH_ONE, null);
+                               case IJavaElement.COMPILATION_UNIT:
+                               case IJavaElement.PACKAGE_DECLARATION:
+                               case IJavaElement.IMPORT_DECLARATION:
+                               case IJavaElement.IMPORT_CONTAINER:
+                               case IJavaElement.TYPE:
+                               case IJavaElement.INITIALIZER:
+                               case IJavaElement.METHOD:
+                               case IJavaElement.FIELD:
+                                       ICompilationUnit cu = (ICompilationUnit) element
+                                                       .getAncestor(IJavaElement.COMPILATION_UNIT);
+                                       if (cu != null) {
+                                               ISourceReference ref = (type == IJavaElement.COMPILATION_UNIT) ? null
+                                                               : (ISourceReference) element;
+                                               // The assumption is that only source elements in
+                                               // compilation unit can have markers
+                                               if (cu.isWorkingCopy()) {
+                                                       // working copy: look at annotation model
+                                                       return getErrorTicksFromWorkingCopy(
+                                                                       (ICompilationUnit) cu.getOriginalElement(),
+                                                                       ref);
+                                               }
+                                               return getErrorTicksFromMarkers(cu.getResource(),
+                                                               IResource.DEPTH_ONE, ref);
+                                       }
+                                       break;
+                               default:
+                               }
+                       } else if (obj instanceof IResource) {
+                               return getErrorTicksFromMarkers((IResource) obj,
+                                               IResource.DEPTH_INFINITE, null);
+                       }
+               } catch (CoreException e) {
+                       if (e instanceof JavaModelException) {
+                               if (((JavaModelException) e).isDoesNotExist()) {
+                                       return 0;
+                               }
+                       }
+                       PHPeclipsePlugin.log(e);
+               }
+               return 0;
+       }
+
+       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 int getErrorTicksFromWorkingCopy(ICompilationUnit original,
+                       ISourceReference sourceElement) throws CoreException {
+               int info = 0;
+               FileEditorInput editorInput = new FileEditorInput((IFile) original
+                               .getResource());
+               IAnnotationModel model = WebUI.getDefault()
+                               .getCompilationUnitDocumentProvider().getAnnotationModel(
+                                               editorInput);
+               if (model != null) {
+                       Iterator iter = model.getAnnotationIterator();
+                       while ((info != ERRORTICK_ERROR) && iter.hasNext()) {
+                               Annotation curr = (Annotation) iter.next();
+                               IMarker marker = isAnnotationInRange(model, curr, 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) {
+                       IMarker marker = ((MarkerAnnotation) annot).getMarker();
+                       if (marker.exists() && marker.isSubtypeOf(IMarker.PROBLEM)) {
+                               Position pos = model.getPosition(annot);
+                               if (sourceElement == null
+                                               || isInside(pos.getOffset(), sourceElement)) {
+                                       return marker;
+                               }
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * 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 {
+               ISourceRange range = sourceElement.getSourceRange();
+               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) {
+                       WebUI.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);
+                               }
+                       };
+                       WebUI.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) {
+                               WebUI.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(PHPUiImages.DESC_OVR_ERROR);
+               } else if (adornmentFlags == ERRORTICK_WARNING) {
+                       decoration.addOverlay(PHPUiImages.DESC_OVR_WARNING);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/StandardJavaElementContentProvider.java
new file mode 100644 (file)
index 0000000..87d461c
--- /dev/null
@@ -0,0 +1,511 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IJavaModel;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.IParent;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * A base content provider for Java elements. It provides access to the Java
+ * element hierarchy without listening to changes in the Java model. If updating
+ * the presentation on Java model change is required than clients have to
+ * subclass, listen to Java model changes and have to update the UI using
+ * corresponding methods provided by the JFace viewers or their own UI
+ * presentation.
+ * <p>
+ * The following Java element hierarchy is surfaced by this content provider:
+ * <p>
+ * 
+ * <pre>
+ *  Java model (
+ * <code>
+ * IJavaModel
+ * </code>
+ * )
+ *  Java project (
+ * <code>
+ * IJavaProject
+ * </code>
+ * )
+ *  package fragment root (
+ * <code>
+ * IPackageFragmentRoot
+ * </code>
+ * )
+ *  package fragment (
+ * <code>
+ * IPackageFragment
+ * </code>
+ * )
+ *  compilation unit (
+ * <code>
+ * ICompilationUnit
+ * </code>
+ * )
+ *  binary class file (
+ * <code>
+ * IClassFile
+ * </code>
+ * )
+ * </pre>
+ * 
+ * </p>
+ * <p>
+ * Note that when the entire Java project is declared to be package fragment
+ * root, the corresponding package fragment root element that normally appears
+ * between the Java project and the package fragments is automatically filtered
+ * out.
+ * </p>
+ * This content provider can optionally return working copy elements for members
+ * below compilation units. If enabled, working copy members are returned for
+ * those compilation units in the Java element hierarchy for which a shared
+ * working copy exists in JDT core.
+ * 
+ * @see net.sourceforge.phpdt.ui.IWorkingCopyProvider
+ * @see JavaCore#getSharedWorkingCopies(net.sourceforge.phpdt.core.IBufferFactory)
+ * 
+ * @since 2.0
+ */
+public class StandardJavaElementContentProvider implements
+               ITreeContentProvider, IWorkingCopyProvider {
+
+       protected static final Object[] NO_CHILDREN = new Object[0];
+
+       protected boolean fProvideMembers = false;
+
+       protected boolean fProvideWorkingCopy = false;
+
+       /**
+        * Creates a new content provider. The content provider does not provide
+        * members of compilation units or class files and it does not provide
+        * working copy elements.
+        */
+       public StandardJavaElementContentProvider() {
+       }
+
+       /**
+        * Creates a new <code>StandardJavaElementContentProvider</code>.
+        * 
+        * @param provideMembers
+        *            if <code>true</code> members below compilation units and
+        *            class files are provided.
+        * @param provideWorkingCopy
+        *            if <code>true</code> the element provider provides working
+        *            copies members of compilation units which have an associated
+        *            working copy in JDT core. Otherwise only original elements are
+        *            provided.
+        */
+       public StandardJavaElementContentProvider(boolean provideMembers,
+                       boolean provideWorkingCopy) {
+               fProvideMembers = provideMembers;
+               fProvideWorkingCopy = provideWorkingCopy;
+       }
+
+       /**
+        * Returns whether members are provided when asking for a compilation units
+        * or class file for its children.
+        * 
+        * @return <code>true</code> if the content provider provides members;
+        *         otherwise <code>false</code> is returned
+        */
+       public boolean getProvideMembers() {
+               return fProvideMembers;
+       }
+
+       /**
+        * Sets whether the content provider is supposed to return members when
+        * asking a compilation unit or class file for its children.
+        * 
+        * @param b
+        *            if <code>true</code> then members are provided. If
+        *            <code>false</code> compilation units and class files are the
+        *            leaves provided by this content provider.
+        */
+       public void setProvideMembers(boolean b) {
+               fProvideMembers = b;
+       }
+
+       /**
+        * Returns whether the provided members are from a working copy or the
+        * original compilation unit.
+        * 
+        * @return <code>true</code> if the content provider provides working copy
+        *         members; otherwise <code>false</code> is returned
+        * 
+        * @see #setProvideWorkingCopy(boolean)
+        */
+       public boolean getProvideWorkingCopy() {
+               return fProvideWorkingCopy;
+       }
+
+       /**
+        * Sets whether the members are provided from a shared working copy that
+        * exists for a original compilation unit in the Java element hierarchy.
+        * 
+        * @param b
+        *            if <code>true</code> members are provided from a working
+        *            copy if one exists in JDT core. If <code>false</code> the
+        *            provider always returns original elements.
+        */
+       public void setProvideWorkingCopy(boolean b) {
+               fProvideWorkingCopy = b;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IWorkingCopyProvider#providesWorkingCopies()
+        */
+       public boolean providesWorkingCopies() {
+               return fProvideWorkingCopy;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IStructuredContentProvider.
+        */
+       public Object[] getElements(Object parent) {
+               return getChildren(parent);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentProvider.
+        */
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentProvider.
+        */
+       public void dispose() {
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ITreeContentProvider.
+        */
+       public Object[] getChildren(Object element) {
+               if (!exists(element))
+                       return NO_CHILDREN;
+
+               try {
+                       if (element instanceof IJavaModel)
+                               return getJavaProjects((IJavaModel) element);
+
+                       // if (element instanceof IJavaProject)
+                       // return getPackageFragmentRoots((IJavaProject)element);
+                       //                      
+                       if (element instanceof IPackageFragmentRoot)
+                               return getPackageFragments((IPackageFragmentRoot) element);
+
+                       // if (element instanceof IPackageFragment)
+                       // return getPackageContents((IPackageFragment)element);
+
+                       if (element instanceof IFolder)
+                               return getResources((IFolder) element);
+
+                       if (fProvideMembers && element instanceof ISourceReference
+                                       && element instanceof IParent) {
+                               if (fProvideWorkingCopy && element instanceof ICompilationUnit) {
+                                       element = JavaModelUtil
+                                                       .toWorkingCopy((ICompilationUnit) element);
+                               }
+                               return ((IParent) element).getChildren();
+                       }
+               } catch (JavaModelException e) {
+                       return NO_CHILDREN;
+               }
+               return NO_CHILDREN;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see ITreeContentProvider
+        */
+       public boolean hasChildren(Object element) {
+               if (fProvideMembers) {
+                       // assume CUs and class files are never empty
+                       if (element instanceof ICompilationUnit) {
+                               // ||
+                               // element instanceof IClassFile) {
+                               return true;
+                       }
+               } else {
+                       // don't allow to drill down into a compilation unit or class file
+                       if (element instanceof ICompilationUnit ||
+                       // element instanceof IClassFile ||
+                                       element instanceof IFile)
+                               return false;
+               }
+
+               if (element instanceof IJavaProject) {
+                       IJavaProject jp = (IJavaProject) element;
+                       if (!jp.getProject().isOpen()) {
+                               return false;
+                       }
+               }
+
+               if (element instanceof IParent) {
+                       try {
+                               // when we have Java children return true, else we fetch all the
+                               // children
+                               if (((IParent) element).hasChildren())
+                                       return true;
+                       } catch (JavaModelException e) {
+                               return true;
+                       }
+               }
+               Object[] children = getChildren(element);
+               return (children != null) && children.length > 0;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ITreeContentProvider.
+        */
+       public Object getParent(Object element) {
+               if (!exists(element))
+                       return null;
+               return internalGetParent(element);
+       }
+
+       private Object[] getPackageFragments(IPackageFragmentRoot root)
+                       throws JavaModelException {
+               IJavaElement[] fragments = root.getChildren();
+               // Object[] nonJavaResources= root.getNonJavaResources();
+               // if (nonJavaResources == null)
+               return fragments;
+               // return concatenate(fragments, nonJavaResources);
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       // protected Object[] getPackageFragmentRoots(IJavaProject project) throws
+       // JavaModelException {
+       // if (!project.getProject().isOpen())
+       // return NO_CHILDREN;
+       //                      
+       // IPackageFragmentRoot[] roots= project.getPackageFragmentRoots();
+       // List list= new ArrayList(roots.length);
+       // // filter out package fragments that correspond to projects and
+       // // replace them with the package fragments directly
+       // for (int i= 0; i < roots.length; i++) {
+       // IPackageFragmentRoot root= (IPackageFragmentRoot)roots[i];
+       // if (isProjectPackageFragmentRoot(root)) {
+       // Object[] children= root.getChildren();
+       // for (int k= 0; k < children.length; k++)
+       // list.add(children[k]);
+       // }
+       // else if (hasChildren(root)) {
+       // list.add(root);
+       // }
+       // }
+       // return concatenate(list.toArray(), project.getNonJavaResources());
+       // }
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected Object[] getJavaProjects(IJavaModel jm) throws JavaModelException {
+               return jm.getJavaProjects();
+       }
+
+       // private Object[] getPackageContents(IPackageFragment fragment) throws
+       // JavaModelException {
+       // if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) {
+       // return concatenate(fragment.getCompilationUnits(),
+       // fragment.getNonJavaResources());
+       // }
+       // return concatenate(fragment.getClassFiles(),
+       // fragment.getNonJavaResources());
+       // }
+
+       private Object[] getResources(IFolder folder) {
+               try {
+                       // filter out folders that are package fragment roots
+                       Object[] members = folder.members();
+                       List nonJavaResources = new ArrayList();
+                       for (int i = 0; i < members.length; i++) {
+                               Object o = members[i];
+                               // A folder can also be a package fragement root in the
+                               // following case
+                               // Project
+                               // + src <- source folder
+                               // + excluded <- excluded from class path
+                               // + included <- a new source folder.
+                               // Included is a member of excluded, but since it is rendered as
+                               // a source
+                               // folder we have to exclude it as a normal child.
+                               if (o instanceof IFolder) {
+                                       IJavaElement element = JavaCore.create((IFolder) o);
+                                       if (element instanceof IPackageFragmentRoot
+                                                       && element.exists()) {
+                                               continue;
+                                       }
+                               }
+                               nonJavaResources.add(o);
+                       }
+                       return nonJavaResources.toArray();
+               } catch (CoreException e) {
+                       return NO_CHILDREN;
+               }
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected boolean isClassPathChange(IJavaElementDelta delta) {
+
+               // need to test the flags only for package fragment roots
+               if (delta.getElement().getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT)
+                       return false;
+
+               int flags = delta.getFlags();
+               return (delta.getKind() == IJavaElementDelta.CHANGED
+                               && ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0)
+                               || ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) || ((flags & IJavaElementDelta.F_REORDER) != 0));
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected Object skipProjectPackageFragmentRoot(IPackageFragmentRoot root) {
+               try {
+                       if (isProjectPackageFragmentRoot(root))
+                               return root.getParent();
+                       return root;
+               } catch (JavaModelException e) {
+                       return root;
+               }
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected boolean isPackageFragmentEmpty(IJavaElement element)
+                       throws JavaModelException {
+               if (element instanceof IPackageFragment) {
+                       IPackageFragment fragment = (IPackageFragment) element;
+                       if (!(fragment.hasChildren()))
+                               // ||
+                               // fragment.getNonJavaResources().length > 0) &&
+                               // fragment.hasSubpackages())
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected boolean isProjectPackageFragmentRoot(IPackageFragmentRoot root)
+                       throws JavaModelException {
+               IResource resource = root.getResource();
+               return (resource instanceof IProject);
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected boolean exists(Object element) {
+               if (element == null) {
+                       return false;
+               }
+               if (element instanceof IResource) {
+                       return ((IResource) element).exists();
+               }
+               if (element instanceof IJavaElement) {
+                       return ((IJavaElement) element).exists();
+               }
+               return true;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected Object internalGetParent(Object element) {
+               if (element instanceof IJavaProject) {
+                       return ((IJavaProject) element).getJavaModel();
+               }
+               // try to map resources to the containing package fragment
+               if (element instanceof IResource) {
+                       IResource parent = ((IResource) element).getParent();
+                       IJavaElement jParent = JavaCore.create(parent);
+                       // http://bugs.eclipse.org/bugs/show_bug.cgi?id=31374
+                       if (jParent != null && jParent.exists())
+                               return jParent;
+                       return parent;
+               }
+
+               // for package fragments that are contained in a project package
+               // fragment
+               // we have to skip the package fragment root as the parent.
+               if (element instanceof IPackageFragment) {
+                       IPackageFragmentRoot parent = (IPackageFragmentRoot) ((IPackageFragment) element)
+                                       .getParent();
+                       return skipProjectPackageFragmentRoot(parent);
+               }
+               if (element instanceof IJavaElement) {
+                       IJavaElement candidate = ((IJavaElement) element).getParent();
+                       // If the parent is a CU we might have shown working copy elements
+                       // below CU level. If so
+                       // return the original element instead of the working copy.
+                       if (candidate != null
+                                       && candidate.getElementType() == IJavaElement.COMPILATION_UNIT) {
+                               candidate = JavaModelUtil
+                                               .toOriginal((ICompilationUnit) candidate);
+                       }
+                       return candidate;
+               }
+               return null;
+       }
+
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       protected static Object[] concatenate(Object[] a1, Object[] a2) {
+               int a1Len = a1.length;
+               int a2Len = a2.length;
+               Object[] res = new Object[a1Len + a2Len];
+               System.arraycopy(a1, 0, res, 0, a1Len);
+               System.arraycopy(a2, 0, res, a1Len, a2Len);
+               return res;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/CustomFiltersActionGroup.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/CustomFiltersActionGroup.java
new file mode 100644 (file)
index 0000000..f4ed17d
--- /dev/null
@@ -0,0 +1,811 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.actions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Stack;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import net.sourceforge.phpdt.core.IJavaModel;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.filters.CustomFiltersDialog;
+import net.sourceforge.phpdt.internal.ui.filters.FilterDescriptor;
+import net.sourceforge.phpdt.internal.ui.filters.FilterMessages;
+import net.sourceforge.phpdt.internal.ui.filters.NamePatternFilter;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.actions.ActionGroup;
+
+/**
+ * Action group to add the filter action to a view part's tool bar menu.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class CustomFiltersActionGroup extends ActionGroup {
+
+       class ShowFilterDialogAction extends Action {
+               ShowFilterDialogAction() {
+                       setText(FilterMessages
+                                       .getString("OpenCustomFiltersDialogAction.text")); //$NON-NLS-1$
+                       setImageDescriptor(PHPUiImages.DESC_ELCL_FILTER);
+                       setDisabledImageDescriptor(PHPUiImages.DESC_DLCL_FILTER);
+               }
+
+               public void run() {
+                       openDialog();
+               }
+       }
+
+       /**
+        * Menu contribution item which shows and lets check and uncheck filters.
+        * 
+        * @since 3.0
+        */
+       class FilterActionMenuContributionItem extends ContributionItem {
+
+               private int fItemNumber;
+
+               private boolean fState;
+
+               private String fFilterId;
+
+               private String fFilterName;
+
+               private CustomFiltersActionGroup fActionGroup;
+
+               /**
+                * Constructor for FilterActionMenuContributionItem.
+                * 
+                * @param actionGroup
+                *            the action group
+                * @param filterId
+                *            the id of the filter
+                * @param filterName
+                *            the name of the filter
+                * @param state
+                *            the initial state of the filter
+                * @param itemNumber
+                *            the menu item index
+                */
+               public FilterActionMenuContributionItem(
+                               CustomFiltersActionGroup actionGroup, String filterId,
+                               String filterName, boolean state, int itemNumber) {
+                       super(filterId);
+                       Assert.isNotNull(actionGroup);
+                       Assert.isNotNull(filterId);
+                       Assert.isNotNull(filterName);
+                       fActionGroup = actionGroup;
+                       fFilterId = filterId;
+                       fFilterName = filterName;
+                       fState = state;
+                       fItemNumber = itemNumber;
+               }
+
+               /*
+                * Overrides method from ContributionItem.
+                */
+               public void fill(Menu menu, int index) {
+                       MenuItem mi = new MenuItem(menu, SWT.CHECK, index);
+                       mi.setText("&" + fItemNumber + " " + fFilterName); //$NON-NLS-1$  //$NON-NLS-2$
+                       /*
+                        * XXX: Don't set the image - would look bad because other menu
+                        * items don't provide image XXX: Get working set specific image
+                        * name from XML - would need to cache icons
+                        */
+                       // mi.setImage(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_JAVA_WORKING_SET));
+                       mi.setSelection(fState);
+                       mi.addSelectionListener(new SelectionAdapter() {
+                               public void widgetSelected(SelectionEvent e) {
+                                       fState = !fState;
+                                       fActionGroup.setFilter(fFilterId, fState);
+                               }
+                       });
+               }
+
+               /*
+                * @see org.eclipse.jface.action.IContributionItem#isDynamic()
+                */
+               public boolean isDynamic() {
+                       return true;
+               }
+       }
+
+       private static final String TAG_CUSTOM_FILTERS = "customFilters"; //$NON-NLS-1$
+
+       private static final String TAG_USER_DEFINED_PATTERNS_ENABLED = "userDefinedPatternsEnabled"; //$NON-NLS-1$
+
+       private static final String TAG_USER_DEFINED_PATTERNS = "userDefinedPatterns"; //$NON-NLS-1$
+
+       private static final String TAG_XML_DEFINED_FILTERS = "xmlDefinedFilters"; //$NON-NLS-1$
+
+       private static final String TAG_LRU_FILTERS = "lastRecentlyUsedFilters"; //$NON-NLS-1$
+
+       private static final String TAG_CHILD = "child"; //$NON-NLS-1$
+
+       private static final String TAG_PATTERN = "pattern"; //$NON-NLS-1$
+
+       private static final String TAG_FILTER_ID = "filterId"; //$NON-NLS-1$
+
+       private static final String TAG_IS_ENABLED = "isEnabled"; //$NON-NLS-1$
+
+       private static final String SEPARATOR = ","; //$NON-NLS-1$
+
+       private static final int MAX_FILTER_MENU_ENTRIES = 3;
+
+       private static final String RECENT_FILTERS_GROUP_NAME = "recentFiltersGroup"; //$NON-NLS-1$
+
+       private StructuredViewer fViewer;
+
+       private NamePatternFilter fPatternFilter;
+
+       private Map fInstalledBuiltInFilters;
+
+       private Map fEnabledFilterIds;
+
+       private boolean fUserDefinedPatternsEnabled;
+
+       private String[] fUserDefinedPatterns;
+
+       /**
+        * Recently changed filter Ids stack with oldest on top (i.e. at the end).
+        * 
+        * @since 3.0
+        */
+       private Stack fLRUFilterIdsStack;
+
+       /**
+        * Handle to menu manager to dynamically update the last recently used
+        * filters.
+        * 
+        * @since 3.0
+        */
+       private IMenuManager fMenuManager;
+
+       /**
+        * The menu listener which dynamically updates the last recently used
+        * filters.
+        * 
+        * @since 3.0
+        */
+       private IMenuListener fMenuListener;
+
+       /**
+        * Filter Ids used in the last view menu invocation.
+        * 
+        * @since 3.0
+        */
+       private String[] fFilterIdsUsedInLastViewMenu;
+
+       private HashMap fFilterDescriptorMap;
+
+       private String fTargetId;
+
+       /**
+        * Creates a new <code>CustomFiltersActionGroup</code>.
+        * 
+        * @param part
+        *            the view part that owns this action group
+        * @param viewer
+        *            the viewer to be filtered
+        */
+       public CustomFiltersActionGroup(IViewPart part, StructuredViewer viewer) {
+               this(part.getViewSite().getId(), viewer);
+       }
+
+       /**
+        * Creates a new <code>CustomFiltersActionGroup</code>.
+        * 
+        * @param ownerId
+        *            the id of this action group's owner
+        * @param viewer
+        *            the viewer to be filtered
+        */
+       public CustomFiltersActionGroup(String ownerId, StructuredViewer viewer) {
+               Assert.isNotNull(ownerId);
+               Assert.isNotNull(viewer);
+               fTargetId = ownerId;
+               fViewer = viewer;
+
+               fLRUFilterIdsStack = new Stack();
+
+               initializeWithPluginContributions();
+               initializeWithViewDefaults();
+
+               installFilters();
+       }
+
+       /*
+        * Method declared on ActionGroup.
+        */
+       public void fillActionBars(IActionBars actionBars) {
+               fillToolBar(actionBars.getToolBarManager());
+               fillViewMenu(actionBars.getMenuManager());
+       }
+
+       public String[] removeFiltersFor(Object parent, Object element,
+                       IContentProvider contentProvider) {
+               String[] enabledFilters = getEnabledFilterIds();
+               Set newFilters = new HashSet();
+               for (int i = 0; i < enabledFilters.length; i++) {
+                       String filterName = enabledFilters[i];
+                       ViewerFilter filter = (ViewerFilter) fInstalledBuiltInFilters
+                                       .get(filterName);
+                       if (filter == null)
+                               newFilters.add(filterName);
+                       else if (isSelected(parent, element, contentProvider, filter))
+                               newFilters.add(filterName);
+               }
+               if (newFilters.size() == enabledFilters.length)
+                       return new String[0];
+               return (String[]) newFilters.toArray(new String[newFilters.size()]);
+       }
+
+       public void setFilters(String[] newFilters) {
+               setEnabledFilterIds(newFilters);
+               updateViewerFilters(true);
+       }
+
+       private boolean isSelected(Object parent, Object element,
+                       IContentProvider contentProvider, ViewerFilter filter) {
+               if (contentProvider instanceof ITreeContentProvider) {
+                       // the element and all its parents have to be selected
+                       ITreeContentProvider provider = (ITreeContentProvider) contentProvider;
+                       while (element != null && !(element instanceof IJavaModel)) {
+                               if (!filter.select(fViewer, parent, element))
+                                       return false;
+                               element = provider.getParent(element);
+                       }
+                       return true;
+               }
+               return filter.select(fViewer, parent, element);
+       }
+
+       /**
+        * Sets the enable state of the given filter.
+        * 
+        * @param filterId
+        *            the id of the filter
+        * @param state
+        *            the filter state
+        */
+       private void setFilter(String filterId, boolean state) {
+               // Renew filter id in LRU stack
+               fLRUFilterIdsStack.remove(filterId);
+               fLRUFilterIdsStack.add(0, filterId);
+
+               fEnabledFilterIds.put(filterId, new Boolean(state));
+               storeViewDefaults();
+
+               updateViewerFilters(true);
+       }
+
+       private String[] getEnabledFilterIds() {
+               Set enabledFilterIds = new HashSet(fEnabledFilterIds.size());
+               Iterator iter = fEnabledFilterIds.entrySet().iterator();
+               while (iter.hasNext()) {
+                       Map.Entry entry = (Map.Entry) iter.next();
+                       String id = (String) entry.getKey();
+                       boolean isEnabled = ((Boolean) entry.getValue()).booleanValue();
+                       if (isEnabled)
+                               enabledFilterIds.add(id);
+               }
+               return (String[]) enabledFilterIds.toArray(new String[enabledFilterIds
+                               .size()]);
+       }
+
+       private void setEnabledFilterIds(String[] enabledIds) {
+               Iterator iter = fEnabledFilterIds.keySet().iterator();
+               while (iter.hasNext()) {
+                       String id = (String) iter.next();
+                       fEnabledFilterIds.put(id, Boolean.FALSE);
+               }
+               for (int i = 0; i < enabledIds.length; i++)
+                       fEnabledFilterIds.put(enabledIds[i], Boolean.TRUE);
+       }
+
+       private void setUserDefinedPatterns(String[] patterns) {
+               fUserDefinedPatterns = patterns;
+               cleanUpPatternDuplicates();
+       }
+
+       /**
+        * Sets the recently changed filters.
+        * 
+        * @param changeHistory
+        *            the change history
+        * @since 3.0
+        */
+       private void setRecentlyChangedFilters(Stack changeHistory) {
+               Stack oldestFirstStack = new Stack();
+
+               int length = Math.min(changeHistory.size(), MAX_FILTER_MENU_ENTRIES);
+               for (int i = 0; i < length; i++)
+                       oldestFirstStack.push(((FilterDescriptor) changeHistory.pop())
+                                       .getId());
+
+               length = Math.min(fLRUFilterIdsStack.size(), MAX_FILTER_MENU_ENTRIES
+                               - oldestFirstStack.size());
+               int NEWEST = 0;
+               for (int i = 0; i < length; i++) {
+                       Object filter = fLRUFilterIdsStack.remove(NEWEST);
+                       if (!oldestFirstStack.contains(filter))
+                               oldestFirstStack.push(filter);
+               }
+               fLRUFilterIdsStack = oldestFirstStack;
+       }
+
+       private boolean areUserDefinedPatternsEnabled() {
+               return fUserDefinedPatternsEnabled;
+       }
+
+       private void setUserDefinedPatternsEnabled(boolean state) {
+               fUserDefinedPatternsEnabled = state;
+       }
+
+       private void fillToolBar(IToolBarManager tooBar) {
+       }
+
+       /**
+        * Fills the given view menu with the entries managed by the group.
+        * 
+        * @param viewMenu
+        *            the menu to fill
+        */
+       public void fillViewMenu(IMenuManager viewMenu) {
+               /*
+                * Don't change the separator group name. Using this name ensures that
+                * other filters get contributed to the same group.
+                */
+               viewMenu.add(new Separator("filters")); //$NON-NLS-1$
+               viewMenu.add(new GroupMarker(RECENT_FILTERS_GROUP_NAME));
+               viewMenu.add(new ShowFilterDialogAction());
+
+               fMenuManager = viewMenu;
+               fMenuListener = new IMenuListener() {
+                       public void menuAboutToShow(IMenuManager manager) {
+                               removePreviousLRUFilterActions(manager);
+                               addLRUFilterActions(manager);
+                       }
+               };
+               fMenuManager.addMenuListener(fMenuListener);
+       }
+
+       private void removePreviousLRUFilterActions(IMenuManager mm) {
+               if (fFilterIdsUsedInLastViewMenu == null)
+                       return;
+
+               for (int i = 0; i < fFilterIdsUsedInLastViewMenu.length; i++)
+                       mm.remove(fFilterIdsUsedInLastViewMenu[i]);
+       }
+
+       private void addLRUFilterActions(IMenuManager mm) {
+               if (fLRUFilterIdsStack.isEmpty()) {
+                       fFilterIdsUsedInLastViewMenu = null;
+                       return;
+               }
+
+               SortedSet sortedFilters = new TreeSet(fLRUFilterIdsStack);
+               String[] recentlyChangedFilterIds = (String[]) sortedFilters
+                               .toArray(new String[sortedFilters.size()]);
+
+               fFilterIdsUsedInLastViewMenu = new String[recentlyChangedFilterIds.length];
+               for (int i = 0; i < recentlyChangedFilterIds.length; i++) {
+                       String id = recentlyChangedFilterIds[i];
+                       fFilterIdsUsedInLastViewMenu[i] = id;
+                       boolean state = fEnabledFilterIds.containsKey(id)
+                                       && ((Boolean) fEnabledFilterIds.get(id)).booleanValue();
+                       FilterDescriptor filterDesc = (FilterDescriptor) fFilterDescriptorMap
+                                       .get(id);
+                       if (filterDesc != null) {
+                               IContributionItem item = new FilterActionMenuContributionItem(
+                                               this, id, filterDesc.getName(), state, i + 1);
+                               mm.insertBefore(RECENT_FILTERS_GROUP_NAME, item);
+                       }
+               }
+       }
+
+       /*
+        * Method declared on ActionGroup.
+        */
+       public void dispose() {
+               if (fMenuManager != null)
+                       fMenuManager.removeMenuListener(fMenuListener);
+               super.dispose();
+       }
+
+       private void initializeWithPluginContributions() {
+               fUserDefinedPatterns = new String[0];
+               fUserDefinedPatternsEnabled = false;
+
+               FilterDescriptor[] filterDescs = FilterDescriptor
+                               .getFilterDescriptors(fTargetId);
+               fFilterDescriptorMap = new HashMap(filterDescs.length);
+               fEnabledFilterIds = new HashMap(filterDescs.length);
+               for (int i = 0; i < filterDescs.length; i++) {
+                       String id = filterDescs[i].getId();
+                       Boolean isEnabled = new Boolean(filterDescs[i].isEnabled());
+                       if (fEnabledFilterIds.containsKey(id))
+                               WebUI
+                                               .logErrorMessage("WARNING: Duplicate id for extension-point \"net.sourceforge.phpdt.ui.javaElementFilters\""); //$NON-NLS-1$
+                       fEnabledFilterIds.put(id, isEnabled);
+                       fFilterDescriptorMap.put(id, filterDescs[i]);
+               }
+       }
+
+       // ---------- viewer filter handling ----------
+
+       private void installFilters() {
+               fInstalledBuiltInFilters = new HashMap(fEnabledFilterIds.size());
+               fPatternFilter = new NamePatternFilter();
+               fPatternFilter.setPatterns(getUserAndBuiltInPatterns());
+               fViewer.addFilter(fPatternFilter);
+               updateBuiltInFilters();
+       }
+
+       private void updateViewerFilters(boolean refresh) {
+               String[] patterns = getUserAndBuiltInPatterns();
+               fPatternFilter.setPatterns(patterns);
+               fViewer.getControl().setRedraw(false);
+               updateBuiltInFilters();
+               if (refresh)
+                       fViewer.refresh();
+               fViewer.getControl().setRedraw(true);
+       }
+
+       private void updateBuiltInFilters() {
+               Set installedFilters = fInstalledBuiltInFilters.keySet();
+               Set filtersToAdd = new HashSet(fEnabledFilterIds.size());
+               Set filtersToRemove = new HashSet(fEnabledFilterIds.size());
+               Iterator iter = fEnabledFilterIds.entrySet().iterator();
+               while (iter.hasNext()) {
+                       Map.Entry entry = (Map.Entry) iter.next();
+                       String id = (String) entry.getKey();
+                       boolean isEnabled = ((Boolean) entry.getValue()).booleanValue();
+                       if (isEnabled && !installedFilters.contains(id))
+                               filtersToAdd.add(id);
+                       else if (!isEnabled && installedFilters.contains(id))
+                               filtersToRemove.add(id);
+               }
+
+               // Install the filters
+               FilterDescriptor[] filterDescs = FilterDescriptor
+                               .getFilterDescriptors(fTargetId);
+               for (int i = 0; i < filterDescs.length; i++) {
+                       String id = filterDescs[i].getId();
+                       // just to double check - id should denote a custom filter anyway
+                       boolean isCustomFilter = filterDescs[i].isCustomFilter();
+                       if (isCustomFilter) {
+                               if (filtersToAdd.contains(id)) {
+                                       ViewerFilter filter = filterDescs[i].createViewerFilter();
+                                       if (filter != null) {
+                                               fViewer.addFilter(filter);
+                                               fInstalledBuiltInFilters.put(id, filter);
+                                       }
+                               }
+                               if (filtersToRemove.contains(id)) {
+                                       fViewer
+                                                       .removeFilter((ViewerFilter) fInstalledBuiltInFilters
+                                                                       .get(id));
+                                       fInstalledBuiltInFilters.remove(id);
+                               }
+                       }
+               }
+       }
+
+       private String[] getUserAndBuiltInPatterns() {
+               List patterns = new ArrayList(fUserDefinedPatterns.length);
+               if (areUserDefinedPatternsEnabled())
+                       patterns.addAll(Arrays.asList(fUserDefinedPatterns));
+               FilterDescriptor[] filterDescs = FilterDescriptor
+                               .getFilterDescriptors(fTargetId);
+               for (int i = 0; i < filterDescs.length; i++) {
+                       String id = filterDescs[i].getId();
+                       boolean isPatternFilter = filterDescs[i].isPatternFilter();
+                       Object isEnabled = fEnabledFilterIds.get(id);
+                       if (isEnabled != null && isPatternFilter
+                                       && ((Boolean) isEnabled).booleanValue())
+                               patterns.add(filterDescs[i].getPattern());
+               }
+               return (String[]) patterns.toArray(new String[patterns.size()]);
+       }
+
+       // ---------- view kind/defaults persistency ----------
+
+       private void initializeWithViewDefaults() {
+               // get default values for view
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+
+               // XXX: can be removed once bug 22533 is fixed.
+               if (!store.contains(getPreferenceKey("TAG_DUMMY_TO_TEST_EXISTENCE")))//$NON-NLS-1$
+                       return;
+
+               // XXX: Uncomment once bug 22533 is fixed.
+               // if
+               // (!store.contains(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED)))
+               // return;
+
+               fUserDefinedPatternsEnabled = store
+                               .getBoolean(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED));
+               setUserDefinedPatterns(CustomFiltersDialog.convertFromString(store
+                               .getString(getPreferenceKey(TAG_USER_DEFINED_PATTERNS)),
+                               SEPARATOR));
+
+               Iterator iter = fEnabledFilterIds.keySet().iterator();
+               while (iter.hasNext()) {
+                       String id = (String) iter.next();
+                       Boolean isEnabled = new Boolean(store.getBoolean(id));
+                       fEnabledFilterIds.put(id, isEnabled);
+               }
+
+               fLRUFilterIdsStack.clear();
+               String lruFilterIds = store.getString(TAG_LRU_FILTERS);
+               StringTokenizer tokenizer = new StringTokenizer(lruFilterIds, SEPARATOR);
+               while (tokenizer.hasMoreTokens()) {
+                       String id = tokenizer.nextToken();
+                       if (fFilterDescriptorMap.containsKey(id)
+                                       && !fLRUFilterIdsStack.contains(id))
+                               fLRUFilterIdsStack.push(id);
+               }
+       }
+
+       private void storeViewDefaults() {
+               // get default values for view
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+
+               // XXX: can be removed once bug 22533 is fixed.
+               store
+                               .setValue(
+                                               getPreferenceKey("TAG_DUMMY_TO_TEST_EXISTENCE"), "storedViewPreferences");//$NON-NLS-1$//$NON-NLS-2$
+
+               store.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED),
+                               fUserDefinedPatternsEnabled);
+               store.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS),
+                               CustomFiltersDialog.convertToString(fUserDefinedPatterns,
+                                               SEPARATOR));
+
+               Iterator iter = fEnabledFilterIds.entrySet().iterator();
+               while (iter.hasNext()) {
+                       Map.Entry entry = (Map.Entry) iter.next();
+                       String id = (String) entry.getKey();
+                       boolean isEnabled = ((Boolean) entry.getValue()).booleanValue();
+                       store.setValue(id, isEnabled);
+               }
+
+               StringBuffer buf = new StringBuffer(fLRUFilterIdsStack.size() * 20);
+               iter = fLRUFilterIdsStack.iterator();
+               while (iter.hasNext()) {
+                       buf.append((String) iter.next());
+                       buf.append(SEPARATOR);
+               }
+               store.setValue(TAG_LRU_FILTERS, buf.toString());
+       }
+
+       private String getPreferenceKey(String tag) {
+               return "CustomFiltersActionGroup." + fTargetId + '.' + tag; //$NON-NLS-1$
+       }
+
+       // ---------- view instance persistency ----------
+
+       /**
+        * Saves the state of the custom filters in a memento.
+        * 
+        * @param memento
+        *            the memento into which the state is saved
+        */
+       public void saveState(IMemento memento) {
+               IMemento customFilters = memento.createChild(TAG_CUSTOM_FILTERS);
+               customFilters.putString(TAG_USER_DEFINED_PATTERNS_ENABLED, new Boolean(
+                               fUserDefinedPatternsEnabled).toString());
+               saveUserDefinedPatterns(customFilters);
+               saveXmlDefinedFilters(customFilters);
+               saveLRUFilters(customFilters);
+       }
+
+       private void saveXmlDefinedFilters(IMemento memento) {
+               if (fEnabledFilterIds != null && !fEnabledFilterIds.isEmpty()) {
+                       IMemento xmlDefinedFilters = memento
+                                       .createChild(TAG_XML_DEFINED_FILTERS);
+                       Iterator iter = fEnabledFilterIds.entrySet().iterator();
+                       while (iter.hasNext()) {
+                               Map.Entry entry = (Map.Entry) iter.next();
+                               String id = (String) entry.getKey();
+                               Boolean isEnabled = (Boolean) entry.getValue();
+                               IMemento child = xmlDefinedFilters.createChild(TAG_CHILD);
+                               child.putString(TAG_FILTER_ID, id);
+                               child.putString(TAG_IS_ENABLED, isEnabled.toString());
+                       }
+               }
+       }
+
+       /**
+        * Stores the last recently used filter Ids into the given memento
+        * 
+        * @param memento
+        *            the memento into which to store the LRU filter Ids
+        * @since 3.0
+        */
+       private void saveLRUFilters(IMemento memento) {
+               if (fLRUFilterIdsStack != null && !fLRUFilterIdsStack.isEmpty()) {
+                       IMemento lruFilters = memento.createChild(TAG_LRU_FILTERS);
+                       Iterator iter = fLRUFilterIdsStack.iterator();
+                       while (iter.hasNext()) {
+                               String id = (String) iter.next();
+                               IMemento child = lruFilters.createChild(TAG_CHILD);
+                               child.putString(TAG_FILTER_ID, id);
+                       }
+               }
+       }
+
+       private void saveUserDefinedPatterns(IMemento memento) {
+               if (fUserDefinedPatterns != null && fUserDefinedPatterns.length > 0) {
+                       IMemento userDefinedPatterns = memento
+                                       .createChild(TAG_USER_DEFINED_PATTERNS);
+                       for (int i = 0; i < fUserDefinedPatterns.length; i++) {
+                               IMemento child = userDefinedPatterns.createChild(TAG_CHILD);
+                               child.putString(TAG_PATTERN, fUserDefinedPatterns[i]);
+                       }
+               }
+       }
+
+       /**
+        * Restores the state of the filter actions from a memento.
+        * <p>
+        * Note: This method does not refresh the viewer.
+        * </p>
+        * 
+        * @param memento
+        *            the memento from which the state is restored
+        */
+       public void restoreState(IMemento memento) {
+               if (memento == null)
+                       return;
+               IMemento customFilters = memento.getChild(TAG_CUSTOM_FILTERS);
+               if (customFilters == null)
+                       return;
+               String userDefinedPatternsEnabled = customFilters
+                               .getString(TAG_USER_DEFINED_PATTERNS_ENABLED);
+               if (userDefinedPatternsEnabled == null)
+                       return;
+
+               fUserDefinedPatternsEnabled = Boolean.valueOf(
+                               userDefinedPatternsEnabled).booleanValue();
+               restoreUserDefinedPatterns(customFilters);
+               restoreXmlDefinedFilters(customFilters);
+               restoreLRUFilters(customFilters);
+
+               updateViewerFilters(false);
+       }
+
+       private void restoreUserDefinedPatterns(IMemento memento) {
+               IMemento userDefinedPatterns = memento
+                               .getChild(TAG_USER_DEFINED_PATTERNS);
+               if (userDefinedPatterns != null) {
+                       IMemento children[] = userDefinedPatterns.getChildren(TAG_CHILD);
+                       String[] patterns = new String[children.length];
+                       for (int i = 0; i < children.length; i++)
+                               patterns[i] = children[i].getString(TAG_PATTERN);
+
+                       setUserDefinedPatterns(patterns);
+               } else
+                       setUserDefinedPatterns(new String[0]);
+       }
+
+       private void restoreXmlDefinedFilters(IMemento memento) {
+               IMemento xmlDefinedFilters = memento.getChild(TAG_XML_DEFINED_FILTERS);
+               if (xmlDefinedFilters != null) {
+                       IMemento[] children = xmlDefinedFilters.getChildren(TAG_CHILD);
+                       for (int i = 0; i < children.length; i++) {
+                               String id = children[i].getString(TAG_FILTER_ID);
+                               Boolean isEnabled = new Boolean(children[i]
+                                               .getString(TAG_IS_ENABLED));
+                               fEnabledFilterIds.put(id, isEnabled);
+                       }
+               }
+       }
+
+       private void restoreLRUFilters(IMemento memento) {
+               IMemento lruFilters = memento.getChild(TAG_LRU_FILTERS);
+               fLRUFilterIdsStack.clear();
+               if (lruFilters != null) {
+                       IMemento[] children = lruFilters.getChildren(TAG_CHILD);
+                       for (int i = 0; i < children.length; i++) {
+                               String id = children[i].getString(TAG_FILTER_ID);
+                               if (fFilterDescriptorMap.containsKey(id)
+                                               && !fLRUFilterIdsStack.contains(id))
+                                       fLRUFilterIdsStack.push(id);
+                       }
+               }
+       }
+
+       private void cleanUpPatternDuplicates() {
+               if (!areUserDefinedPatternsEnabled())
+                       return;
+               List userDefinedPatterns = new ArrayList(Arrays
+                               .asList(fUserDefinedPatterns));
+               FilterDescriptor[] filters = FilterDescriptor
+                               .getFilterDescriptors(fTargetId);
+
+               for (int i = 0; i < filters.length; i++) {
+                       if (filters[i].isPatternFilter()) {
+                               String pattern = filters[i].getPattern();
+                               if (userDefinedPatterns.contains(pattern)) {
+                                       fEnabledFilterIds.put(filters[i].getId(), Boolean.TRUE);
+                                       boolean hasMore = true;
+                                       while (hasMore)
+                                               hasMore = userDefinedPatterns.remove(pattern);
+                               }
+                       }
+               }
+               fUserDefinedPatterns = (String[]) userDefinedPatterns
+                               .toArray(new String[userDefinedPatterns.size()]);
+               setUserDefinedPatternsEnabled(fUserDefinedPatternsEnabled
+                               && fUserDefinedPatterns.length > 0);
+       }
+
+       // ---------- dialog related code ----------
+
+       private void openDialog() {
+               CustomFiltersDialog dialog = new CustomFiltersDialog(fViewer
+                               .getControl().getShell(), fTargetId,
+                               areUserDefinedPatternsEnabled(), fUserDefinedPatterns,
+                               getEnabledFilterIds());
+
+               if (dialog.open() == Window.OK) {
+                       setEnabledFilterIds(dialog.getEnabledFilterIds());
+                       setUserDefinedPatternsEnabled(dialog
+                                       .areUserDefinedPatternsEnabled());
+                       setUserDefinedPatterns(dialog.getUserDefinedPatterns());
+                       setRecentlyChangedFilters(dialog.getFilterDescriptorChangeHistory());
+
+                       storeViewDefaults();
+
+                       updateViewerFilters(true);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/GenerateActionGroup.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/GenerateActionGroup.java
new file mode 100644 (file)
index 0000000..f627deb
--- /dev/null
@@ -0,0 +1,395 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.ui.actions;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.actions.ActionMessages;
+import net.sourceforge.phpdt.internal.ui.actions.AddTaskAction;
+import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.util.Assert;
+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.ui.IActionBars;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.actions.AddBookmarkAction;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.part.Page;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * Action group that adds the source and generate actions to a part's context
+ * menu and installs handlers for the corresponding global menu actions.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class GenerateActionGroup extends ActionGroup {
+       /**
+        * Pop-up menu: id of the source sub menu (value
+        * <code>net.sourceforge.phpdt.ui.source.menu</code>).
+        * 
+        * @since 3.0
+        */
+       public static final String MENU_ID = "net.sourceforge.pheclipse.ui.source.menu"; //$NON-NLS-1$
+
+       private PHPEditor fEditor;
+
+       // private boolean fEditorIsOwner;
+       private IWorkbenchSite fSite;
+
+       private String fGroupName = IContextMenuConstants.GROUP_SOURCE;
+
+       private List fRegisteredSelectionListeners;
+
+       // private AddImportOnSelectionAction fAddImport;
+       // private OverrideMethodsAction fOverrideMethods;
+       // private AddGetterSetterAction fAddGetterSetter;
+       // private AddUnimplementedConstructorsAction fAddUnimplementedConstructors;
+       // private AddJavaDocStubAction fAddJavaDocStub;
+       private AddBookmarkAction fAddBookmark;
+
+       private AddTaskAction fAddTaskAction;
+
+       // private ExternalizeStringsAction fExternalizeStrings;
+       // private FindStringsToExternalizeAction fFindStringsToExternalize;
+       // private SurroundWithTryCatchAction fSurroundWithTryCatch;
+
+       // private OrganizeImportsAction fOrganizeImports;
+
+       /**
+        * Note: This constructor is for internal use only. Clients should not call
+        * this constructor.
+        */
+       public GenerateActionGroup(PHPEditor editor, String groupName) {
+               fSite = editor.getSite();
+               fEditor = editor;
+               fGroupName = groupName;
+
+               ISelectionProvider provider = fSite.getSelectionProvider();
+               ISelection selection = provider.getSelection();
+
+               // fAddImport= new AddImportOnSelectionAction(editor);
+               // fAddImport.setActionDefinitionId(IJavaEditorActionDefinitionIds.ADD_IMPORT);
+               // fAddImport.update();
+               // editor.setAction("AddImport", fAddImport); //$NON-NLS-1$
+
+               // fOrganizeImports= new OrganizeImportsAction(editor);
+               // fOrganizeImports.setActionDefinitionId(IJavaEditorActionDefinitionIds.ORGANIZE_IMPORTS);
+               // fOrganizeImports.editorStateChanged();
+               // editor.setAction("OrganizeImports", fOrganizeImports); //$NON-NLS-1$
+
+               // fOverrideMethods= new OverrideMethodsAction(editor);
+               // fOverrideMethods.setActionDefinitionId(IJavaEditorActionDefinitionIds.OVERRIDE_METHODS);
+               // fOverrideMethods.editorStateChanged();
+               // editor.setAction("OverrideMethods", fOverrideMethods); //$NON-NLS-1$
+
+               // fAddGetterSetter= new AddGetterSetterAction(editor);
+               // fAddGetterSetter.setActionDefinitionId(IJavaEditorActionDefinitionIds.CREATE_GETTER_SETTER);
+               // fAddGetterSetter.editorStateChanged();
+               // editor.setAction("AddGetterSetter", fAddGetterSetter); //$NON-NLS-1$
+
+               // fAddUnimplementedConstructors= new
+               // AddUnimplementedConstructorsAction(editor);
+               // fAddUnimplementedConstructors.setActionDefinitionId(IJavaEditorActionDefinitionIds.ADD_UNIMPLEMENTED_CONTRUCTORS);
+               // fAddUnimplementedConstructors.editorStateChanged();
+               // editor.setAction("AddUnimplementedConstructors",
+               // fAddUnimplementedConstructors); //$NON-NLS-1$
+
+               // fAddJavaDocStub= new AddJavaDocStubAction(editor);
+               // fAddJavaDocStub.editorStateChanged();
+               //
+               // fSurroundWithTryCatch= new SurroundWithTryCatchAction(editor);
+               // fSurroundWithTryCatch.setActionDefinitionId(IJavaEditorActionDefinitionIds.SURROUND_WITH_TRY_CATCH);
+               // fSurroundWithTryCatch.update(selection);
+               // provider.addSelectionChangedListener(fSurroundWithTryCatch);
+               // editor.setAction("SurroundWithTryCatch", fSurroundWithTryCatch);
+               // //$NON-NLS-1$
+               //
+               // fExternalizeStrings= new ExternalizeStringsAction(editor);
+               // fExternalizeStrings.setActionDefinitionId(IJavaEditorActionDefinitionIds.EXTERNALIZE_STRINGS);
+               // fExternalizeStrings.editorStateChanged();
+               // editor.setAction("ExternalizeStrings", fExternalizeStrings);
+               // //$NON-NLS-1$
+
+       }
+
+       /**
+        * Creates a new <code>GenerateActionGroup</code>. The group requires
+        * that the selection provided by the page's selection provider is of type
+        * <code>org.eclipse.jface.viewers.IStructuredSelection</code>.
+        * 
+        * @param page
+        *            the page that owns this action group
+        */
+       public GenerateActionGroup(Page page) {
+               this(page.getSite());
+       }
+
+       /**
+        * Creates a new <code>GenerateActionGroup</code>. The group requires
+        * that the selection provided by the part's selection provider is of type
+        * <code>org.eclipse.jface.viewers.IStructuredSelection</code>.
+        * 
+        * @param part
+        *            the view part that owns this action group
+        */
+       public GenerateActionGroup(IViewPart part) {
+               this(part.getSite());
+       }
+
+       private GenerateActionGroup(IWorkbenchSite site) {
+               fSite = site;
+               ISelectionProvider provider = fSite.getSelectionProvider();
+               ISelection selection = provider.getSelection();
+
+               // fOverrideMethods= new OverrideMethodsAction(site);
+               // fAddGetterSetter= new AddGetterSetterAction(site);
+               // fAddUnimplementedConstructors= new
+               // AddUnimplementedConstructorsAction(site);
+               // fAddJavaDocStub= new AddJavaDocStubAction(site);
+               fAddBookmark = new AddBookmarkAction(site.getShell());
+               fAddTaskAction = new AddTaskAction(site);
+               // fExternalizeStrings= new ExternalizeStringsAction(site);
+               // fFindStringsToExternalize= new FindStringsToExternalizeAction(site);
+               // fOrganizeImports= new OrganizeImportsAction(site);
+               //
+               // fOverrideMethods.update(selection);
+               // fAddGetterSetter.update(selection);
+               // fAddUnimplementedConstructors.update(selection);
+               // fAddJavaDocStub.update(selection);
+               // fExternalizeStrings.update(selection);
+               // fFindStringsToExternalize.update(selection);
+               fAddTaskAction.update(selection);
+               // fOrganizeImports.update(selection);
+               if (selection instanceof IStructuredSelection) {
+                       IStructuredSelection ss = (IStructuredSelection) selection;
+                       fAddBookmark.selectionChanged(ss);
+               } else {
+                       fAddBookmark.setEnabled(false);
+               }
+
+               // registerSelectionListener(provider, fOverrideMethods);
+               // registerSelectionListener(provider, fAddGetterSetter);
+               // registerSelectionListener(provider, fAddUnimplementedConstructors);
+               // registerSelectionListener(provider, fAddJavaDocStub);
+               registerSelectionListener(provider, fAddBookmark);
+               // registerSelectionListener(provider, fExternalizeStrings);
+               // registerSelectionListener(provider, fFindStringsToExternalize);
+               // registerSelectionListener(provider, fOrganizeImports);
+               registerSelectionListener(provider, fAddTaskAction);
+       }
+
+       private void registerSelectionListener(ISelectionProvider provider,
+                       ISelectionChangedListener listener) {
+               if (fRegisteredSelectionListeners == null)
+                       fRegisteredSelectionListeners = new ArrayList(12);
+               provider.addSelectionChangedListener(listener);
+               fRegisteredSelectionListeners.add(listener);
+       }
+
+       /*
+        * The state of the editor owning this action group has changed. This method
+        * does nothing if the group's owner isn't an editor.
+        */
+       /**
+        * Note: This method is for internal use only. Clients should not call this
+        * method.
+        */
+       public void editorStateChanged() {
+               Assert.isTrue(isEditorOwner());
+
+               // http://dev.eclipse.org/bugs/show_bug.cgi?id=17709
+       }
+
+       /*
+        * (non-Javadoc) Method declared in ActionGroup
+        */
+       public void fillActionBars(IActionBars actionBar) {
+               super.fillActionBars(actionBar);
+               setGlobalActionHandlers(actionBar);
+       }
+
+       /*
+        * (non-Javadoc) Method declared in ActionGroup
+        */
+       // public void fillContextMenu(IMenuManager menu) {
+       // super.fillContextMenu(menu);
+       // if (fEditorIsOwner) {
+       // IMenuManager subMenu= createEditorSubMenu(menu);
+       // if (subMenu != null)
+       // menu.appendToGroup(fGroupName, subMenu);
+       // } else {
+       // // appendToGroup(menu, fOrganizeImports);
+       // // appendToGroup(menu, fOverrideMethods);
+       // // appendToGroup(menu, fAddGetterSetter);
+       // // appendToGroup(menu, fAddUnimplementedConstructors);
+       // // appendToGroup(menu, fAddJavaDocStub);
+       // appendToGroup(menu, fAddBookmark);
+       // }
+       // }
+       /*
+        * (non-Javadoc) Method declared in ActionGroup
+        */
+       // public void fillContextMenu(IMenuManager menu) {
+       // super.fillContextMenu(menu);
+       // IMenuManager subMenu= null;
+       // if (isEditorOwner()) {
+       // subMenu= fillEditorSubMenu(menu);
+       // } else {
+       // // subMenu= createViewSubMenu(menu);
+       // }
+       // if (subMenu != null)
+       // menu.appendToGroup(fGroupName, subMenu);
+       // }
+       public void fillContextMenu(IMenuManager menu) {
+               super.fillContextMenu(menu);
+               String shortCut = null; //$NON-NLS-1$
+               // if (fQuickAccessAction != null) {
+               // shortCut= fQuickAccessAction.getShortCutString(); //$NON-NLS-1$
+               // }
+               IMenuManager subMenu = new MenuManager(
+                               ActionMessages.getString("SourceMenu.label") + (shortCut != null ? "\t" + shortCut : ""), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                               MENU_ID);
+               int added = 0;
+               if (isEditorOwner()) {
+                       added = fillEditorSubMenu(subMenu);
+               }
+               // else {
+               // added= fillViewSubMenu(subMenu);
+               // }
+               if (added > 0)
+                       menu.appendToGroup(fGroupName, subMenu);
+       }
+
+       private int fillEditorSubMenu(IMenuManager source) {
+               // IMenuManager result= new
+               // MenuManager(ActionMessages.getString("SourceMenu.label"));
+               // //$NON-NLS-1$
+               int added = 0;
+               added += addEditorAction(source, "Comment"); //$NON-NLS-1$
+               added += addEditorAction(source, "Uncomment"); //$NON-NLS-1$
+               added += addEditorAction(source, "ToggleComment"); //$NON-NLS-1$
+               added += addEditorAction(source, "AddBlockComment"); //$NON-NLS-1$
+               added += addEditorAction(source, "RemoveBlockComment"); //$NON-NLS-1$
+               added += addEditorAction(source, "Format"); //$NON-NLS-1$
+               added += addEditorAction(source, "Indent"); //$NON-NLS-1$
+               // result.add(new Separator());
+               // added+= addAction(result, fOrganizeImports);
+               // added+= addAction(result, fAddImport);
+               // result.add(new Separator());
+               // added+= addAction(result, fOverrideMethods);
+               // added+= addAction(result, fAddGetterSetter);
+               // added+= addAction(result, fAddUnimplementedConstructors);
+               // added+= addAction(result, fAddJavaDocStub);
+               // added+= addAction(result, fAddBookmark);
+               // result.add(new Separator());
+               // added+= addAction(result, fSurroundWithTryCatch);
+               // added+= addAction(result, fExternalizeStrings);
+               // if (added == 0)
+               // result= null;
+               return added;
+       }
+
+       /*
+        * (non-Javadoc) Method declared in ActionGroup
+        */
+       public void dispose() {
+               if (fRegisteredSelectionListeners != null) {
+                       ISelectionProvider provider = fSite.getSelectionProvider();
+                       for (Iterator iter = fRegisteredSelectionListeners.iterator(); iter
+                                       .hasNext();) {
+                               ISelectionChangedListener listener = (ISelectionChangedListener) iter
+                                               .next();
+                               provider.removeSelectionChangedListener(listener);
+                       }
+               }
+               fEditor = null;
+               super.dispose();
+       }
+
+       private void setGlobalActionHandlers(IActionBars actionBar) {
+               // actionBar.setGlobalActionHandler(JdtActionConstants.ADD_IMPORT,
+               // fAddImport);
+               // actionBar.setGlobalActionHandler(JdtActionConstants.SURROUND_WITH_TRY_CATCH,
+               // fSurroundWithTryCatch);
+               // actionBar.setGlobalActionHandler(JdtActionConstants.OVERRIDE_METHODS,
+               // fOverrideMethods);
+               // actionBar.setGlobalActionHandler(JdtActionConstants.GENERATE_GETTER_SETTER,
+               // fAddGetterSetter);
+               // actionBar.setGlobalActionHandler(JdtActionConstants.ADD_CONSTRUCTOR_FROM_SUPERCLASS,
+               // fAddUnimplementedConstructors);
+               // actionBar.setGlobalActionHandler(JdtActionConstants.ADD_JAVA_DOC_COMMENT,
+               // fAddJavaDocStub);
+               // actionBar.setGlobalActionHandler(JdtActionConstants.EXTERNALIZE_STRINGS,
+               // fExternalizeStrings);
+               // actionBar.setGlobalActionHandler(JdtActionConstants.FIND_STRINGS_TO_EXTERNALIZE,
+               // fFindStringsToExternalize);
+               // actionBar.setGlobalActionHandler(JdtActionConstants.ORGANIZE_IMPORTS,
+               // fOrganizeImports);
+               if (!isEditorOwner()) {
+                       // editor provides its own implementation of these actions.
+                       actionBar.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(),
+                                       fAddBookmark);
+                       actionBar.setGlobalActionHandler(IDEActionFactory.ADD_TASK.getId(),
+                                       fAddTaskAction);
+               }
+       }
+
+       private int appendToGroup(IMenuManager menu, IAction action) {
+               if (action != null && action.isEnabled()) {
+                       menu.appendToGroup(fGroupName, action);
+                       return 1;
+               }
+               return 0;
+       }
+
+       private int addAction(IMenuManager menu, IAction action) {
+               if (action != null && action.isEnabled()) {
+                       menu.add(action);
+                       return 1;
+               }
+               return 0;
+       }
+
+       private int addEditorAction(IMenuManager menu, String actionID) {
+               if (fEditor == null)
+                       return 0;
+               IAction action = fEditor.getAction(actionID);
+               if (action == null)
+                       return 0;
+               if (action instanceof IUpdate)
+                       ((IUpdate) action).update();
+               if (action.isEnabled()) {
+                       menu.add(action);
+                       return 1;
+               }
+               return 0;
+       }
+
+       private boolean isEditorOwner() {
+               return fEditor != null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/GotoMatchingBracketAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/GotoMatchingBracketAction.java
new file mode 100644 (file)
index 0000000..ae586c0
--- /dev/null
@@ -0,0 +1,31 @@
+package net.sourceforge.phpdt.ui.actions;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import net.sourceforge.phpdt.internal.corext.Assert;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditorMessages;
+
+import org.eclipse.jface.action.Action;
+
+public class GotoMatchingBracketAction extends Action {
+
+       public final static String GOTO_MATCHING_BRACKET = "GotoMatchingBracket"; //$NON-NLS-1$
+
+       private final PHPEditor fEditor;
+
+       public GotoMatchingBracketAction(PHPEditor editor) {
+               super(PHPEditorMessages.getString("GotoMatchingBracket.label"));
+               Assert.isNotNull(editor);
+               fEditor = editor;
+               setEnabled(null != fEditor);
+       }
+
+       public void run() {
+               fEditor.gotoMatchingBracket();
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/MemberFilterActionGroup.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/MemberFilterActionGroup.java
new file mode 100644 (file)
index 0000000..25d3159
--- /dev/null
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.actions;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.actions.ActionMessages;
+import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilter;
+import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilterAction;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.actions.ActionGroup;
+
+/**
+ * Action Group that contributes filter buttons for a view parts showing methods
+ * and fields. Contributed filters are: hide fields, hide static members and
+ * hide non-public members.
+ * <p>
+ * The action group installs a filter on a structured viewer. The filter is
+ * connected to the actions installed in the view part's toolbar menu and is
+ * updated when the state of the buttons changes.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class MemberFilterActionGroup extends ActionGroup {
+
+       public static final int FILTER_NONPUBLIC = MemberFilter.FILTER_NONPUBLIC;
+
+       public static final int FILTER_STATIC = MemberFilter.FILTER_STATIC;
+
+       public static final int FILTER_FIELDS = MemberFilter.FILTER_FIELDS;
+
+       private static final String TAG_HIDEFIELDS = "hidefields"; //$NON-NLS-1$
+
+       private static final String TAG_HIDESTATIC = "hidestatic"; //$NON-NLS-1$
+
+       private static final String TAG_HIDENONPUBLIC = "hidenonpublic"; //$NON-NLS-1$
+
+       private MemberFilterAction[] fFilterActions;
+
+       private MemberFilter fFilter;
+
+       private StructuredViewer fViewer;
+
+       private String fViewerId;
+
+       private boolean fInViewMenu;
+
+       /**
+        * Creates a new <code>MemberFilterActionGroup</code>.
+        * 
+        * @param viewer
+        *            the viewer to be filtered
+        * @param viewerId
+        *            a unique id of the viewer. Used as a key to to store the last
+        *            used filter settings in the preference store
+        */
+       public MemberFilterActionGroup(StructuredViewer viewer, String viewerId) {
+               this(viewer, viewerId, false);
+       }
+
+       /**
+        * Creates a new <code>MemberFilterActionGroup</code>.
+        * 
+        * @param viewer
+        *            the viewer to be filtered
+        * @param viewerId
+        *            a unique id of the viewer. Used as a key to to store the last
+        *            used filter settings in the preference store
+        * @param inViewMenu
+        *            if <code>true</code> the actions are added to the view menu.
+        *            If <code>false</code> they are added to the toobar.
+        * 
+        * @since 2.1
+        */
+       public MemberFilterActionGroup(StructuredViewer viewer, String viewerId,
+                       boolean inViewMenu) {
+               fViewer = viewer;
+               fViewerId = viewerId;
+               fInViewMenu = inViewMenu;
+
+               // get initial values
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               boolean doHideFields = store
+                               .getBoolean(getPreferenceKey(FILTER_FIELDS));
+               boolean doHideStatic = store
+                               .getBoolean(getPreferenceKey(FILTER_STATIC));
+               boolean doHidePublic = store
+                               .getBoolean(getPreferenceKey(FILTER_NONPUBLIC));
+
+               fFilter = new MemberFilter();
+               if (doHideFields)
+                       fFilter.addFilter(FILTER_FIELDS);
+               if (doHideStatic)
+                       fFilter.addFilter(FILTER_STATIC);
+               if (doHidePublic)
+                       fFilter.addFilter(FILTER_NONPUBLIC);
+
+               // fields
+               String title = ActionMessages
+                               .getString("MemberFilterActionGroup.hide_fields.label"); //$NON-NLS-1$
+               String helpContext = IJavaHelpContextIds.FILTER_FIELDS_ACTION;
+               MemberFilterAction hideFields = new MemberFilterAction(this, title,
+                               FILTER_FIELDS, helpContext, doHideFields);
+               hideFields.setDescription(ActionMessages
+                               .getString("MemberFilterActionGroup.hide_fields.description")); //$NON-NLS-1$
+               hideFields.setToolTipText(ActionMessages
+                               .getString("MemberFilterActionGroup.hide_fields.tooltip")); //$NON-NLS-1$
+               PHPUiImages.setLocalImageDescriptors(hideFields, "fields_co.gif"); //$NON-NLS-1$
+
+               // static
+               title = ActionMessages
+                               .getString("MemberFilterActionGroup.hide_static.label"); //$NON-NLS-1$
+               helpContext = IJavaHelpContextIds.FILTER_STATIC_ACTION;
+               MemberFilterAction hideStatic = new MemberFilterAction(this, title,
+                               FILTER_STATIC, helpContext, doHideStatic);
+               hideStatic.setDescription(ActionMessages
+                               .getString("MemberFilterActionGroup.hide_static.description")); //$NON-NLS-1$
+               hideStatic.setToolTipText(ActionMessages
+                               .getString("MemberFilterActionGroup.hide_static.tooltip")); //$NON-NLS-1$
+               PHPUiImages.setLocalImageDescriptors(hideStatic, "static_co.gif"); //$NON-NLS-1$
+
+               // non-public
+               title = ActionMessages
+                               .getString("MemberFilterActionGroup.hide_nonpublic.label"); //$NON-NLS-1$
+               helpContext = IJavaHelpContextIds.FILTER_PUBLIC_ACTION;
+               MemberFilterAction hideNonPublic = new MemberFilterAction(this, title,
+                               FILTER_NONPUBLIC, helpContext, doHidePublic);
+               hideNonPublic
+                               .setDescription(ActionMessages
+                                               .getString("MemberFilterActionGroup.hide_nonpublic.description")); //$NON-NLS-1$
+               hideNonPublic.setToolTipText(ActionMessages
+                               .getString("MemberFilterActionGroup.hide_nonpublic.tooltip")); //$NON-NLS-1$
+               PHPUiImages.setLocalImageDescriptors(hideNonPublic, "public_co.gif"); //$NON-NLS-1$
+
+               // order corresponds to order in toolbar
+               fFilterActions = new MemberFilterAction[] { hideFields, hideStatic,
+                               hideNonPublic };
+
+               fViewer.addFilter(fFilter);
+       }
+
+       private String getPreferenceKey(int filterProperty) {
+               return "MemberFilterActionGroup." + fViewerId + '.' + String.valueOf(filterProperty); //$NON-NLS-1$
+       }
+
+       /**
+        * Sets the member filters.
+        * 
+        * @param filterProperty
+        *            the filter to be manipulated. Valid values are
+        *            <code>FILTER_FIELDS</code>, <code>FILTER_PUBLIC</code>,
+        *            and <code>FILTER_PRIVATE</code> as defined by this action
+        *            group
+        * @param set
+        *            if <code>true</code> the given filter is installed. If
+        *            <code>false</code> the given filter is removed .
+        */
+       public void setMemberFilter(int filterProperty, boolean set) {
+               setMemberFilters(new int[] { filterProperty }, new boolean[] { set },
+                               true);
+       }
+
+       private void setMemberFilters(int[] propertyKeys, boolean[] propertyValues,
+                       boolean refresh) {
+               if (propertyKeys.length == 0)
+                       return;
+               Assert.isTrue(propertyKeys.length == propertyValues.length);
+
+               for (int i = 0; i < propertyKeys.length; i++) {
+                       int filterProperty = propertyKeys[i];
+                       boolean set = propertyValues[i];
+                       if (set) {
+                               fFilter.addFilter(filterProperty);
+                       } else {
+                               fFilter.removeFilter(filterProperty);
+                       }
+                       IPreferenceStore store = WebUI.getDefault()
+                                       .getPreferenceStore();
+
+                       for (int j = 0; j < fFilterActions.length; j++) {
+                               int currProperty = fFilterActions[j].getFilterProperty();
+                               if (currProperty == filterProperty) {
+                                       fFilterActions[j].setChecked(set);
+                               }
+                               store.setValue(getPreferenceKey(currProperty),
+                                               hasMemberFilter(currProperty));
+                       }
+               }
+               if (refresh) {
+                       fViewer.getControl().setRedraw(false);
+                       BusyIndicator.showWhile(fViewer.getControl().getDisplay(),
+                                       new Runnable() {
+                                               public void run() {
+                                                       fViewer.refresh();
+                                               }
+                                       });
+                       fViewer.getControl().setRedraw(true);
+               }
+       }
+
+       /**
+        * Returns <code>true</code> if the given filter is installed.
+        * 
+        * @param filterProperty
+        *            the filter to be tested. Valid values are
+        *            <code>FILTER_FIELDS</code>, <code>FILTER_PUBLIC</code>,
+        *            and <code>FILTER_PRIVATE</code> as defined by this action
+        *            group
+        */
+       public boolean hasMemberFilter(int filterProperty) {
+               return fFilter.hasFilter(filterProperty);
+       }
+
+       /**
+        * Saves the state of the filter actions in a memento.
+        * 
+        * @param memento
+        *            the memento to which the state is saved
+        */
+       public void saveState(IMemento memento) {
+               memento.putString(TAG_HIDEFIELDS, String
+                               .valueOf(hasMemberFilter(FILTER_FIELDS)));
+               memento.putString(TAG_HIDESTATIC, String
+                               .valueOf(hasMemberFilter(FILTER_STATIC)));
+               memento.putString(TAG_HIDENONPUBLIC, String
+                               .valueOf(hasMemberFilter(FILTER_NONPUBLIC)));
+       }
+
+       /**
+        * Restores the state of the filter actions from a memento.
+        * <p>
+        * Note: This method does not refresh the viewer.
+        * </p>
+        * 
+        * @param memento
+        *            the memento from which the state is restored
+        */
+       public void restoreState(IMemento memento) {
+               setMemberFilters(new int[] { FILTER_FIELDS, FILTER_STATIC,
+                               FILTER_NONPUBLIC }, new boolean[] {
+                               Boolean.valueOf(memento.getString(TAG_HIDEFIELDS))
+                                               .booleanValue(),
+                               Boolean.valueOf(memento.getString(TAG_HIDESTATIC))
+                                               .booleanValue(),
+                               Boolean.valueOf(memento.getString(TAG_HIDENONPUBLIC))
+                                               .booleanValue() }, false);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see ActionGroup#fillActionBars(IActionBars)
+        */
+       public void fillActionBars(IActionBars actionBars) {
+               contributeToToolBar(actionBars.getToolBarManager());
+       };
+
+       /**
+        * Adds the filter actions to the given tool bar
+        * 
+        * @param tbm
+        *            the tool bar to which the actions are added
+        */
+       public void contributeToToolBar(IToolBarManager tbm) {
+               if (fInViewMenu)
+                       return;
+               tbm.add(fFilterActions[0]); // fields
+               tbm.add(fFilterActions[1]); // static
+               tbm.add(fFilterActions[2]); // public
+       }
+
+       /**
+        * Adds the filter actions to the given menu manager.
+        * 
+        * @param menu
+        *            the menu manager to which the actions are added
+        * @since 2.1
+        */
+       public void contributeToViewMenu(IMenuManager menu) {
+               if (!fInViewMenu)
+                       return;
+               final String filters = "filters"; //$NON-NLS-1$
+               if (menu.find(filters) != null) {
+                       menu.prependToGroup(filters, fFilterActions[0]); // fields
+                       menu.prependToGroup(filters, fFilterActions[1]); // static
+                       menu.prependToGroup(filters, fFilterActions[2]); // public
+               } else {
+                       menu.add(fFilterActions[0]); // fields
+                       menu.add(fFilterActions[1]); // static
+                       menu.add(fFilterActions[2]); // public
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see ActionGroup#dispose()
+        */
+       public void dispose() {
+               super.dispose();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/OpenEditorActionGroup.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/OpenEditorActionGroup.java
new file mode 100644 (file)
index 0000000..a1474ea
--- /dev/null
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.actions;
+
+import net.sourceforge.phpdt.internal.ui.actions.ActionMessages;
+import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import net.sourceforge.phpeclipse.actions.PHPOpenDeclarationAction;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.actions.OpenWithMenu;
+
+/**
+ * Action group that adds the actions opening a new editor to the context menu
+ * and the action bar's navigate menu.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class OpenEditorActionGroup extends ActionGroup {
+
+       private IWorkbenchSite fSite;
+
+       private boolean fIsEditorOwner;
+
+       private PHPOpenDeclarationAction fOpen;
+
+       /**
+        * Creates a new <code>OpenActionGroup</code>. The group requires that
+        * the selection provided by the part's selection provider is of type <code>
+        * org.eclipse.jface.viewers.IStructuredSelection</code>.
+        * 
+        * @param part
+        *            the view part that owns this action group
+        */
+       public OpenEditorActionGroup(IViewPart part) {
+               fSite = part.getSite();
+               fOpen = new PHPOpenDeclarationAction(fSite);
+               fOpen.setActionDefinitionId(PHPEditorActionDefinitionIds.OPEN_EDITOR);
+               initialize(fSite.getSelectionProvider());
+       }
+
+       /**
+        * Note: This constructor is for internal use only. Clients should not call
+        * this constructor.
+        */
+       public OpenEditorActionGroup(PHPEditor part) {
+               fIsEditorOwner = true;
+               fOpen = new PHPOpenDeclarationAction(part);
+               fOpen.setActionDefinitionId(PHPEditorActionDefinitionIds.OPEN_EDITOR);
+               part.setAction("OpenEditor", fOpen); //$NON-NLS-1$
+               fSite = part.getEditorSite();
+               initialize(fSite.getSelectionProvider());
+       }
+
+       /**
+        * Returns the open action managed by this action group.
+        * 
+        * @return the open action. Returns <code>null</code> if the group doesn't
+        *         provide any open action
+        */
+       public IAction getOpenAction() {
+               return fOpen;
+       }
+
+       private void initialize(ISelectionProvider provider) {
+               ISelection selection = provider.getSelection();
+               fOpen.update(selection);
+               if (!fIsEditorOwner) {
+                       provider.addSelectionChangedListener(fOpen);
+               }
+       }
+
+       /*
+        * (non-Javadoc) Method declared in ActionGroup
+        */
+       public void fillActionBars(IActionBars actionBar) {
+               super.fillActionBars(actionBar);
+               setGlobalActionHandlers(actionBar);
+       }
+
+       /*
+        * (non-Javadoc) Method declared in ActionGroup
+        */
+       public void fillContextMenu(IMenuManager menu) {
+               super.fillContextMenu(menu);
+               appendToGroup(menu, fOpen);
+               if (!fIsEditorOwner) {
+                       addOpenWithMenu(menu);
+               }
+       }
+
+       /*
+        * @see ActionGroup#dispose()
+        */
+       public void dispose() {
+               ISelectionProvider provider = fSite.getSelectionProvider();
+               provider.removeSelectionChangedListener(fOpen);
+               super.dispose();
+       }
+
+       private void setGlobalActionHandlers(IActionBars actionBars) {
+               actionBars.setGlobalActionHandler(PHPdtActionConstants.OPEN, fOpen);
+       }
+
+       private void appendToGroup(IMenuManager menu, IAction action) {
+               if (action.isEnabled())
+                       menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, action);
+       }
+
+       private void addOpenWithMenu(IMenuManager menu) {
+               ISelection selection = getContext().getSelection();
+               if (selection.isEmpty() || !(selection instanceof IStructuredSelection))
+                       return;
+               IStructuredSelection ss = (IStructuredSelection) selection;
+               if (ss.size() != 1)
+                       return;
+
+               Object o = ss.getFirstElement();
+               if (!(o instanceof IAdaptable))
+                       return;
+
+               IAdaptable element = (IAdaptable) o;
+               Object resource = element.getAdapter(IResource.class);
+               if (!(resource instanceof IFile))
+                       return;
+
+               // Create a menu flyout.
+               IMenuManager submenu = new MenuManager(ActionMessages
+                               .getString("OpenWithMenu.label")); //$NON-NLS-1$
+               submenu.add(new OpenWithMenu(fSite.getPage(), (IFile) resource));
+
+               // Add the submenu.
+               menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, submenu);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/OpenPHPPerspectiveAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/OpenPHPPerspectiveAction.java
new file mode 100644 (file)
index 0000000..577af0e
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.actions;
+
+import net.sourceforge.phpdt.internal.ui.actions.ActionMessages;
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+import net.sourceforge.phpdt.ui.JavaUI;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.WorkbenchException;
+
+/**
+ * Action to programmatically open a Java perspective.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class OpenPHPPerspectiveAction extends Action {
+
+       /**
+        * Create a new <code>OpenPHPPerspectiveAction</code>.
+        */
+       public OpenPHPPerspectiveAction() {
+               // WorkbenchHelp.setHelp(this,
+               // IJavaHelpContextIds.OPEN_JAVA_PERSPECTIVE_ACTION);
+       }
+
+       public void run() {
+               IWorkbench workbench = WebUI.getDefault().getWorkbench();
+               IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+               IWorkbenchPage page = window.getActivePage();
+               IAdaptable input;
+               if (page != null)
+                       input = page.getInput();
+               else
+                       input = ResourcesPlugin.getWorkspace().getRoot();
+               try {
+                       workbench.showPerspective(JavaUI.ID_PERSPECTIVE, window,
+                                       input);
+               } catch (WorkbenchException e) {
+                       ExceptionHandler
+                                       .handle(
+                                                       e,
+                                                       window.getShell(),
+                                                       ActionMessages
+                                                                       .getString("OpenPHPPerspectiveAction.dialog.title"), //$NON-NLS-1$
+                                                       ActionMessages
+                                                                       .getString("OpenPHPPerspectiveAction.error.open_failed")); //$NON-NLS-1$
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java
new file mode 100644 (file)
index 0000000..13c5b40
--- /dev/null
@@ -0,0 +1,42 @@
+package net.sourceforge.phpdt.ui.actions;
+
+public interface PHPEditorActionDefinitionIds {
+       /**
+        * Value: net.sourceforge.phpeclipse.phpeditor.comment
+        */
+       public static final String COMMENT = "net.sourceforge.phpdt.ui.actions.comment";
+
+       /**
+        * Value: net.sourceforge.phpeclipse.phpeditor.uncomment
+        */
+       public static final String UNCOMMENT = "net.sourceforge.phpdt.ui.actions.uncomment";
+
+       // navigate
+
+       /**
+        * Action definition ID of the navigate -> open action (value
+        * <code>"org.phpeclipse.phpdt.ui.edit.text.php.open.editor"</code>).
+        */
+       public static final String OPEN_EDITOR = "net.sourceforge.phpeclipse.ui.edit.text.java.open.editor"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the toggle presentation toolbar button action
+        * (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.toggle.presentation"</code>).
+        */
+       public static final String TOGGLE_PRESENTATION = "net.sourceforge.phpeclipse.ui.edit.text.java.toggle.presentation"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the toggle text hover toolbar button action
+        * (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.toggle.text.hover"</code>).
+        */
+       public static final String TOGGLE_TEXT_HOVER = "net.sourceforge.phpeclipse.ui.edit.text.java.toggle.text.hover"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the edit -> show Javadoc action (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.show.javadoc"</code>).
+        */
+       public static final String SHOW_JAVADOC = "net.sourceforge.phpeclipse.ui.edit.text.java.show.javadoc"; //$NON-NLS-1$
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/PHPdtActionConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/PHPdtActionConstants.java
new file mode 100644 (file)
index 0000000..b7b5df5
--- /dev/null
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.ui.actions;
+
+/**
+ * Action ids for standard actions, for groups in the menu bar, and for actions
+ * in context menus of PHPDT views.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class PHPdtActionConstants {
+
+       // Edit menu
+       /**
+        * Edit menu: name of standard Show Javadoc global action (value
+        * <code>"net.sourceforge.phpdt.ui.actions.ShowJavaDoc"</code>).
+        */
+       public static final String SHOW_JAVA_DOC = "net.sourceforge.phpeclipse.phpeditor.ShowJavaDoc"; //$NON-NLS-1$
+
+       /**
+        * Edit menu: name of standard Code Assist global action (value
+        * <code>"org.phpeclipse.phpdt.ui.actions.ContentAssist"</code>).
+        */
+       public static final String CONTENT_ASSIST = "net.sourceforge.phpeclipse.phpeditor.ContentAssist"; //$NON-NLS-1$
+
+       // Source menu
+
+       /**
+        * Source menu: name of standard Comment global action (value
+        * <code>"net.sourceforge.phpdt.ui.actions.Comment"</code>).
+        */
+       public static final String COMMENT = "net.sourceforge.phpeclipse.phpeditor.Comment"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Uncomment global action (value
+        * <code>"net.sourceforge.phpdt.ui.actions.Uncomment"</code>).
+        */
+       public static final String UNCOMMENT = "net.sourceforge.phpeclipse.phpeditor.Uncomment"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard ToggleComment global action (value
+        * <code>"net.sourceforge.phpdt.ui.actions.ToggleComment"</code>).
+        * 
+        * @since 3.0
+        */
+       public static final String TOGGLE_COMMENT = "net.sourceforge.phpeclipse.ui.actions.ToggleComment"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Comment global action (value
+        * <code>"net.sourceforge.phpdt.ui.actions.AddBlockComment"</code>).
+        * 
+        * @since 3.0
+        */
+       public static final String ADD_BLOCK_COMMENT = "net.sourceforge.phpeclipse.ui.actions.AddBlockComment"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Uncomment global action (value
+        * <code>"net.sourceforge.phpdt.ui.actions.RemoveBlockComment"</code>).
+        * 
+        * @since 3.0
+        */
+       public static final String REMOVE_BLOCK_COMMENT = "net.sourceforge.phpeclipse.ui.actions.RemoveBlockComment"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Indent global action (value
+        * <code>"net.sourceforge.phpdt.ui.actions.Indent"</code>).
+        * 
+        * @since 3.0
+        */
+       public static final String INDENT = "net.sourceforge.phpeclipse.ui.actions.Indent"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Shift Rightl action (value
+        * <code>"net.sourceforge.phpeclipse.phpeditor.ShiftRight"</code>).
+        */
+       public static final String SHIFT_RIGHT = "net.sourceforge.phpeclipse.phpeditor.ShiftRight"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Shift Left global action (value
+        * <code>"net.sourceforge.phpeclipse.phpeditor.ShiftLeft"</code>).
+        */
+       public static final String SHIFT_LEFT = "net.sourceforge.phpeclipse.phpeditor.ShiftLeft"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Format global action (value <code>"org.
+        * phpeclipse.phpdt.ui.actions.Format"</code>).
+        */
+       public static final String FORMAT = "net.sourceforge.phpeclipse.phpeditor.Format"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Convert Line Delimiters To Windows global
+        * action (value
+        * <code>"org.phpeclipse.phpdt.ui.actions.ConvertLineDelimitersToWindows"</code>).
+        */
+       public static String CONVERT_LINE_DELIMITERS_TO_WINDOWS = "net.sourceforge.phpeclipse.ui.actions.ConvertLineDelimitersToWindows"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard Convert Line Delimiters To UNIX global
+        * action (value
+        * <code>"org.phpeclipse.phpdt.ui.actions.ConvertLineDelimitersToUNIX"</code>).
+        */
+       public static String CONVERT_LINE_DELIMITERS_TO_UNIX = "net.sourceforge.phpeclipse.ui.actions.ConvertLineDelimitersToUNIX"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standardConvert Line Delimiters ToMac global action
+        * (value
+        * <code>"org.phpeclipse.phpdt.ui.actions.ConvertLineDelimitersToMac"</code>).
+        */
+       public static String CONVERT_LINE_DELIMITERS_TO_MAC = "net.sourceforge.phpeclipse.ui.actions.ConvertLineDelimitersToMac"; //$NON-NLS-1$
+
+       /**
+        * Navigate menu: name of standard Open global action (value
+        * <code>"org.phpeclipse.phpdt.ui.actions.Open"</code>).
+        */
+       public static final String OPEN = "net.sourceforge.phpeclipse.ui.actions.Open"; //$NON-NLS-1$
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/SelectionDispatchAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/actions/SelectionDispatchAction.java
new file mode 100644 (file)
index 0000000..41d8d34
--- /dev/null
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.ui.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.util.Assert;
+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 plugin.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public abstract class SelectionDispatchAction extends Action implements
+               ISelectionChangedListener {
+
+       private IWorkbenchSite fSite;
+
+       /**
+        * 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;
+       }
+
+       /**
+        * 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() {
+               return getSelectionProvider().getSelection();
+       }
+
+       /**
+        * 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.
+        * 
+        * @return the site's selection provider
+        */
+       public ISelectionProvider getSelectionProvider() {
+               return fSite.getSelectionProvider();
+       }
+
+       /**
+        * 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
+        */
+       protected void selectionChanged(IStructuredSelection selection) {
+               selectionChanged((ISelection) selection);
+       }
+
+       /**
+        * Executes this actions with the given structured selection. This default
+        * implementation calls <code>run(ISelection selection)</code>.
+        */
+       protected 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
+        */
+       protected void selectionChanged(ITextSelection selection) {
+               selectionChanged((ISelection) selection);
+       }
+
+       /**
+        * Executes this actions with the given text selection. This default
+        * implementation calls <code>run(ISelection selection)</code>.
+        */
+       protected 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
+        */
+       protected void selectionChanged(ISelection selection) {
+               setEnabled(false);
+       }
+
+       /**
+        * Executes this actions with the given selection. This default
+        * implementation does nothing.
+        */
+       protected 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);
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IColorManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IColorManager.java
new file mode 100644 (file)
index 0000000..2a6b3a5
--- /dev/null
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2001 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.ui.text;
+
+import org.eclipse.jface.text.source.ISharedTextColors;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * Manages SWT color objects for given color keys and given <code>RGB</code>
+ * objects. Until the <code>dispose</code> method is called, the same color
+ * object is returned for equal keys and equal <code>RGB</code> values.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ * 
+ * @see IJavaColorConstants
+ */
+public interface IColorManager extends ISharedTextColors {
+
+       /**
+        * Returns a color object for the given key. The color objects are
+        * remembered internally; the same color object is returned for equal keys.
+        * 
+        * @param key
+        *            the color key
+        * @return the color object for the given key
+        */
+       Color getColor(String key);
+
+       /**
+        * Returns the color object for the value represented by the given
+        * <code>RGB</code> object.
+        * 
+        * @param rgb
+        *            the rgb color specification
+        * @return the color object for the given rgb value
+        */
+       Color getColor(RGB rgb);
+
+       /**
+        * Disposes all color objects remembered by this color manager.
+        */
+       void dispose();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IColorManagerExtension.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IColorManagerExtension.java
new file mode 100644 (file)
index 0000000..15c0346
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.ui.text;
+
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * A color manager extension for extending <code>IColorManager</code>
+ * instances with new functionality.
+ * 
+ * @since 2.0
+ */
+public interface IColorManagerExtension {
+
+       /**
+        * Remembers the given color specification under the given key.
+        * 
+        * @param key
+        *            the color key
+        * @param rgb
+        *            the color specification
+        * @exception UnsupportedOperationException
+        *                if there is already a color specification remembered under
+        *                the given key
+        */
+       void bindColor(String key, RGB rgb);
+
+       /**
+        * Forgets the color specification remembered under the given key.
+        * 
+        * @param key
+        *            the color key
+        */
+       void unbindColor(String key);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IJavaColorConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/IJavaColorConstants.java
new file mode 100644 (file)
index 0000000..936d157
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.ui.text;
+
+/**
+ * Color keys used for syntax highlighting PHP code and PHPDoc compliant
+ * comments. A <code>IColorManager</code> is responsible for mapping concrete
+ * colors to these keys.
+ * <p>
+ * This interface declares static final fields only; it is not intended to be
+ * implemented.
+ * </p>
+ * 
+ * @see IColorManager
+ */
+public interface IJavaColorConstants {
+
+       /**
+        * Note: This constant is for internal use only. Clients should not use this
+        * constant. The prefix all color constants start with.
+        */
+       // String PREFIX= "php_"; //$NON-NLS-1$
+       //      
+       // /** The color key for multi-line comments in PHP code. */
+       // String PHP_MULTI_LINE_COMMENT= "php_multi_line_comment"; //$NON-NLS-1$
+       // /** The color key for single-line comments in PHP code. */
+       // String PHP_SINGLE_LINE_COMMENT= "php_single_line_comment"; //$NON-NLS-1$
+       // /** The color key for PHP keywords in PHP code. */
+       // String PHP_KEYWORD= "php_keyword"; //$NON-NLS-1$
+       // /** The color key for string and character literals in PHP code. */
+       // String PHP_STRING= "php_string"; //$NON-NLS-1$
+       // /** The color key for everthing in PHP code for which no other color is
+       // specified. */
+       // String PHP_DEFAULT= "php_default"; //$NON-NLS-1$
+       // /** The color key for predefined PHP function namesin PHP code. */
+       // String PHP_FUNCTIONNAME= "php_functionname"; //$NON-NLS-1$
+       // /** The color key for ($-)variables in PHP code. */
+       // String PHP_VARIABLE= "php_variable"; //$NON-NLS-1$
+       // /** The color key for constants in PHP code */
+       // String PHP_CONSTANT= "php_constant"; //$NON-NLS-1$
+       // /** The color key for the PHP built-in types in PHP code. */
+       // String PHP_TYPE= "php_type"; //$NON-NLS-1$
+
+       // /** The color key for PHPDoc keywords (<code>@foo</code>) in PHPDoc
+       // comments. */
+       // String PHPDOC_KEYWORD= "php_doc_keyword"; //$NON-NLS-1$
+       // /** The color key for HTML tags (<code>&lt;foo&gt;</code>) in PHPDoc
+       // comments. */
+       // String PHPDOC_TAG= "php_doc_tag"; //$NON-NLS-1$
+       // /** The color key for PHPDoc links (<code>{foo}</code>) in PHPDoc
+       // comments. */
+       // String PHPDOC_LINK= "php_doc_link"; //$NON-NLS-1$
+       // /** The color key for everthing in PHPDoc comments for which no other
+       // color is specified. */
+       // String PHPDOC_DEFAULT= "php_doc_default"; //$NON-NLS-1$
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java
new file mode 100644 (file)
index 0000000..028bc82
--- /dev/null
@@ -0,0 +1,736 @@
+package net.sourceforge.phpdt.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import net.sourceforge.phpdt.internal.ui.text.FastJavaPartitionScanner;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaColorManager;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.php.HTMLPartitionScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.SmartyCodeScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.SmartyDocCodeScanner;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+//
+// import org.phpeclipse.phpdt.internal.ui.text.FastJavaPartitionScanner;
+// import org.phpeclipse.phpdt.internal.ui.text.JavaColorManager;
+// import org.phpeclipse.phpdt.internal.ui.text.JavaPartitionScanner;
+// import org.phpeclipse.phpdt.internal.ui.text.SingleTokenJavaScanner;
+// import org.phpeclipse.phpdt.internal.ui.text.php.JavaCodeScanner;
+// import org.phpeclipse.phpdt.internal.ui.text.phpdoc.JavaDocScanner;
+
+/**
+ * Tools required to configure a Java text viewer. The color manager and all
+ * scanner exist only one time, i.e. the same instances are returned to all
+ * clients. Thus, clients share those tools.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ */
+public class JavaTextTools implements IPHPPartitions {
+       // private static final String[] TOKENS = {
+       // JSPScriptScanner.JSP_DEFAULT,
+       // JSPScriptScanner.JSP_BRACKET };
+       private final static String[] LEGAL_CONTENT_TYPES = new String[] {
+                       PHP_PHPDOC_COMMENT, PHP_MULTILINE_COMMENT, PHP_SINGLELINE_COMMENT,
+                       PHP_STRING_DQ, PHP_STRING_SQ, PHP_STRING_HEREDOC };
+
+       // private static XMLPartitionScanner HTML_PARTITION_SCANNER = null;
+
+       // private static FastJavaPartitionScanner PHP_PARTITION_SCANNER = null;
+
+       private static HTMLPartitionScanner SMARTY_PARTITION_SCANNER = null;
+
+       // private static XMLPartitionScanner XML_PARTITION_SCANNER = null;
+
+       // private final static String[] TYPES= new String[] {
+       // PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC,
+       // PHPPartitionScanner.JAVA_MULTILINE_COMMENT };
+       // private final static String[] TYPES = new String[] {
+       // IPHPPartitions.PHP_PARTITIONING,
+       // IPHPPartitions.PHP_PHPDOC_COMMENT,
+       // // IPHPPartitions.HTML,
+       // // IPHPPartitions.HTML_MULTILINE_COMMENT,
+       // IPHPPartitions.JAVASCRIPT,
+       // IPHPPartitions.CSS,
+       // IPHPPartitions.SMARTY,
+       // IPHPPartitions.SMARTY_MULTILINE_COMMENT };
+
+       /**
+        * This tools' preference listener.
+        */
+       private class PreferenceListener implements IPropertyChangeListener,
+                       Preferences.IPropertyChangeListener {
+               public void propertyChange(PropertyChangeEvent event) {
+                       adaptToPreferenceChange(event);
+               }
+
+               public void propertyChange(Preferences.PropertyChangeEvent event) {
+                       adaptToPreferenceChange(new PropertyChangeEvent(event.getSource(),
+                                       event.getProperty(), event.getOldValue(), event
+                                                       .getNewValue()));
+               }
+       };
+
+       // /** The color manager */
+       private JavaColorManager colorManager;
+
+       /** The PHP source code scanner */
+       private PHPCodeScanner fCodeScanner;
+
+       /** The PHP multiline comment scanner */
+       private SingleTokenPHPScanner fMultilineCommentScanner;
+
+       /** The Java singleline comment scanner */
+       private SingleTokenPHPScanner fSinglelineCommentScanner;
+
+       /** The PHP double quoted string scanner */
+       // private SingleTokenPHPScanner fStringDQScanner;
+       /** The PHP single quoted string scanner */
+       // private SingleTokenPHPScanner fStringSQScanner;
+       /** The PHPDoc scanner */
+       private PHPDocCodeScanner fPHPDocScanner;
+
+       /** The HTML scanner */
+       // private HTMLCodeScanner fHTMLScanner;
+       /** The Smarty scanner */
+       private SmartyCodeScanner fSmartyScanner;
+
+       /** The SmartyDoc scanner */
+       private SmartyDocCodeScanner fSmartyDocScanner;
+
+       /** The Java partitions scanner. */
+       private FastJavaPartitionScanner fPartitionScanner;
+
+       /** The preference store */
+       private IPreferenceStore fPreferenceStore;
+
+       /** The XML Language text tools */
+       private XMLTextTools xmlTextTools;
+
+       /**
+        * The core preference store.
+        * 
+        * @since 2.1
+        */
+       private Preferences fCorePreferenceStore;
+
+       /** The preference change listener */
+       private PreferenceListener fPreferenceListener = new PreferenceListener();
+
+       /** The JSP partitions scanner */
+       private PHPPartitionScanner jspPartitionScanner = null;
+
+       /** The JSP script subpartitions scanner */
+       // private JSPScriptScanner jspScriptScanner;
+       /** The PHP plain text scanner */
+       // private RuleBasedScanner jspTextScanner;
+       /** The PHP brackets scanner */
+       // private RuleBasedScanner jspBracketScanner;
+       /**
+        * Creates a new Java text tools collection.
+        * 
+        * @param store
+        *            the preference store to initialize the text tools. The text
+        *            tool instance installs a listener on the passed preference
+        *            store to adapt itself to changes in the preference store. In
+        *            general <code>PreferenceConstants.
+        *                      getPreferenceStore()</code>
+        *            should be used to initialize the text tools.
+        * @param coreStore
+        *            optional preference store to initialize the text tools. The
+        *            text tool instance installs a listener on the passed
+        *            preference store to adapt itself to changes in the preference
+        *            store.
+        * @see net.sourceforge.phpdt.ui.PreferenceConstants#getPreferenceStore()
+        * @since 2.1
+        */
+       public JavaTextTools(IPreferenceStore store, Preferences coreStore) {
+               this(store, coreStore, true);
+       }
+
+       /**
+        * Creates a new Java text tools collection.
+        * 
+        * @param store
+        *            the preference store to initialize the text tools. The text
+        *            tool instance installs a listener on the passed preference
+        *            store to adapt itself to changes in the preference store. In
+        *            general <code>PreferenceConstants.
+        *                      getPreferenceStore()</code>
+        *            shoould be used to initialize the text tools.
+        * @param coreStore
+        *            optional preference store to initialize the text tools. The
+        *            text tool instance installs a listener on the passed
+        *            preference store to adapt itself to changes in the preference
+        *            store.
+        * @param autoDisposeOnDisplayDispose
+        *            if <code>true</code> the color manager automatically
+        *            disposes all managed colors when the current display gets
+        *            disposed and all calls to
+        *            {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()}are
+        *            ignored.
+        * @see net.sourceforge.phpdt.ui.PreferenceConstants#getPreferenceStore()
+        * @since 2.1
+        */
+       public JavaTextTools(IPreferenceStore store, Preferences coreStore,
+                       boolean autoDisposeOnDisplayDispose) {
+               // super(store, TOKENS, );
+               // REVISIT: preference store
+               xmlTextTools = new XMLTextTools(/*XMLPlugin*/WebUI.getDefault()
+                               .getPreferenceStore());
+
+               colorManager = new JavaColorManager(autoDisposeOnDisplayDispose);
+               fPreferenceStore = store;
+               fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
+
+               fCorePreferenceStore = coreStore;
+               if (fCorePreferenceStore != null)
+                       fCorePreferenceStore.addPropertyChangeListener(fPreferenceListener);
+
+               fCodeScanner = new PHPCodeScanner((JavaColorManager) colorManager,
+                               store);
+               fMultilineCommentScanner = new SingleTokenPHPScanner(
+                               (JavaColorManager) colorManager, store,
+                               IPreferenceConstants.PHP_MULTILINE_COMMENT);
+               fSinglelineCommentScanner = new SingleTokenPHPScanner(
+                               (JavaColorManager) colorManager, store,
+                               IPreferenceConstants.PHP_SINGLELINE_COMMENT);
+               // fStringDQScanner = new SingleTokenPHPScanner((JavaColorManager)
+               // colorManager, store, IPreferenceConstants.PHP_STRING);
+               // fStringSQScanner = new SingleTokenPHPScanner((JavaColorManager)
+               // colorManager, store, IPreferenceConstants.PHP_STRING);
+
+               fPHPDocScanner = new PHPDocCodeScanner((JavaColorManager) colorManager,
+                               store);
+               // fHTMLScanner = new HTMLCodeScanner((JavaColorManager)fColorManager,
+               // store);
+               fSmartyScanner = new SmartyCodeScanner((JavaColorManager) colorManager,
+                               store);
+               fSmartyDocScanner = new SmartyDocCodeScanner(
+                               (JavaColorManager) colorManager, store);
+
+               fPartitionScanner = new FastJavaPartitionScanner();
+
+               // jspScriptScanner = new JSPScriptScanner();
+               // fPartitionScanner = new FastJavaPartitionScanner();
+               // fPartitionScanner = new PHPPartitionScanner();
+
+               // jspBracketScanner = new RuleBasedScanner();
+               // jspBracketScanner.setDefaultReturnToken(new
+               // Token(JSPScriptScanner.JSP_BRACKET));
+               // jspTextScanner = new RuleBasedScanner();
+               // jspTextScanner.setDefaultReturnToken(new
+               // Token(JSPScriptScanner.JSP_DEFAULT));
+       }
+
+       /**
+        * 
+        */
+       public XMLTextTools getXMLTextTools() {
+               return xmlTextTools;
+       }
+
+       /**
+        * Disposes all the individual tools of this tools collection.
+        */
+       public void dispose() {
+
+               fCodeScanner = null;
+               fMultilineCommentScanner = null;
+               fSinglelineCommentScanner = null;
+               // fStringDQScanner = null;
+               // fStringSQScanner = null;
+               fPHPDocScanner = null;
+               // fPartitionScanner = null;
+
+               if (colorManager != null) {
+                       colorManager.dispose();
+                       colorManager = null;
+               }
+
+               if (fPreferenceStore != null) {
+                       fPreferenceStore.removePropertyChangeListener(fPreferenceListener);
+                       fPreferenceStore = null;
+
+                       if (fCorePreferenceStore != null) {
+                               fCorePreferenceStore
+                                               .removePropertyChangeListener(fPreferenceListener);
+                               fCorePreferenceStore = null;
+                       }
+
+                       fPreferenceListener = null;
+               }
+       }
+
+       /**
+        * Returns the color manager which is used to manage any Java-specific
+        * colors needed for such things like syntax highlighting.
+        * 
+        * @return the color manager to be used for Java text viewers
+        */
+       public JavaColorManager getColorManager() {
+               return (JavaColorManager) colorManager;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan Java source code.
+        * 
+        * @return a Java source code scanner
+        */
+       public RuleBasedScanner getCodeScanner() {
+               return fCodeScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan Java multiline comments.
+        * 
+        * @return a Java multiline comment scanner
+        * 
+        * @since 2.0
+        */
+       public RuleBasedScanner getMultilineCommentScanner() {
+               return fMultilineCommentScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan HTML code.
+        * 
+        * @return a HTML scanner
+        * 
+        * @since 2.0
+        */
+       // public RuleBasedScanner getHTMLScanner() {
+       // return fHTMLScanner;
+       // }
+       /**
+        * Returns a scanner which is configured to scan Smarty code.
+        * 
+        * @return a Smarty scanner
+        * 
+        * @since 2.0
+        */
+       public RuleBasedScanner getSmartyScanner() {
+               return fSmartyScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan Smarty code.
+        * 
+        * @return a Smarty scanner
+        * 
+        * @since 2.0
+        */
+       public RuleBasedScanner getSmartyDocScanner() {
+               return fSmartyDocScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan Java singleline comments.
+        * 
+        * @return a Java singleline comment scanner
+        * 
+        * @since 2.0
+        */
+       public RuleBasedScanner getSinglelineCommentScanner() {
+               return fSinglelineCommentScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan Java strings.
+        * 
+        * @return a Java string scanner
+        * 
+        * @since 2.0
+        */
+       // public RuleBasedScanner getStringScanner() {
+       // return fStringDQScanner;
+       // }
+       /**
+        * Returns a scanner which is configured to scan JavaDoc compliant comments.
+        * Notes that the start sequence "/**" and the corresponding end sequence
+        * are part of the JavaDoc comment.
+        * 
+        * @return a JavaDoc scanner
+        */
+       public RuleBasedScanner getJavaDocScanner() {
+               return fPHPDocScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan Java-specific partitions,
+        * which are multi-line comments, JavaDoc comments, and regular Java source
+        * code.
+        * 
+        * @return a Java partition scanner
+        */
+       // public IPartitionTokenScanner getPartitionScanner() {
+       // return fPartitionScanner;
+       // }
+       /**
+        * Factory method for creating a PHP-specific document partitioner using
+        * this object's partitions scanner. This method is a convenience method.
+        * 
+        * @return a newly created Java document partitioner
+        */
+       public IDocumentPartitioner createDocumentPartitioner() {
+               return createDocumentPartitioner(".php");
+       }
+
+       /**
+        * Factory method for creating a PHP-specific document partitioner using
+        * this object's partitions scanner. This method is a convenience method.
+        * 
+        * @return a newly created Java document partitioner
+        */
+       public IDocumentPartitioner createDocumentPartitioner(String extension) {
+
+               // String[] types =
+               // new String[] {
+               // FastJavaPartitionScanner.JAVA_DOC,
+               // FastJavaPartitionScanner.JAVA_MULTI_LINE_COMMENT,
+               // FastJavaPartitionScanner.JAVA_SINGLE_LINE_COMMENT,
+               // FastJavaPartitionScanner.JAVA_STRING };
+               //
+               // return new DefaultPartitioner(getPartitionScanner(), types);
+               IDocumentPartitioner partitioner = null;
+               // System.out.println(extension);
+               if (extension.equalsIgnoreCase(".html")
+                               || extension.equalsIgnoreCase(".htm")) {
+                       // html
+                       partitioner = createHTMLPartitioner();
+                       partitioner = createJSPPartitioner();
+               } else if (extension.equalsIgnoreCase(".xml")) {
+                       // xml
+                       partitioner = createXMLPartitioner();
+                       // } else if (extension.equalsIgnoreCase(".js")) {
+                       // // javascript
+                       // partitioner = createJavaScriptPartitioner();
+                       // } else if (extension.equalsIgnoreCase(".css")) {
+                       // // cascading style sheets
+                       // partitioner = createCSSPartitioner();
+               } else if (extension.equalsIgnoreCase(".tpl")) {
+                       // smarty ?
+                       partitioner = createSmartyPartitioner();
+                       // } else if (extension.equalsIgnoreCase(".inc")) {
+                       // // php include files ?
+                       // partitioner = createIncludePartitioner();
+               }
+
+               if (partitioner == null) {
+                       partitioner = createJSPPartitioner();
+               }
+
+               return partitioner;
+       }
+
+       /**
+        * Sets up the Java document partitioner for the given document for the
+        * given partitioning.
+        * 
+        * @param document
+        *            the document to be set up
+        * @param partitioning
+        *            the document partitioning
+        * @param element
+        *            TODO
+        * 
+        * @since 3.0
+        */
+       // public void setupJavaDocumentPartitioner(IDocument document, String
+       // partitioning, Object element) {
+       // IDocumentPartitioner partitioner = createDocumentPartitioner(".php");
+       //
+       // // if (document instanceof IDocumentExtension3) {
+       // // IDocumentExtension3 extension3= (IDocumentExtension3) document;
+       // // extension3.setDocumentPartitioner(partitioning, partitioner);
+       // // } else {
+       // document.setDocumentPartitioner(partitioner);
+       // // }
+       // partitioner.connect(document);
+       // }
+       public void setupHTMLDocumentPartitioner(IDocument document,
+                       String partitioning, Object element) {
+               IDocumentPartitioner partitioner = createDocumentPartitioner(".html");
+
+               // if (document instanceof IDocumentExtension3) {
+               // IDocumentExtension3 extension3= (IDocumentExtension3) document;
+               // extension3.setDocumentPartitioner(partitioning, partitioner);
+               // } else {
+               document.setDocumentPartitioner(partitioner);
+               // }
+               partitioner.connect(document);
+       }
+
+       public void setupSmartyDocumentPartitioner(IDocument document,
+                       String partitioning, Object element) {
+               IDocumentPartitioner partitioner = createDocumentPartitioner(".tpl");
+
+               // if (document instanceof IDocumentExtension3) {
+               // IDocumentExtension3 extension3= (IDocumentExtension3) document;
+               // extension3.setDocumentPartitioner(partitioning, partitioner);
+               // } else {
+               document.setDocumentPartitioner(partitioner);
+               // }
+               partitioner.connect(document);
+       }
+
+       /**
+        * Returns the names of the document position categories used by the
+        * document partitioners created by this object to manage their partition
+        * information. If the partitioners don't use document position categories,
+        * the returned result is <code>null</code>.
+        * 
+        * @return the partition managing position categories or <code>null</code>
+        *         if there is none
+        */
+       public String[] getPartitionManagingPositionCategories() {
+               return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
+       }
+
+       /**
+        * Determines whether the preference change encoded by the given event
+        * changes the behavior of one its contained components.
+        * 
+        * @param event
+        *            the event to be investigated
+        * @return <code>true</code> if event causes a behavioral change
+        * @since 2.0
+        * @deprecated As of 3.0, replaced by
+        *             {@link net.sourceforge.phpdt.ui.text.JavaSourceViewerConfiguration#affectsTextPresentation(PropertyChangeEvent)}
+        */
+       // public boolean affectsBehavior(PropertyChangeEvent event) {
+       // return fCodeScanner.affectsBehavior(event)
+       // || fMultilineCommentScanner.affectsBehavior(event)
+       // || fSinglelineCommentScanner.affectsBehavior(event)
+       // || fStringDQScanner.affectsBehavior(event)
+       // || fPHPDocScanner.affectsBehavior(event);
+       // }
+       /**
+        * Adapts the behavior of the contained components to the change encoded in
+        * the given event.
+        * 
+        * @param event
+        *            the event to which to adapt
+        * @since 2.0
+        */
+       protected void adaptToPreferenceChange(PropertyChangeEvent event) {
+               if (fCodeScanner.affectsBehavior(event))
+                       fCodeScanner.adaptToPreferenceChange(event);
+               if (fMultilineCommentScanner.affectsBehavior(event))
+                       fMultilineCommentScanner.adaptToPreferenceChange(event);
+               if (fSinglelineCommentScanner.affectsBehavior(event))
+                       fSinglelineCommentScanner.adaptToPreferenceChange(event);
+               // if (fStringDQScanner.affectsBehavior(event))
+               // fStringDQScanner.adaptToPreferenceChange(event);
+               if (fPHPDocScanner.affectsBehavior(event))
+                       fPHPDocScanner.adaptToPreferenceChange(event);
+               // if (fHTMLScanner.affectsBehavior(event))
+               // fHTMLScanner.adaptToPreferenceChange(event);
+               if (fSmartyScanner.affectsBehavior(event))
+                       fSmartyScanner.adaptToPreferenceChange(event);
+               if (fSmartyDocScanner.affectsBehavior(event))
+                       fSmartyDocScanner.adaptToPreferenceChange(event);
+               // if (XMLPlugin.getDefault().getXMLTextTools().affectsBehavior(event))
+               // {
+               // XMLPlugin.getDefault().getXMLTextTools().adaptToPreferenceChange(event);
+               // }
+       }
+
+       /**
+        * Return a partitioner for .html files.
+        */
+       public IDocumentPartitioner createHTMLPartitioner() {
+               // return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
+               return xmlTextTools.createXMLPartitioner();
+       }
+
+       // private static IDocumentPartitioner createIncludePartitioner() {
+       // // return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+       // return new DefaultPartitioner(getPHPPartitionScanner(),
+       // FastJavaPartitionScanner.PHP_PARTITION_TYPES);
+       //
+       // }
+
+       // private static IDocumentPartitioner createJavaScriptPartitioner() {
+       // return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
+       // }
+
+       /**
+        * Return a partitioner for .php files.
+        */
+       public IDocumentPartitioner createPHPPartitioner() {
+               // return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+               return new DefaultPartitioner(getPHPPartitionScanner(),
+                               LEGAL_CONTENT_TYPES);
+       }
+
+       private IDocumentPartitioner createJSPPartitioner() {
+               return new PHPDocumentPartitioner(getJSPPartitionScanner());
+               // return new JSPDocumentPartitioner(getJSPPartitionScanner(),
+               // jspScriptScanner);
+       }
+
+       /**
+        * 
+        */
+       // public IPartitionTokenScanner getJSPScriptScanner() {
+       // return jspScriptScanner;
+       // }
+       private IDocumentPartitioner createSmartyPartitioner() {
+               return new DefaultPartitioner(getSmartyPartitionScanner(),
+                               XMLTextTools.TYPES);
+       }
+
+       private IDocumentPartitioner createXMLPartitioner() {
+               // return new DefaultPartitioner(getXMLPartitionScanner(),
+               // XMLTextTools.TYPES);
+               return xmlTextTools.createXMLPartitioner();
+       }
+
+       // private IDocumentPartitioner createCSSPartitioner() {
+       // return new DefaultPartitioner(getHTMLPartitionScanner(),
+       // XMLTextTools.TYPES);
+       // }
+
+       /**
+        * Return a scanner for creating html partitions.
+        */
+       // private static XMLPartitionScanner getHTMLPartitionScanner() {
+       // // if (HTML_PARTITION_SCANNER == null)
+       // // HTML_PARTITION_SCANNER = new
+       // HTMLPartitionScanner(IPHPPartitions.HTML_FILE);
+       // // return HTML_PARTITION_SCANNER;^
+       // if (HTML_PARTITION_SCANNER == null)
+       // HTML_PARTITION_SCANNER = new XMLPartitionScanner(false);
+       // return HTML_PARTITION_SCANNER;
+       // }
+       /**
+        * Return a scanner for creating php partitions.
+        */
+       private FastJavaPartitionScanner getPHPPartitionScanner() {
+               // if (PHP_PARTITION_SCANNER == null)
+               // PHP_PARTITION_SCANNER = new FastJavaPartitionScanner(); //new
+               // PHPPartitionScanner(IPHPPartitions.PHP_FILE);
+               // return PHP_PARTITION_SCANNER;
+               return fPartitionScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan plain text in JSP.
+        * 
+        * @return a JSP text scanner
+        */
+       // public RuleBasedScanner getJSPTextScanner() {
+       // return jspTextScanner;
+       // }
+       /**
+        * Returns a scanner which is configured to scan plain text in JSP.
+        * 
+        * @return a JSP text scanner
+        */
+       // public RuleBasedScanner getJSPBracketScanner() {
+       // return jspBracketScanner;
+       // }
+       /**
+        * Return a scanner for creating smarty partitions.
+        */
+       private static HTMLPartitionScanner getSmartyPartitionScanner() {
+               if (SMARTY_PARTITION_SCANNER == null)
+                       SMARTY_PARTITION_SCANNER = new HTMLPartitionScanner(
+                                       IPHPPartitions.SMARTY_FILE);
+               return SMARTY_PARTITION_SCANNER;
+       }
+
+       /**
+        * Return a scanner for creating xml partitions.
+        */
+       // private static XMLPartitionScanner getXMLPartitionScanner() {
+       // // if (XML_PARTITION_SCANNER == null)
+       // // XML_PARTITION_SCANNER = new
+       // HTMLPartitionScanner(IPHPPartitions.XML_FILE);
+       // // return XML_PARTITION_SCANNER;
+       // if (XML_PARTITION_SCANNER == null)
+       // XML_PARTITION_SCANNER = new XMLPartitionScanner(false);
+       // return XML_PARTITION_SCANNER;
+       // }
+       private PHPPartitionScanner getJSPPartitionScanner() {
+               if (jspPartitionScanner == null)
+                       jspPartitionScanner = new PHPPartitionScanner();
+               return jspPartitionScanner;
+       }
+
+       /**
+        * Sets up the Java document partitioner for the given document for the
+        * default partitioning.
+        * 
+        * @param document
+        *            the document to be set up
+        * @since 3.0
+        */
+       public void setupJavaDocumentPartitioner(IDocument document) {
+               setupJavaDocumentPartitioner(document,
+                               IDocumentExtension3.DEFAULT_PARTITIONING);
+       }
+
+       /**
+        * Sets up the Java document partitioner for the given document for the
+        * given partitioning.
+        * 
+        * @param document
+        *            the document to be set up
+        * @param partitioning
+        *            the document partitioning
+        * @since 3.0
+        */
+       public void setupJavaDocumentPartitioner(IDocument document,
+                       String partitioning) {
+               IDocumentPartitioner partitioner = createDocumentPartitioner();
+               if (document instanceof IDocumentExtension3) {
+                       IDocumentExtension3 extension3 = (IDocumentExtension3) document;
+                       extension3.setDocumentPartitioner(partitioning, partitioner);
+               } else {
+                       document.setDocumentPartitioner(partitioner);
+               }
+               partitioner.connect(document);
+       }
+
+       /**
+        * Returns this text tool's preference store.
+        * 
+        * @return the preference store
+        * @since 3.0
+        */
+       protected IPreferenceStore getPreferenceStore() {
+               return fPreferenceStore;
+       }
+
+       /**
+        * Returns this text tool's core preference store.
+        * 
+        * @return the core preference store
+        * @since 3.0
+        */
+       protected Preferences getCorePreferenceStore() {
+               return fCorePreferenceStore;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java
new file mode 100644 (file)
index 0000000..3cba77d
--- /dev/null
@@ -0,0 +1,1146 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpdt.ui.text;
+
+import java.util.Vector;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
+import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaAnnotationHover;
+import net.sourceforge.phpdt.internal.ui.text.JavaCompositeReconcilingStrategy;
+import net.sourceforge.phpdt.internal.ui.text.JavaElementProvider;
+import net.sourceforge.phpdt.internal.ui.text.JavaOutlineInformationControl;
+import net.sourceforge.phpdt.internal.ui.text.JavaPresentationReconciler;
+import net.sourceforge.phpdt.internal.ui.text.JavaReconciler;
+import net.sourceforge.phpdt.internal.ui.text.java.JavaFormattingStrategy;
+import net.sourceforge.phpdt.internal.ui.text.java.JavaStringAutoIndentStrategyDQ;
+import net.sourceforge.phpdt.internal.ui.text.java.JavaStringAutoIndentStrategySQ;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaInformationProvider;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.JavaDocAutoIndentStrategy;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+//import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.php.HTMLCompletionProcessor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPAutoIndentStrategy;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPCompletionProcessor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDoubleClickSelector;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner;
+import net.sourceforge.phpeclipse.ui.WebUI;
+//import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.formatter.ContentFormatter;
+import org.eclipse.jface.text.formatter.IContentFormatter;
+import org.eclipse.jface.text.formatter.IFormattingStrategy;
+import org.eclipse.jface.text.information.IInformationPresenter;
+import org.eclipse.jface.text.information.IInformationProvider;
+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.reconciler.IReconciler;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Configuration for an <code>SourceViewer</code> which shows PHP code.
+ */
+public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
+       /**
+        * Preference key used to look up display tab width.
+        * 
+        * @since 2.0
+        */
+       public final static String PREFERENCE_TAB_WIDTH = PreferenceConstants.EDITOR_TAB_WIDTH;
+
+       /**
+        * Preference key for inserting spaces rather than tabs.
+        * 
+        * @since 2.0
+        */
+       public final static String SPACES_FOR_TABS = PreferenceConstants.EDITOR_SPACES_FOR_TABS;
+
+       // public static final String HTML_DEFAULT =
+       // IPHPPartitionScannerConstants.HTML;
+       // IDocument.DEFAULT_CONTENT_TYPE;
+       // private JavaTextTools fJavaTextTools;
+
+       private ITextEditor fTextEditor;
+
+       /**
+        * The document partitioning.
+        * 
+        * @since 3.0
+        */
+       private String fDocumentPartitioning;
+
+       private ContentFormatter fFormatter;
+
+       /**
+        * Single token scanner.
+        */
+       static class SingleTokenScanner extends BufferedRuleBasedScanner {
+               public SingleTokenScanner(TextAttribute attribute) {
+                       setDefaultReturnToken(new Token(attribute));
+               }
+       };
+
+       /**
+        * The document partitioning.
+        * 
+        * @since 3.0
+        */
+       // private String fDocumentPartitioning;
+       /**
+        * The Java source code scanner
+        * 
+        * @since 3.0
+        */
+       private AbstractJavaScanner fCodeScanner;
+
+       /**
+        * The Java multi-line comment scanner
+        * 
+        * @since 3.0
+        */
+       private AbstractJavaScanner fMultilineCommentScanner;
+
+       /**
+        * The Java single-line comment scanner
+        * 
+        * @since 3.0
+        */
+       private AbstractJavaScanner fSinglelineCommentScanner;
+
+       /**
+        * The PHP double quoted string scanner
+        */
+       private AbstractJavaScanner fStringDQScanner;
+
+       /**
+        * The PHP single quoted string scanner
+        */
+       private AbstractJavaScanner fStringSQScanner;
+
+       /**
+        * The Javadoc scanner
+        * 
+        * @since 3.0
+        */
+       private AbstractJavaScanner fJavaDocScanner;
+
+       /**
+        * The preference store, can be read-only
+        * 
+        * @since 3.0
+        */
+       private IPreferenceStore fPreferenceStore;
+
+       /**
+        * The color manager
+        * 
+        * @since 3.0
+        */
+       private IColorManager fColorManager;
+
+       private XMLTextTools fXMLTextTools;
+
+       private XMLConfiguration xmlConfiguration;
+
+       /**
+        * Creates a new Java source viewer configuration for viewers in the given
+        * editor using the given preference store, the color manager and the
+        * specified document partitioning.
+        * <p>
+        * Creates a Java source viewer configuration in the new setup without text
+        * tools. Clients are allowed to call
+        * {@link JavaSourceViewerConfiguration#handlePropertyChangeEvent(PropertyChangeEvent)}and
+        * disallowed to call
+        * {@link JavaSourceViewerConfiguration#getPreferenceStore()}on the
+        * resulting Java source viewer configuration.
+        * </p>
+        * 
+        * @param colorManager
+        *            the color manager
+        * @param preferenceStore
+        *            the preference store, can be read-only
+        * @param editor
+        *            the editor in which the configured viewer(s) will reside
+        * @param partitioning
+        *            the document partitioning for this configuration
+        * @since 3.0
+        */
+       public PHPSourceViewerConfiguration(IColorManager colorManager,
+                       IPreferenceStore preferenceStore, ITextEditor editor,
+                       String partitioning) {
+               fColorManager = colorManager;
+               fPreferenceStore = preferenceStore;
+               fTextEditor = editor;
+               fDocumentPartitioning = partitioning;
+               // fJavaTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
+               fXMLTextTools = new XMLTextTools(getPreferenceStore());
+               //XMLPlugin.getDefault().getXMLTextTools();
+               xmlConfiguration = new XMLConfiguration(fXMLTextTools);
+               fColorManager = colorManager;
+               fPreferenceStore = preferenceStore;
+               fTextEditor = editor;
+               fDocumentPartitioning = partitioning;
+
+               initializeScanners();
+       }
+
+       /**
+        * Creates a new Java source viewer configuration for viewers in the given
+        * editor using the given Java tools.
+        * 
+        * @param tools
+        *            the Java text tools to be used
+        * @param editor
+        *            the editor in which the configured viewer(s) will reside
+        * @see JavaTextTools
+        * @deprecated As of 3.0, replaced by
+        *             {@link JavaSourceViewerConfiguration#JavaSourceViewerConfiguration(IColorManager, IPreferenceStore, ITextEditor, String)}
+        */
+       // public PHPSourceViewerConfiguration(JavaTextTools tools, PHPEditor
+       // editor, String partitioning) {
+       // fJavaTextTools = tools;
+       // fColorManager = tools.getColorManager();
+       // fPreferenceStore = createPreferenceStore();
+       // fDocumentPartitioning = partitioning;
+       // fCodeScanner = (AbstractJavaScanner) fJavaTextTools.getCodeScanner();
+       // fMultilineCommentScanner = (AbstractJavaScanner)
+       // fJavaTextTools.getMultilineCommentScanner();
+       // fSinglelineCommentScanner = (AbstractJavaScanner)
+       // fJavaTextTools.getSinglelineCommentScanner();
+       // fStringDQScanner = (AbstractJavaScanner)
+       // fJavaTextTools.getStringScanner();
+       // fJavaDocScanner = (AbstractJavaScanner)
+       // fJavaTextTools.getJavaDocScanner();
+       // fTextEditor = editor;
+       // fXMLTextTools = XMLPlugin.getDefault().getXMLTextTools();
+       // xmlConfiguration = new XMLConfiguration(fXMLTextTools);
+       // }
+       /**
+        * Returns the color manager for this configuration.
+        * 
+        * @return the color manager
+        */
+       protected IColorManager getColorManager() {
+               return fColorManager;
+       }
+
+       /**
+        * Initializes the scanners.
+        * 
+        * @since 3.0
+        */
+       private void initializeScanners() {
+               // Assert.isTrue(isNewSetup());
+               fCodeScanner = new PHPCodeScanner(getColorManager(), fPreferenceStore);
+               fMultilineCommentScanner = new SingleTokenPHPScanner(getColorManager(),
+                               fPreferenceStore, IPreferenceConstants.PHP_MULTILINE_COMMENT);
+               fSinglelineCommentScanner = new SingleTokenPHPScanner(
+                               getColorManager(), fPreferenceStore,
+                               IPreferenceConstants.PHP_SINGLELINE_COMMENT);
+               // fStringDQScanner = new SingleTokenPHPScanner(getColorManager(),
+               // fPreferenceStore, IPreferenceConstants.PHP_STRING_DQ);
+               fStringDQScanner = new PHPStringDQCodeScanner(getColorManager(),
+                               fPreferenceStore);
+               fStringSQScanner = new SingleTokenPHPScanner(getColorManager(),
+                               fPreferenceStore, IPreferenceConstants.PHP_STRING_SQ);
+               fJavaDocScanner = new PHPDocCodeScanner(getColorManager(),
+                               fPreferenceStore);
+       }
+
+       /**
+        * Determines whether the preference change encoded by the given event
+        * changes the behavior of one of its contained components.
+        * 
+        * @param event
+        *            the event to be investigated
+        * @return <code>true</code> if event causes a behavioral change
+        * @since 3.0
+        */
+       public boolean affectsTextPresentation(PropertyChangeEvent event) {
+               return fCodeScanner.affectsBehavior(event)
+                               || fMultilineCommentScanner.affectsBehavior(event)
+                               || fSinglelineCommentScanner.affectsBehavior(event)
+                               || fStringDQScanner.affectsBehavior(event)
+                               || fStringSQScanner.affectsBehavior(event)
+                               || fJavaDocScanner.affectsBehavior(event);
+       }
+
+       /**
+        * Adapts the behavior of the contained components to the change encoded in
+        * the given event.
+        * <p>
+        * Clients are not allowed to call this method if the old setup with text
+        * tools is in use.
+        * </p>
+        * 
+        * @param event
+        *            the event to which to adapt
+        * @see JavaSourceViewerConfiguration#JavaSourceViewerConfiguration(IColorManager,
+        *      IPreferenceStore, ITextEditor, String)
+        * @since 3.0
+        */
+       public void handlePropertyChangeEvent(PropertyChangeEvent event) {
+               // Assert.isTrue(isNewSetup());
+               if (fCodeScanner.affectsBehavior(event))
+                       fCodeScanner.adaptToPreferenceChange(event);
+               if (fMultilineCommentScanner.affectsBehavior(event))
+                       fMultilineCommentScanner.adaptToPreferenceChange(event);
+               if (fSinglelineCommentScanner.affectsBehavior(event))
+                       fSinglelineCommentScanner.adaptToPreferenceChange(event);
+               if (fStringDQScanner.affectsBehavior(event))
+                       fStringDQScanner.adaptToPreferenceChange(event);
+               if (fStringSQScanner.affectsBehavior(event))
+                       fStringSQScanner.adaptToPreferenceChange(event);
+               if (fJavaDocScanner.affectsBehavior(event))
+                       fJavaDocScanner.adaptToPreferenceChange(event);
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getContentFormatter(ISourceViewer)
+        */
+       public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
+               // if (fFormatter == null) {
+               // fFormatter = new ContentFormatter();
+               // fFormattingStrategy = new HTMLFormattingStrategy(this,
+               // sourceViewer);
+               // fFormatter.setFormattingStrategy(fFormattingStrategy, HTML_DEFAULT);
+               // fFormatter.enablePartitionAwareFormatting(false);
+               // fFormatter.setPartitionManagingPositionCategories(getConfiguredContentTypes(null));
+               // }
+               // return fFormatter;
+               if (fFormatter == null) {
+                       // ContentFormatter
+                       fFormatter = new ContentFormatter();
+                       IFormattingStrategy strategy = new JavaFormattingStrategy(
+                                       sourceViewer);
+                       fFormatter.setFormattingStrategy(strategy,
+                                       IDocument.DEFAULT_CONTENT_TYPE);
+                       fFormatter.enablePartitionAwareFormatting(false);
+                       fFormatter
+                                       .setPartitionManagingPositionCategories(getPartitionManagingPositionCategories());
+               }
+               return fFormatter;
+       }
+
+       /**
+        * Returns the names of the document position categories used by the
+        * document partitioners created by this object to manage their partition
+        * information. If the partitioners don't use document position categories,
+        * the returned result is <code>null</code>.
+        * 
+        * @return the partition managing position categories or <code>null</code>
+        *         if there is none
+        */
+       public String[] getPartitionManagingPositionCategories() {
+               return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
+       }
+
+       // /**
+       // * Returns the names of the document position categories used by the
+       // document
+       // * partitioners created by this object to manage their partition
+       // information.
+       // * If the partitioners don't use document position categories, the
+       // returned
+       // * result is <code>null</code>.
+       // *
+       // * @return the partition managing position categories or
+       // <code>null</code>
+       // * if there is none
+       // */
+       // private String[] getPartitionManagingPositionCategories() {
+       // return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
+       // }
+       public ITextEditor getEditor() {
+               return fTextEditor;
+       }
+
+       /**
+        * Returns the preference store used by this configuration to initialize the
+        * individual bits and pieces.
+        * 
+        * @return the preference store used to initialize this configuration
+        * 
+        * @since 2.0
+        */
+       protected IPreferenceStore getPreferenceStore() {
+               return WebUI.getDefault().getPreferenceStore();
+       }
+
+       // /* (non-Javadoc)
+       // * Method declared on SourceViewerConfiguration
+       // */
+       // public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+       // return new PHPAnnotationHover();
+       // }
+       /*
+        * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
+        */
+       public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+               return new JavaAnnotationHover(JavaAnnotationHover.VERTICAL_RULER_HOVER);
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getOverviewRulerAnnotationHover(ISourceViewer)
+        * @since 3.0
+        */
+       public IAnnotationHover getOverviewRulerAnnotationHover(
+                       ISourceViewer sourceViewer) {
+               return new JavaAnnotationHover(JavaAnnotationHover.OVERVIEW_RULER_HOVER);
+       }
+
+       public IAutoEditStrategy[] getAutoEditStrategies(
+                       ISourceViewer sourceViewer, String contentType) {
+               IAutoEditStrategy strategy = new DefaultIndentLineAutoEditStrategy();
+               if (IPHPPartitions.PHP_PHPDOC_COMMENT.equals(contentType)
+                               || IPHPPartitions.PHP_MULTILINE_COMMENT.equals(contentType))
+                       strategy = new JavaDocAutoIndentStrategy(
+                                       getConfiguredDocumentPartitioning(sourceViewer));
+               else if (IPHPPartitions.PHP_STRING_DQ.equals(contentType))
+                       strategy = new JavaStringAutoIndentStrategyDQ(
+                                       getConfiguredDocumentPartitioning(sourceViewer));
+               else if (IPHPPartitions.PHP_STRING_SQ.equals(contentType))
+                       strategy = new JavaStringAutoIndentStrategySQ(
+                                       getConfiguredDocumentPartitioning(sourceViewer));
+               else
+                       strategy = (PHPDocumentPartitioner.PHP_TEMPLATE_DATA
+                                       .equals(contentType)
+                                       || PHPDocumentPartitioner.PHP_SCRIPT_CODE
+                                                       .equals(contentType)
+                                       || IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)
+                                       || IPHPPartitions.PHP_PARTITIONING.equals(contentType)
+                                       || PHPPartitionScanner.PHP_SCRIPTING_AREA
+                                                       .equals(contentType) ? new PHPAutoIndentStrategy()
+                                       : new DefaultIndentLineAutoEditStrategy());
+               IAutoEditStrategy[] result = new IAutoEditStrategy[1];
+               result[0] = strategy;
+               return result;
+       }
+
+       /**
+        * Returns the PHP source code scanner for this configuration.
+        * 
+        * @return the PHP source code scanner
+        */
+       protected RuleBasedScanner getCodeScanner() {
+               return fCodeScanner; // fJavaTextTools.getCodeScanner();
+       }
+
+       /**
+        * Returns the Java multi-line comment scanner for this configuration.
+        * 
+        * @return the Java multi-line comment scanner
+        * @since 2.0
+        */
+       protected RuleBasedScanner getMultilineCommentScanner() {
+               return fMultilineCommentScanner;
+       }
+
+       /**
+        * Returns the Java single-line comment scanner for this configuration.
+        * 
+        * @return the Java single-line comment scanner
+        * @since 2.0
+        */
+       protected RuleBasedScanner getSinglelineCommentScanner() {
+               return fSinglelineCommentScanner;
+       }
+
+       /**
+        * Returns the PHP double quoted string scanner for this configuration.
+        * 
+        * @return the PHP double quoted string scanner
+        */
+       protected RuleBasedScanner getStringDQScanner() {
+               return fStringDQScanner;
+       }
+
+       /**
+        * Returns the PHP single quoted string scanner for this configuration.
+        * 
+        * @return the PHP single quoted string scanner
+        */
+       protected RuleBasedScanner getStringSQScanner() {
+               return fStringSQScanner;
+       }
+
+       /**
+        * Returns the HTML source code scanner for this configuration.
+        * 
+        * @return the HTML source code scanner
+        */
+       // protected RuleBasedScanner getHTMLScanner() {
+       // return fJavaTextTools.getHTMLScanner();
+       // }
+       /**
+        * Returns the Smarty source code scanner for this configuration.
+        * 
+        * @return the Smarty source code scanner
+        */
+       // protected RuleBasedScanner getSmartyScanner() {
+       // return fJavaTextTools.getSmartyScanner();
+       // }
+       /*
+        * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
+        */
+       /*
+        * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
+        */
+       public IReconciler getReconciler(ISourceViewer sourceViewer) {
+
+               final ITextEditor editor = getEditor();
+               if (editor != null && editor.isEditable()) {
+
+                       JavaCompositeReconcilingStrategy strategy = new JavaCompositeReconcilingStrategy(
+                                       editor, getConfiguredDocumentPartitioning(sourceViewer));
+                       JavaReconciler reconciler = new JavaReconciler(editor, strategy,
+                                       false);
+                       reconciler.setIsIncrementalReconciler(false);
+                       reconciler.setProgressMonitor(new NullProgressMonitor());
+                       reconciler.setDelay(500);
+
+                       return reconciler;
+               }
+               return null;
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer,
+        *      String)
+        * @since 2.1
+        */
+       public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer,
+                       String contentType) {
+               JavaEditorTextHoverDescriptor[] hoverDescs = WebUI
+                               .getDefault().getJavaEditorTextHoverDescriptors();
+               int stateMasks[] = new int[hoverDescs.length];
+               int stateMasksLength = 0;
+               for (int i = 0; i < hoverDescs.length; i++) {
+                       if (hoverDescs[i].isEnabled()) {
+                               int j = 0;
+                               int stateMask = hoverDescs[i].getStateMask();
+                               while (j < stateMasksLength) {
+                                       if (stateMasks[j] == stateMask)
+                                               break;
+                                       j++;
+                               }
+                               if (j == stateMasksLength)
+                                       stateMasks[stateMasksLength++] = stateMask;
+                       }
+               }
+               if (stateMasksLength == hoverDescs.length)
+                       return stateMasks;
+               int[] shortenedStateMasks = new int[stateMasksLength];
+               System.arraycopy(stateMasks, 0, shortenedStateMasks, 0,
+                               stateMasksLength);
+               return shortenedStateMasks;
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String, int)
+        * @since 2.1
+        */
+       public ITextHover getTextHover(ISourceViewer sourceViewer,
+                       String contentType, int stateMask) {
+               JavaEditorTextHoverDescriptor[] hoverDescs = WebUI
+                               .getDefault().getJavaEditorTextHoverDescriptors();
+               int i = 0;
+               while (i < hoverDescs.length) {
+                       if (hoverDescs[i].isEnabled()
+                                       && hoverDescs[i].getStateMask() == stateMask)
+                               return new JavaEditorTextHoverProxy(hoverDescs[i], getEditor());
+                       i++;
+               }
+               return null;
+               // if (fEditor != null) {
+               // IEditorInput editorInput = fEditor.getEditorInput();
+               // if (editorInput instanceof IFileEditorInput) {
+               // try {
+               // IFile f = ((IFileEditorInput) editorInput).getFile();
+               // return new PHPTextHover(f.getProject());
+               // } catch (NullPointerException e) {
+               // // this exception occurs, if getTextHover is called by
+               // // preference pages !
+               // }
+               // }
+               // }
+               // return new PHPTextHover(null);
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
+        */
+       public ITextHover getTextHover(ISourceViewer sourceViewer,
+                       String contentType) {
+               return getTextHover(sourceViewer, contentType,
+                               ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+       }
+
+       /**
+        * Returns the SmartyDoc source code scanner for this configuration.
+        * 
+        * @return the SmartyDoc source code scanner
+        */
+       // protected RuleBasedScanner getSmartyDocScanner() {
+       // return fJavaTextTools.getSmartyDocScanner();
+       // }
+       /**
+        * Returns the PHPDoc source code scanner for this configuration.
+        * 
+        * @return the PHPDoc source code scanner
+        */
+       protected RuleBasedScanner getPHPDocScanner() {
+               return fJavaDocScanner; // fJavaTextTools.getJavaDocScanner();
+       }
+
+       /*
+        * (non-Javadoc) Method declared on SourceViewerConfiguration
+        */
+       public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+               return new String[] { IDocument.DEFAULT_CONTENT_TYPE,
+                               PHPPartitionScanner.PHP_SCRIPTING_AREA,
+
+                               IPHPPartitions.HTML, IPHPPartitions.HTML_MULTILINE_COMMENT,
+                               IPHPPartitions.PHP_PARTITIONING,
+                               IPHPPartitions.PHP_SINGLELINE_COMMENT,
+                               IPHPPartitions.PHP_MULTILINE_COMMENT,
+                               IPHPPartitions.PHP_PHPDOC_COMMENT,
+                               IPHPPartitions.PHP_STRING_DQ, IPHPPartitions.PHP_STRING_SQ,
+                               IPHPPartitions.PHP_STRING_HEREDOC, IPHPPartitions.CSS,
+                               IPHPPartitions.CSS_MULTILINE_COMMENT,
+                               IPHPPartitions.JAVASCRIPT, IPHPPartitions.JS_MULTILINE_COMMENT,
+                               IPHPPartitions.SMARTY, IPHPPartitions.SMARTY_MULTILINE_COMMENT,
+
+                               XMLPartitionScanner.XML_PI, XMLPartitionScanner.XML_COMMENT,
+                               XMLPartitionScanner.XML_DECL, XMLPartitionScanner.XML_TAG,
+                               XMLPartitionScanner.XML_ATTRIBUTE,
+                               XMLPartitionScanner.XML_CDATA,
+
+                               XMLPartitionScanner.DTD_INTERNAL,
+                               XMLPartitionScanner.DTD_INTERNAL_PI,
+                               XMLPartitionScanner.DTD_INTERNAL_COMMENT,
+                               XMLPartitionScanner.DTD_INTERNAL_DECL,
+
+                               PHPDocumentPartitioner.PHP_TEMPLATE_DATA,
+                               PHPDocumentPartitioner.PHP_SCRIPT_CODE };
+       }
+
+       public String[] getConfiguredHTMLContentTypes() {
+               return new String[] { XMLPartitionScanner.XML_PI,
+                               XMLPartitionScanner.XML_COMMENT, XMLPartitionScanner.XML_DECL,
+                               XMLPartitionScanner.XML_TAG, XMLPartitionScanner.XML_ATTRIBUTE,
+                               XMLPartitionScanner.XML_CDATA,
+
+                               XMLPartitionScanner.DTD_INTERNAL,
+                               XMLPartitionScanner.DTD_INTERNAL_PI,
+                               XMLPartitionScanner.DTD_INTERNAL_COMMENT,
+                               XMLPartitionScanner.DTD_INTERNAL_DECL, };
+       }
+
+       public String[] getConfiguredPHPContentTypes() {
+               return new String[] { IDocument.DEFAULT_CONTENT_TYPE,
+                               IPHPPartitions.PHP_PARTITIONING,
+                               IPHPPartitions.PHP_SINGLELINE_COMMENT,
+                               IPHPPartitions.PHP_MULTILINE_COMMENT,
+                               IPHPPartitions.PHP_PHPDOC_COMMENT,
+                               IPHPPartitions.PHP_STRING_DQ, IPHPPartitions.PHP_STRING_SQ,
+                               IPHPPartitions.PHP_STRING_HEREDOC, IPHPPartitions.CSS,
+                               IPHPPartitions.CSS_MULTILINE_COMMENT,
+                               IPHPPartitions.JAVASCRIPT, IPHPPartitions.JS_MULTILINE_COMMENT,
+                               IPHPPartitions.SMARTY, IPHPPartitions.SMARTY_MULTILINE_COMMENT, };
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredDocumentPartitioning(org.eclipse.jface.text.source.ISourceViewer)
+        * @since 3.0
+        */
+       public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+               if (fDocumentPartitioning != null)
+                       return fDocumentPartitioning;
+               return super.getConfiguredDocumentPartitioning(sourceViewer);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on SourceViewerConfiguration
+        */
+       public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+               ContentAssistant assistant = new ContentAssistant();
+               IContentAssistProcessor processor = new HTMLCompletionProcessor(
+                               getEditor());
+               assistant
+                               .setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+               assistant.setContentAssistProcessor(processor, IPHPPartitions.HTML);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.HTML_MULTILINE_COMMENT);
+
+               assistant.setContentAssistProcessor(processor, IPHPPartitions.CSS);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.CSS_MULTILINE_COMMENT);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.JAVASCRIPT);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.JS_MULTILINE_COMMENT);
+               // TODO define special smarty partition content assist
+               assistant.setContentAssistProcessor(processor, IPHPPartitions.SMARTY);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+
+               assistant.setContentAssistProcessor(processor,
+                               PHPDocumentPartitioner.PHP_TEMPLATE_DATA);
+               String[] htmlTypes = getConfiguredHTMLContentTypes();
+               for (int i = 0; i < htmlTypes.length; i++) {
+                       assistant.setContentAssistProcessor(processor, htmlTypes[i]);
+               }
+               processor = new PHPCompletionProcessor(getEditor());
+
+               assistant.setContentAssistProcessor(processor,
+                               PHPDocumentPartitioner.PHP_SCRIPT_CODE);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.PHP_PARTITIONING);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.PHP_STRING_DQ);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.PHP_STRING_SQ);
+               assistant.setContentAssistProcessor(processor,
+                               IPHPPartitions.PHP_STRING_HEREDOC);
+
+               assistant.setContentAssistProcessor(new PHPDocCompletionProcessor(
+                               getEditor()), IPHPPartitions.PHP_PHPDOC_COMMENT);
+               // assistant.enableAutoActivation(true);
+               // assistant.setAutoActivationDelay(500);
+               // assistant.setProposalPopupOrientation(ContentAssistant.PROPOSAL_OVERLAY);
+               // ContentAssistPreference.configure(assistant, getPreferenceStore());
+               // assistant.setContextInformationPopupOrientation(
+               // ContentAssistant.CONTEXT_INFO_ABOVE);
+               // assistant.setContextInformationPopupBackground(
+               // PHPEditorEnvironment.getPHPColorProvider().getColor(
+               // new RGB(150, 150, 0)));
+               ContentAssistPreference.configure(assistant, getPreferenceStore());
+               assistant
+                               .setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_ABOVE);
+               assistant
+                               .setInformationControlCreator(getInformationControlCreator(sourceViewer));
+               return assistant;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on SourceViewerConfiguration
+        */
+       // public String getDefaultPrefix(ISourceViewer sourceViewer, String
+       // contentType) {
+       // return (PHPPartitionScanner.PHP.equals(contentType) ? "//" : null);
+       // //$NON-NLS-1$
+       // // return (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) ? "//" :
+       // null); //$NON-NLS-1$
+       // }
+       /*
+        * @see SourceViewerConfiguration#getDefaultPrefix(ISourceViewer, String)
+        * @since 2.0
+        */
+       public String[] getDefaultPrefixes(ISourceViewer sourceViewer,
+                       String contentType) {
+               return new String[] { "//", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+       }
+
+       /*
+        * (non-Javadoc) Method declared on SourceViewerConfiguration
+        */
+       public ITextDoubleClickStrategy getDoubleClickStrategy(
+                       ISourceViewer sourceViewer, String contentType) {
+               return new PHPDoubleClickSelector();
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String)
+        */
+       public String[] getIndentPrefixes(ISourceViewer sourceViewer,
+                       String contentType) {
+               Vector vector = new Vector();
+               // prefix[0] is either '\t' or ' ' x tabWidth, depending on useSpaces
+               final IPreferenceStore preferences = WebUI.getDefault()
+                               .getPreferenceStore();
+               int tabWidth = preferences.getInt(JavaCore.FORMATTER_TAB_SIZE);
+               boolean useSpaces = getPreferenceStore().getBoolean(SPACES_FOR_TABS);
+               for (int i = 0; i <= tabWidth; i++) {
+                       StringBuffer prefix = new StringBuffer();
+                       if (useSpaces) {
+                               for (int j = 0; j + i < tabWidth; j++)
+                                       prefix.append(' ');
+                               if (i != 0)
+                                       prefix.append('\t');
+                       } else {
+                               for (int j = 0; j < i; j++)
+                                       prefix.append(' ');
+                               if (i != tabWidth)
+                                       prefix.append('\t');
+                       }
+                       vector.add(prefix.toString());
+               }
+               vector.add(""); //$NON-NLS-1$
+               return (String[]) vector.toArray(new String[vector.size()]);
+       }
+
+       /**
+        * @return <code>true</code> iff the new setup without text tools is in
+        *         use.
+        * 
+        * @since 3.0
+        */
+       // private boolean isNewSetup() {
+       // return fJavaTextTools == null;
+       // }
+       /**
+        * Creates and returns a preference store which combines the preference
+        * stores from the text tools and which is read-only.
+        * 
+        * @return the read-only preference store
+        * @since 3.0
+        */
+       // private IPreferenceStore createPreferenceStore() {
+       // Assert.isTrue(!isNewSetup());
+       // IPreferenceStore generalTextStore = EditorsUI.getPreferenceStore();
+       // if (fJavaTextTools.getCorePreferenceStore() == null)
+       // return new ChainedPreferenceStore(new IPreferenceStore[] {
+       // fJavaTextTools.getPreferenceStore(), generalTextStore });
+       //
+       // return new ChainedPreferenceStore(new IPreferenceStore[] {
+       // fJavaTextTools.getPreferenceStore(),
+       // new PreferencesAdapter(fJavaTextTools.getCorePreferenceStore()),
+       // generalTextStore });
+       // }
+       /*
+        * (non-Javadoc) Method declared on SourceViewerConfiguration
+        */
+       public IPresentationReconciler getPresentationReconciler(
+                       ISourceViewer sourceViewer) {
+               // PHPColorProvider provider =
+               // PHPEditorEnvironment.getPHPColorProvider();
+               // JavaColorManager provider =
+               // PHPEditorEnvironment.getPHPColorProvider();
+               PresentationReconciler phpReconciler = new JavaPresentationReconciler();
+               phpReconciler
+                               .setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+               // DefaultDamagerRepairer dr = new
+               // DefaultDamagerRepairer(getHTMLScanner());
+               // reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+               // reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+               // dr = new DefaultDamagerRepairer(getHTMLScanner());
+               // reconciler.setDamager(dr, IPHPPartitions.HTML);
+               // reconciler.setRepairer(dr, IPHPPartitions.HTML);
+               // dr = new DefaultDamagerRepairer(getHTMLScanner());
+               // reconciler.setDamager(dr, IPHPPartitions.CSS);
+               // reconciler.setRepairer(dr, IPHPPartitions.CSS);
+               // dr = new DefaultDamagerRepairer(getHTMLScanner());
+               // reconciler.setDamager(dr, IPHPPartitions.CSS_MULTILINE_COMMENT);
+               // reconciler.setRepairer(dr, IPHPPartitions.CSS_MULTILINE_COMMENT);
+               // dr = new DefaultDamagerRepairer(getHTMLScanner());
+               // reconciler.setDamager(dr, IPHPPartitions.JAVASCRIPT);
+               // reconciler.setRepairer(dr, IPHPPartitions.JAVASCRIPT);
+               // dr = new DefaultDamagerRepairer(getHTMLScanner());
+               // reconciler.setDamager(dr, IPHPPartitions.JS_MULTILINE_COMMENT);
+               // reconciler.setRepairer(dr, IPHPPartitions.JS_MULTILINE_COMMENT);
+               // DefaultDamagerRepairer phpDR = new
+               // DefaultDamagerRepairer(getSmartyScanner());
+               // phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY);
+               // phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY);
+               // phpDR = new DefaultDamagerRepairer(getSmartyDocScanner());
+               // phpReconciler.setDamager(phpDR,
+               // IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+               // phpReconciler.setRepairer(phpDR,
+               // IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+               // dr = new DefaultDamagerRepairer(new SingleTokenScanner(new
+               // TextAttribute(fJavaTextTools.getColorManager().getColor(
+               // PHPColorProvider.MULTI_LINE_COMMENT))));
+               // reconciler.setDamager(dr, IPHPPartitions.HTML_MULTILINE_COMMENT);
+               // reconciler.setRepairer(dr, IPHPPartitions.HTML_MULTILINE_COMMENT);
+
+               DefaultDamagerRepairer phpDR = new DefaultDamagerRepairer(
+                               getCodeScanner());
+               phpReconciler.setDamager(phpDR, IDocument.DEFAULT_CONTENT_TYPE);
+               phpReconciler.setRepairer(phpDR, IDocument.DEFAULT_CONTENT_TYPE);
+
+               phpDR = new DefaultDamagerRepairer(getCodeScanner());
+               phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_PARTITIONING);
+               phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_PARTITIONING);
+
+               phpDR = new DefaultDamagerRepairer(getPHPDocScanner());
+               phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_PHPDOC_COMMENT);
+               phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_PHPDOC_COMMENT);
+
+               phpDR = new DefaultDamagerRepairer(getStringDQScanner());
+               phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_STRING_DQ);
+               phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_STRING_DQ);
+               phpDR = new DefaultDamagerRepairer(getStringSQScanner());
+               phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_STRING_SQ);
+               phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_STRING_SQ);
+               phpDR = new DefaultDamagerRepairer(getStringDQScanner());
+               phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_STRING_HEREDOC);
+               phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_STRING_HEREDOC);
+               phpDR = new DefaultDamagerRepairer(getSinglelineCommentScanner());
+               phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_SINGLELINE_COMMENT);
+               phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_SINGLELINE_COMMENT);
+               phpDR = new DefaultDamagerRepairer(getMultilineCommentScanner());
+               phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_MULTILINE_COMMENT);
+               phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_MULTILINE_COMMENT);
+
+               PresentationReconciler reconciler = new PresentationReconciler();
+               reconciler
+                               .setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+               //
+               // JavaTextTools jspTextTools =
+               // PHPeclipsePlugin.getDefault().getJavaTextTools();
+               DefaultDamagerRepairer dr = new DefaultDamagerRepairer(
+                               getPHPDocScanner());// jspTextTools.getJSPTextScanner());
+               reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+               reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+               // dr = new DefaultDamagerRepairer(new SingleTokenScanner(new
+               // TextAttribute(fJavaTextTools.getColorManager().getColor(
+               // PHPColorProvider.PHPDOC_TAG))));//jspTextTools.getJSPBracketScanner());
+               // reconciler.setDamager(dr, JSPScriptScanner.JSP_BRACKET);
+               // reconciler.setRepairer(dr, JSPScriptScanner.JSP_BRACKET);
+
+               // xml partitions
+               configureEmbeddedPresentationReconciler(reconciler, xmlConfiguration
+                               .getPresentationReconciler(sourceViewer), xmlConfiguration
+                               .getConfiguredContentTypes(sourceViewer),
+                               PHPDocumentPartitioner.PHP_TEMPLATE_DATA);
+
+               // java partitions
+               configureEmbeddedPresentationReconciler(reconciler, phpReconciler,
+                               getConfiguredPHPContentTypes(),
+                               PHPDocumentPartitioner.PHP_SCRIPT_CODE);
+
+               return reconciler;
+       }
+
+       private void configureEmbeddedPresentationReconciler(
+                       PresentationReconciler reconciler,
+                       IPresentationReconciler embedded, String[] types, String defaultType) {
+               for (int i = 0; i < types.length; i++) {
+                       String type = types[i];
+
+                       IPresentationDamager damager = embedded.getDamager(type);
+                       IPresentationRepairer repairer = embedded.getRepairer(type);
+
+                       if (type == IDocument.DEFAULT_CONTENT_TYPE) {
+                               type = defaultType;
+                       }
+
+                       reconciler.setDamager(damager, type);
+                       reconciler.setRepairer(repairer, type);
+               }
+       }
+
+       /*
+        * (non-Javadoc) Method declared on SourceViewerConfiguration
+        */
+       public int getTabWidth(ISourceViewer sourceViewer) {
+               return getPreferenceStore().getInt(PREFERENCE_TAB_WIDTH);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on SourceViewerConfiguration
+        */
+       // public ITextHover getTextHover(ISourceViewer sourceViewer, String
+       // contentType) {
+       // if (fEditor != null) {
+       // IEditorInput editorInput = fEditor.getEditorInput();
+       // if (editorInput instanceof IFileEditorInput) {
+       // try {
+       // IFile f = ((IFileEditorInput) editorInput).getFile();
+       // return new PHPTextHover(f.getProject());
+       // } catch (NullPointerException e) {
+       // // this exception occurs, if getTextHover is called by preference pages
+       // !
+       // }
+       // }
+       // }
+       // return new PHPTextHover(null);
+       // }
+       /*
+        * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer)
+        * @since 2.0
+        */
+       public IInformationControlCreator getInformationControlCreator(
+                       ISourceViewer sourceViewer) {
+               return new IInformationControlCreator() {
+                       public IInformationControl createInformationControl(Shell parent) {
+                               return new DefaultInformationControl(parent, SWT.NONE,
+                                               new HTMLTextPresenter(true));
+                               // return new HoverBrowserControl(parent);
+                       }
+               };
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer)
+        * @since 2.0
+        */
+       public IInformationPresenter getInformationPresenter(
+                       ISourceViewer sourceViewer) {
+               InformationPresenter presenter = new InformationPresenter(
+                               getInformationPresenterControlCreator(sourceViewer));
+               presenter
+                               .setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+               IInformationProvider provider = new JavaInformationProvider(getEditor());
+               presenter.setInformationProvider(provider,
+                               IDocument.DEFAULT_CONTENT_TYPE);
+               presenter.setInformationProvider(provider,
+                               IPHPPartitions.PHP_PHPDOC_COMMENT);
+               // presenter.setInformationProvider(provider,
+               // IPHPPartitions.JAVA_CHARACTER);
+               presenter.setSizeConstraints(60, 10, true, true);
+               return presenter;
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer)
+        * @since 2.0
+        */
+       // public IInformationPresenter getInformationPresenter(ISourceViewer
+       // sourceViewer) {
+       // InformationPresenter presenter= new
+       // InformationPresenter(getInformationPresenterControlCreator(sourceViewer));
+       // IInformationProvider provider= new JavaInformationProvider(getEditor());
+       // presenter.setInformationProvider(provider,
+       // IDocument.DEFAULT_CONTENT_TYPE);
+       // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC);
+       // presenter.setSizeConstraints(60, 10, true, true);
+       // return presenter;
+       // }
+       /**
+        * Returns the information presenter control creator. The creator is a
+        * factory creating the presenter controls for the given source viewer. This
+        * implementation always returns a creator for
+        * <code>DefaultInformationControl</code> instances.
+        * 
+        * @param sourceViewer
+        *            the source viewer to be configured by this configuration
+        * @return an information control creator
+        * @since 2.1
+        */
+       private IInformationControlCreator getInformationPresenterControlCreator(
+                       ISourceViewer sourceViewer) {
+               return new IInformationControlCreator() {
+                       public IInformationControl createInformationControl(Shell parent) {
+                               int shellStyle = SWT.RESIZE;
+                               int style = SWT.V_SCROLL | SWT.H_SCROLL;
+                               return new DefaultInformationControl(parent, shellStyle, style,
+                                               new HTMLTextPresenter(false));
+                               // return new HoverBrowserControl(parent);
+                       }
+               };
+       }
+
+       /**
+        * 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>JavaOutlineInformationControl</code> instances.
+        * 
+        * @param sourceViewer
+        *            the source viewer to be configured by this configuration
+        * @return an information control creator
+        * @since 2.1
+        */
+       private IInformationControlCreator getOutlinePresenterControlCreator(
+                       ISourceViewer sourceViewer) {
+               return new IInformationControlCreator() {
+                       public IInformationControl createInformationControl(Shell parent) {
+                               int shellStyle = SWT.RESIZE;
+                               int treeStyle = SWT.V_SCROLL | SWT.H_SCROLL;
+                               return new JavaOutlineInformationControl(parent, shellStyle,
+                                               treeStyle);
+                       }
+               };
+       }
+
+       /**
+        * Returns the outline presenter which will determine and shown 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 Java element
+        * @return an information presenter
+        * @since 2.1
+        */
+       public IInformationPresenter getOutlinePresenter(
+                       ISourceViewer sourceViewer, boolean doCodeResolve) {
+               InformationPresenter presenter = new InformationPresenter(
+                               getOutlinePresenterControlCreator(sourceViewer));
+               presenter.setAnchor(InformationPresenter.ANCHOR_GLOBAL);
+               IInformationProvider provider = new JavaElementProvider(getEditor(),
+                               doCodeResolve);
+               presenter.setInformationProvider(provider,
+                               IDocument.DEFAULT_CONTENT_TYPE);
+               presenter.setInformationProvider(provider,
+                               PHPDocumentPartitioner.PHP_SCRIPT_CODE);
+               presenter.setInformationProvider(provider,
+                               IPHPPartitions.PHP_PARTITIONING);
+               presenter.setInformationProvider(provider,
+                               IPHPPartitions.PHP_PHPDOC_COMMENT);
+               presenter.setInformationProvider(provider,
+                               IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+               presenter.setInformationProvider(provider, IPHPPartitions.HTML);
+               presenter.setInformationProvider(provider,
+                               IPHPPartitions.HTML_MULTILINE_COMMENT);
+               presenter.setSizeConstraints(40, 20, true, false);
+               return presenter;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/PHPStringDQCodeScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/PHPStringDQCodeScanner.java
new file mode 100644 (file)
index 0000000..6203ece
--- /dev/null
@@ -0,0 +1,125 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpdt.ui.text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPVariableDetector;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * A rule based PHPDoc scanner.
+ */
+public final class PHPStringDQCodeScanner extends AbstractJavaScanner {
+
+       private static String[] fgTokenProperties = {
+                       IPreferenceConstants.PHP_STRING_DQ,
+                       IPreferenceConstants.PHP_VARIABLE,
+                       IPreferenceConstants.PHP_VARIABLE_DOLLAR };
+
+       private class PHPWordRule extends WordRule {
+               private StringBuffer fBuffer = new StringBuffer();
+
+               public PHPWordRule(IWordDetector detector) {
+                       super(detector, Token.UNDEFINED);
+               }
+
+               public PHPWordRule(IWordDetector detector, IToken defaultToken) {
+                       super(detector, defaultToken);
+               }
+
+               public IToken evaluate(ICharacterScanner scanner) {
+                       int c = scanner.read();
+                       boolean isUnderscore = false;
+                       if (fDetector.isWordStart((char) c)) {
+                               if (fColumn == UNDEFINED
+                                               || (fColumn == scanner.getColumn() - 1)) {
+
+                                       fBuffer.setLength(0);
+                                       fBuffer.append((char) c);
+                                       c = scanner.read();
+                                       if (c == '_') {
+                                               isUnderscore = true;
+                                       }
+                                       while (c != ICharacterScanner.EOF
+                                                       && fDetector.isWordPart((char) c)) {
+                                               fBuffer.append((char) c);
+                                               c = scanner.read();
+                                               // hack for coloring object elements with variable color
+                                               // instead of string color
+                                               if (c == '-') {
+                                                       int c2 = scanner.read();
+                                                       if (c2 == '>') {
+                                                               fBuffer.append(c);
+                                                               fBuffer.append(c2);
+                                                               c = scanner.read();
+                                                       } else {
+                                                               scanner.unread();
+                                                       }
+                                               }
+                                               // hack end
+                                       }
+                                       scanner.unread();
+                                       if (isUnderscore) {
+                                               return getToken(IPreferenceConstants.PHP_VARIABLE_DOLLAR);
+                                       }
+                                       return getToken(IPreferenceConstants.PHP_VARIABLE);
+                               }
+                       }
+
+                       scanner.unread();
+                       return Token.UNDEFINED;
+               }
+       }
+
+       public PHPStringDQCodeScanner(IColorManager manager, IPreferenceStore store) {
+               super(manager, store);
+               initialize();
+       }
+
+       public IDocument getDocument() {
+               return fDocument;
+       }
+
+       /*
+        * @see AbstractJavaScanner#getTokenProperties()
+        */
+       protected String[] getTokenProperties() {
+               return fgTokenProperties;
+       }
+
+       /*
+        * @see AbstractJavaScanner#createRules()
+        */
+       protected List createRules() {
+
+               List list = new ArrayList();
+
+               // Add rule for tags.
+               Token token = getToken(IPreferenceConstants.PHP_STRING_DQ);
+               PHPWordRule wordRule = new PHPWordRule(new PHPVariableDetector(), token);
+
+               list.add(wordRule);
+
+               setDefaultReturnToken(getToken(IPreferenceConstants.PHP_STRING_DQ));
+               return list;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/SingleTokenPHPScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/SingleTokenPHPScanner.java
new file mode 100644 (file)
index 0000000..81bdd4e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+package net.sourceforge.phpdt.ui.text;
+
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * 
+ */
+public final class SingleTokenPHPScanner extends AbstractJavaScanner {
+
+       private String[] fProperty;
+
+       public SingleTokenPHPScanner(IColorManager manager, IPreferenceStore store,
+                       String property) {
+               super(manager, store);
+               fProperty = new String[] { property };
+               initialize();
+       }
+
+       /*
+        * @see AbstractJavaScanner#getTokenProperties()
+        */
+       protected String[] getTokenProperties() {
+               return fProperty;
+       }
+
+       /*
+        * @see AbstractJavaScanner#createRules()
+        */
+       protected List createRules() {
+               setDefaultReturnToken(getToken(fProperty[0]));
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/IJavaFoldingPreferenceBlock.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/IJavaFoldingPreferenceBlock.java
new file mode 100644 (file)
index 0000000..dc9e1bf
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.text.folding;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Contributors to the
+ * <code>net.sourceforge.phpdt.ui.foldingStructureProvider</code> extension
+ * point can specify an implementation of this interface to be displayed on the
+ * Java &gt; Editor &gt; Folding preference page.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public interface IJavaFoldingPreferenceBlock {
+
+       /**
+        * Creates the control that will be displayed on the Java Editor folding
+        * preference page.
+        * 
+        * @param parent
+        *            the parent composite to which to add the preferences control
+        * @return the control that was added to <code>parent</code>
+        */
+       Control createControl(Composite parent);
+
+       /**
+        * Called after creating the control. Implementations should load the
+        * preferences values and update the controls accordingly.
+        */
+       void initialize();
+
+       /**
+        * Called when the <code>OK</code> button is pressed on the preference
+        * page. Implementations should commit the configured preference settings
+        * into their form of preference storage.
+        */
+       void performOk();
+
+       /**
+        * Called when the <code>Defaults</code> button is pressed on the
+        * preference page. Implementation should reset any preference settings to
+        * their default values and adjust the controls accordingly.
+        */
+       void performDefaults();
+
+       /**
+        * Called when the preference page is being disposed. Implementations should
+        * free any resources they are holding on to.
+        */
+       void dispose();
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/IJavaFoldingStructureProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/IJavaFoldingStructureProvider.java
new file mode 100644 (file)
index 0000000..9fa814a
--- /dev/null
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.text.folding;
+
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Contributors to the
+ * <code>net.sourceforge.phpdt.ui.foldingStructureProvider</code> extension
+ * point must specify an implementation of this interface which will create and
+ * maintain
+ * {@link org.eclipse.jface.text.source.projection.ProjectionAnnotation} objects
+ * as understood by
+ * {@link org.eclipse.jface.text.source.projection.ProjectionViewer}.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public interface IJavaFoldingStructureProvider {
+
+       /**
+        * Installs this structure provider on the given editor and viewer.
+        * Implementations should observe the projection events generated by
+        * <code>viewer</code> and enable / disable generation of projection
+        * structure accordingly.
+        * 
+        * @param editor
+        *            the editor that this provider works on
+        * @param viewer
+        *            the projection viewer that displays the annotations created by
+        *            this structure provider
+        */
+       public abstract void install(ITextEditor editor, ProjectionViewer viewer);
+
+       /**
+        * Uninstalls this structure provider. Any references to editors or viewers
+        * should be cleared.
+        */
+       public abstract void uninstall();
+
+       /**
+        * (Re-)initializes the structure provided by the receiver.
+        */
+       public abstract void initialize();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/package.html b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/folding/package.html
new file mode 100644 (file)
index 0000000..3148d97
--- /dev/null
@@ -0,0 +1,16 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Eclipse Text Editor">
+   <title>Java Folding</title>
+</head>
+<body>
+Application programming interfaces for interaction
+with the Eclipse Java Editor folding.
+<h2>
+Package Specification</h2>
+Interfaces for contributions to the <code>net.sourceforge.phpdt.ui.foldingStructureProviders</code> extension point.
+</body>
+</html>
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/java/hover/IJavaEditorTextHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/java/hover/IJavaEditorTextHover.java
new file mode 100644 (file)
index 0000000..5f4dda2
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.text.java.hover;
+
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Provides a hover popup which appears on top of an editor with relevant
+ * display information. If the text hover does not provide information no hover
+ * popup is shown.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @see org.eclipse.ui.IEditorPart
+ * @see org.eclipse.jface.text.ITextHover
+ * 
+ * @since 2.0
+ */
+public interface IJavaEditorTextHover extends ITextHover {
+
+       /**
+        * Sets the editor on which the hover is shown.
+        * 
+        * @param editor
+        *            the editor on which the hover popup should be shown
+        */
+       void setEditor(IEditorPart editor);
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/java/hover/package.html b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/text/java/hover/package.html
new file mode 100644 (file)
index 0000000..7cfda13
--- /dev/null
@@ -0,0 +1,16 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Application programming interfaces for interaction with the PHPeclipse PHP Editor.
+<h2>
+Package Specification</h2>
+Support for presenting text hovers in PHP editors. The interface <b>IJavaEditorTextHover</b>
+defines the programming interface for a text hover.
+</body>
+</html>
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewClassWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewClassWizardPage.java
new file mode 100644 (file)
index 0000000..4203e32
--- /dev/null
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.wizards;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.internal.ui.wizards.NewWizardMessages;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogFieldGroup;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Wizard page to create a new class.
+ * <p>
+ * Note: This class is not intended to be subclassed. To implement a different
+ * kind of a new class wizard page, extend <code>NewTypeWizardPage</code>.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class NewClassWizardPage extends NewTypeWizardPage {
+
+       private final static String PAGE_NAME = "NewClassWizardPage"; //$NON-NLS-1$
+
+       private final static String SETTINGS_CREATEMAIN = "create_main"; //$NON-NLS-1$
+
+       private final static String SETTINGS_CREATECONSTR = "create_constructor"; //$NON-NLS-1$
+
+       private final static String SETTINGS_CREATEUNIMPLEMENTED = "create_unimplemented"; //$NON-NLS-1$
+
+       private SelectionButtonDialogFieldGroup fMethodStubsButtons;
+
+       /**
+        * Creates a new <code>NewClassWizardPage</code>
+        */
+       public NewClassWizardPage() {
+               super(true, PAGE_NAME);
+
+               setTitle(NewWizardMessages.getString("NewClassWizardPage.title")); //$NON-NLS-1$
+               setDescription(NewWizardMessages
+                               .getString("NewClassWizardPage.description")); //$NON-NLS-1$
+
+               String[] buttonNames3 = new String[] {
+                               NewWizardMessages.getString("NewClassWizardPage.methods.main"), NewWizardMessages.getString("NewClassWizardPage.methods.constructors"), //$NON-NLS-1$ //$NON-NLS-2$
+                               NewWizardMessages
+                                               .getString("NewClassWizardPage.methods.inherited") //$NON-NLS-1$
+               };
+               fMethodStubsButtons = new SelectionButtonDialogFieldGroup(SWT.CHECK,
+                               buttonNames3, 1);
+               fMethodStubsButtons.setLabelText(NewWizardMessages
+                               .getString("NewClassWizardPage.methods.label")); //$NON-NLS-1$
+       }
+
+       // -------- Initialization ---------
+
+       /**
+        * The wizard owning this page is responsible for calling this method with
+        * the current selection. The selection is used to initialize the fields of
+        * the wizard page.
+        * 
+        * @param selection
+        *            used to initialize the fields
+        */
+       public void init(IStructuredSelection selection) {
+               IJavaElement jelem = getInitialJavaElement(selection);
+               initContainerPage(jelem);
+               initTypePage(jelem);
+               doStatusUpdate();
+
+               boolean createMain = false;
+               boolean createConstructors = false;
+               boolean createUnimplemented = true;
+               IDialogSettings section = getDialogSettings().getSection(PAGE_NAME);
+               if (section != null) {
+                       createMain = section.getBoolean(SETTINGS_CREATEMAIN);
+                       createConstructors = section.getBoolean(SETTINGS_CREATECONSTR);
+                       createUnimplemented = section
+                                       .getBoolean(SETTINGS_CREATEUNIMPLEMENTED);
+               }
+
+               setMethodStubSelection(createMain, createConstructors,
+                               createUnimplemented, true);
+       }
+
+       // ------ validation --------
+       private void doStatusUpdate() {
+               // status of all used components
+               IStatus[] status = new IStatus[] {
+                               fContainerStatus,
+                               isEnclosingTypeSelected() ? fEnclosingTypeStatus
+                                               : fPackageStatus, fTypeNameStatus, fModifierStatus,
+               // fSuperClassStatus,
+               // fSuperInterfacesStatus
+               };
+
+               // the mode severe status will be displayed and the ok button
+               // enabled/disabled.
+               updateStatus(status);
+       }
+
+       /*
+        * @see NewContainerWizardPage#handleFieldChanged
+        */
+       protected void handleFieldChanged(String fieldName) {
+               super.handleFieldChanged(fieldName);
+
+               doStatusUpdate();
+       }
+
+       // ------ ui --------
+
+       /*
+        * @see WizardPage#createControl
+        */
+       public void createControl(Composite parent) {
+               initializeDialogUnits(parent);
+
+               Composite composite = new Composite(parent, SWT.NONE);
+
+               int nColumns = 4;
+
+               GridLayout layout = new GridLayout();
+               layout.numColumns = nColumns;
+               composite.setLayout(layout);
+
+               // pick & choose the wanted UI components
+
+               createContainerControls(composite, nColumns);
+               createPackageControls(composite, nColumns);
+               createEnclosingTypeControls(composite, nColumns);
+
+               createSeparator(composite, nColumns);
+
+               createTypeNameControls(composite, nColumns);
+               createModifierControls(composite, nColumns);
+
+               createSuperClassControls(composite, nColumns);
+               createSuperInterfacesControls(composite, nColumns);
+
+               createMethodStubSelectionControls(composite, nColumns);
+
+               setControl(composite);
+
+               Dialog.applyDialogFont(composite);
+               // WorkbenchHelp.setHelp(composite,
+               // IJavaHelpContextIds.NEW_CLASS_WIZARD_PAGE);
+       }
+
+       /*
+        * @see WizardPage#becomesVisible
+        */
+       public void setVisible(boolean visible) {
+               super.setVisible(visible);
+               if (visible) {
+                       setFocus();
+               }
+       }
+
+       private void createMethodStubSelectionControls(Composite composite,
+                       int nColumns) {
+               Control labelControl = fMethodStubsButtons.getLabelControl(composite);
+               LayoutUtil.setHorizontalSpan(labelControl, nColumns);
+
+               DialogField.createEmptySpace(composite);
+
+               Control buttonGroup = fMethodStubsButtons
+                               .getSelectionButtonsGroup(composite);
+               LayoutUtil.setHorizontalSpan(buttonGroup, nColumns - 1);
+       }
+
+       /**
+        * Returns the current selection state of the 'Create Main' checkbox.
+        * 
+        * @return the selection state of the 'Create Main' checkbox
+        */
+       public boolean isCreateMain() {
+               return fMethodStubsButtons.isSelected(0);
+       }
+
+       /**
+        * Returns the current selection state of the 'Create Constructors'
+        * checkbox.
+        * 
+        * @return the selection state of the 'Create Constructors' checkbox
+        */
+       public boolean isCreateConstructors() {
+               return fMethodStubsButtons.isSelected(1);
+       }
+
+       /**
+        * Returns the current selection state of the 'Create inherited abstract
+        * methods' checkbox.
+        * 
+        * @return the selection state of the 'Create inherited abstract methods'
+        *         checkbox
+        */
+       public boolean isCreateInherited() {
+               return fMethodStubsButtons.isSelected(2);
+       }
+
+       /**
+        * Sets the selection state of the method stub checkboxes.
+        * 
+        * @param createMain
+        *            initial selection state of the 'Create Main' checkbox.
+        * @param createConstructors
+        *            initial selection state of the 'Create Constructors' checkbox.
+        * @param createInherited
+        *            initial selection state of the 'Create inherited abstract
+        *            methods' checkbox.
+        * @param canBeModified
+        *            if <code>true</code> the method stub checkboxes can be
+        *            changed by the user. If <code>false</code> the buttons are
+        *            "read-only"
+        */
+       public void setMethodStubSelection(boolean createMain,
+                       boolean createConstructors, boolean createInherited,
+                       boolean canBeModified) {
+               fMethodStubsButtons.setSelection(0, createMain);
+               fMethodStubsButtons.setSelection(1, createConstructors);
+               fMethodStubsButtons.setSelection(2, createInherited);
+
+               fMethodStubsButtons.setEnabled(canBeModified);
+       }
+
+       // ---- creation ----------------
+
+       /*
+        * @see NewTypeWizardPage#createTypeMembers
+        */
+       // protected void createTypeMembers(IType type, ImportsManager imports,
+       // IProgressMonitor monitor) throws CoreException {
+       // boolean doMain= isCreateMain();
+       // boolean doConstr= isCreateConstructors();
+       // boolean doInherited= isCreateInherited();
+       // createInheritedMethods(type, doConstr, doInherited, imports, new
+       // SubProgressMonitor(monitor, 1));
+       //
+       // if (doMain) {
+       // StringBuffer buf= new StringBuffer();
+       // buf.append("public static void main("); //$NON-NLS-1$
+       // buf.append(imports.addImport("java.lang.String")); //$NON-NLS-1$
+       // buf.append("[] args) {}"); //$NON-NLS-1$
+       // type.createMethod(buf.toString(), null, false, null);
+       // }
+       //              
+       // IDialogSettings section= getDialogSettings().getSection(PAGE_NAME);
+       // if (section == null) {
+       // section= getDialogSettings().addNewSection(PAGE_NAME);
+       // }
+       // section.put(SETTINGS_CREATEMAIN, doMain);
+       // section.put(SETTINGS_CREATECONSTR, doConstr);
+       // section.put(SETTINGS_CREATEUNIMPLEMENTED, doInherited);
+       //              
+       // if (monitor != null) {
+       // monitor.done();
+       // }
+       // }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java
new file mode 100644 (file)
index 0000000..f21bfb6
--- /dev/null
@@ -0,0 +1,474 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.wizards;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.externaltools.internal.ui.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider;
+import net.sourceforge.phpdt.internal.ui.wizards.NewWizardMessages;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+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.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.views.contentoutline.ContentOutline;
+
+/**
+ * Wizard page that acts as a base class for wizard pages that create new Java
+ * elements. The class provides a input field for source folders (called
+ * container in this class) and API to validate the enter source folder name.
+ * 
+ * @since 2.0
+ */
+public abstract class NewContainerWizardPage extends NewElementWizardPage {
+
+       /** Id of the container field */
+       protected static final String CONTAINER = "NewContainerWizardPage.container"; //$NON-NLS-1$
+
+       /** The status of the last validation. */
+       protected IStatus fContainerStatus;
+
+       private StringButtonDialogField fContainerDialogField;
+
+       /*
+        * package fragment root corresponding to the input type (can be null)
+        */
+       private IPackageFragmentRoot fCurrRoot;
+
+       private IWorkspaceRoot fWorkspaceRoot;
+
+       /**
+        * Create a new <code>NewContainerWizardPage</code>
+        * 
+        * @param name
+        *            the wizard page's name
+        */
+       public NewContainerWizardPage(String name) {
+               super(name);
+               fWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+               ContainerFieldAdapter adapter = new ContainerFieldAdapter();
+
+               fContainerDialogField = new StringButtonDialogField(adapter);
+               fContainerDialogField.setDialogFieldListener(adapter);
+               fContainerDialogField.setLabelText(NewWizardMessages
+                               .getString("NewContainerWizardPage.container.label")); //$NON-NLS-1$
+               fContainerDialogField.setButtonLabel(NewWizardMessages
+                               .getString("NewContainerWizardPage.container.button")); //$NON-NLS-1$
+
+               fContainerStatus = new StatusInfo();
+               fCurrRoot = null;
+       }
+
+       /**
+        * Initializes the source folder field with a valid package fragement root.
+        * The package fragement root is computed from the given Java element.
+        * 
+        * @param elem
+        *            the Java element used to compute the initial package fragment
+        *            root used as the source folder
+        */
+       protected void initContainerPage(IJavaElement elem) {
+               IPackageFragmentRoot initRoot = null;
+               // if (elem != null) {
+               // initRoot= JavaModelUtil.getPackageFragmentRoot(elem);
+               // if (initRoot == null || initRoot.isArchive()) {
+               // IJavaProject jproject= elem.getJavaProject();
+               // if (jproject != null) {
+               // try {
+               // initRoot= null;
+               // if (jproject.exists()) {
+               // IPackageFragmentRoot[] roots= jproject.getPackageFragmentRoots();
+               // for (int i= 0; i < roots.length; i++) {
+               // if (roots[i].getKind() == IPackageFragmentRoot.K_SOURCE) {
+               // initRoot= roots[i];
+               // break;
+               // }
+               // }
+               // }
+               // } catch (JavaModelException e) {
+               // PHPeclipsePlugin.log(e);
+               // }
+               // if (initRoot == null) {
+               // initRoot= jproject.getPackageFragmentRoot(jproject.getResource());
+               // }
+               // }
+               // }
+               // }
+               // setPackageFragmentRoot(initRoot, true);
+       }
+
+       /**
+        * Utility method to inspect a selection to find a Java element.
+        * 
+        * @param selection
+        *            the selection to be inspected
+        * @return a Java element to be used as the initial selection, or
+        *         <code>null</code>, if no Java element exists in the given
+        *         selection
+        */
+       protected IJavaElement getInitialJavaElement(IStructuredSelection selection) {
+               IJavaElement jelem = null;
+               if (selection != null && !selection.isEmpty()) {
+                       Object selectedElement = selection.getFirstElement();
+                       if (selectedElement instanceof IAdaptable) {
+                               IAdaptable adaptable = (IAdaptable) selectedElement;
+
+                               jelem = (IJavaElement) adaptable.getAdapter(IJavaElement.class);
+                               if (jelem == null) {
+                                       IResource resource = (IResource) adaptable
+                                                       .getAdapter(IResource.class);
+                                       if (resource != null
+                                                       && resource.getType() != IResource.ROOT) {
+                                               while (jelem == null
+                                                               && resource.getType() != IResource.PROJECT) {
+                                                       resource = resource.getParent();
+                                                       jelem = (IJavaElement) resource
+                                                                       .getAdapter(IJavaElement.class);
+                                               }
+                                               if (jelem == null) {
+                                                       jelem = JavaCore.create(resource); // java project
+                                               }
+                                       }
+                               }
+                       }
+               }
+               if (jelem == null) {
+                       IWorkbenchPart part = WebUI.getActivePage()
+                                       .getActivePart();
+                       if (part instanceof ContentOutline) {
+                               part = WebUI.getActivePage().getActiveEditor();
+                       }
+
+                       if (part instanceof IViewPartInputProvider) {
+                               Object elem = ((IViewPartInputProvider) part)
+                                               .getViewPartInput();
+                               if (elem instanceof IJavaElement) {
+                                       jelem = (IJavaElement) elem;
+                               }
+                       }
+               }
+
+               if (jelem == null || jelem.getElementType() == IJavaElement.JAVA_MODEL) {
+                       try {
+                               IJavaProject[] projects = JavaCore.create(getWorkspaceRoot())
+                                               .getJavaProjects();
+                               if (projects.length == 1) {
+                                       jelem = projects[0];
+                               }
+                       } catch (JavaModelException e) {
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+               return jelem;
+       }
+
+       /**
+        * Returns the recommended maximum width for text fields (in pixels). This
+        * method requires that createContent has been called before this method is
+        * call. Subclasses may override to change the maximum width for text
+        * fields.
+        * 
+        * @return the recommended maximum width for text fields.
+        */
+       protected int getMaxFieldWidth() {
+               return convertWidthInCharsToPixels(40);
+       }
+
+       /**
+        * Creates the necessary controls (label, text field and browse button) to
+        * edit the source folder location. The method expects that the parent
+        * composite uses a <code>GridLayout</code> as its layout manager and that
+        * the grid layout has at least 3 columns.
+        * 
+        * @param parent
+        *            the parent composite
+        * @param nColumns
+        *            the number of columns to span. This number must be greater or
+        *            equal three
+        */
+       protected void createContainerControls(Composite parent, int nColumns) {
+               fContainerDialogField.doFillIntoGrid(parent, nColumns);
+               LayoutUtil.setWidthHint(fContainerDialogField.getTextControl(null),
+                               getMaxFieldWidth());
+       }
+
+       /**
+        * Sets the focus to the source folder's text field.
+        */
+       protected void setFocusOnContainer() {
+               fContainerDialogField.setFocus();
+       }
+
+       // -------- ContainerFieldAdapter --------
+
+       private class ContainerFieldAdapter implements IStringButtonAdapter,
+                       IDialogFieldListener {
+
+               // -------- IStringButtonAdapter
+               public void changeControlPressed(DialogField field) {
+                       containerChangeControlPressed(field);
+               }
+
+               // -------- IDialogFieldListener
+               public void dialogFieldChanged(DialogField field) {
+                       containerDialogFieldChanged(field);
+               }
+       }
+
+       private void containerChangeControlPressed(DialogField field) {
+               // take the current jproject as init element of the dialog
+               // IPackageFragmentRoot root= getPackageFragmentRoot();
+               // root= chooseSourceContainer(root);
+               // if (root != null) {
+               // setPackageFragmentRoot(root, true);
+               // }
+       }
+
+       private void containerDialogFieldChanged(DialogField field) {
+               if (field == fContainerDialogField) {
+                       fContainerStatus = containerChanged();
+               }
+               // tell all others
+               handleFieldChanged(CONTAINER);
+       }
+
+       // ----------- validation ----------
+
+       /**
+        * This method is a hook which gets called after the source folder's text
+        * input field has changed. This default implementation updates the model
+        * and returns an error status. The underlying model is only valid if the
+        * returned status is OK.
+        * 
+        * @return the model's error status
+        */
+       protected IStatus containerChanged() {
+               StatusInfo status = new StatusInfo();
+
+               fCurrRoot = null;
+               String str = getPackageFragmentRootText();
+               if (str.length() == 0) {
+                       status
+                                       .setError(NewWizardMessages
+                                                       .getString("NewContainerWizardPage.error.EnterContainerName")); //$NON-NLS-1$
+                       return status;
+               }
+               IPath path = new Path(str);
+               IResource res = fWorkspaceRoot.findMember(path);
+               if (res != null) {
+                       int resType = res.getType();
+                       if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
+                               IProject proj = res.getProject();
+                               if (!proj.isOpen()) {
+                                       status
+                                                       .setError(NewWizardMessages
+                                                                       .getFormattedString(
+                                                                                       "NewContainerWizardPage.error.ProjectClosed", proj.getFullPath().toString())); //$NON-NLS-1$
+                                       return status;
+                               }
+                               IJavaProject jproject = JavaCore.create(proj);
+                               // fCurrRoot= jproject.getPackageFragmentRoot(res);
+                               // if (res.exists()) {
+                               // try {
+                               // if (!proj.hasNature(JavaCore.NATURE_ID)) {
+                               // if (resType == IResource.PROJECT) {
+                               // status.setError(NewWizardMessages.getString("NewContainerWizardPage.warning.NotAJavaProject"));
+                               // //$NON-NLS-1$
+                               // } else {
+                               // status.setWarning(NewWizardMessages.getString("NewContainerWizardPage.warning.NotInAJavaProject"));
+                               // //$NON-NLS-1$
+                               // }
+                               // return status;
+                               // }
+                               // } catch (CoreException e) {
+                               // status.setWarning(NewWizardMessages.getString("NewContainerWizardPage.warning.NotAJavaProject"));
+                               // //$NON-NLS-1$
+                               // }
+                               // if (!jproject.isOnClasspath(fCurrRoot)) {
+                               // status.setWarning(NewWizardMessages.getFormattedString("NewContainerWizardPage.warning.NotOnClassPath",
+                               // str)); //$NON-NLS-1$
+                               // }
+                               // if (fCurrRoot.isArchive()) {
+                               // status.setError(NewWizardMessages.getFormattedString("NewContainerWizardPage.error.ContainerIsBinary",
+                               // str)); //$NON-NLS-1$
+                               // return status;
+                               // }
+                               // }
+                               return status;
+                       } else {
+                               status.setError(NewWizardMessages.getFormattedString(
+                                               "NewContainerWizardPage.error.NotAFolder", str)); //$NON-NLS-1$
+                               return status;
+                       }
+               } else {
+                       status.setError(NewWizardMessages.getFormattedString(
+                                       "NewContainerWizardPage.error.ContainerDoesNotExist", str)); //$NON-NLS-1$
+                       return status;
+               }
+       }
+
+       // -------- update message ----------------
+
+       /**
+        * Hook method that gets called when a field on this page has changed. For
+        * this page the method gets called when the source folder field changes.
+        * <p>
+        * Every sub type is responsible to call this method when a field on its
+        * page has changed. Subtypes override (extend) the method to add
+        * verification when a own field has a dependency to an other field. For
+        * example the class name input must be verified again when the package
+        * field changes (check for duplicated class names).
+        * 
+        * @param fieldName
+        *            The name of the field that has changed (field id). For the
+        *            source folder the field id is <code>CONTAINER</code>
+        */
+       protected void handleFieldChanged(String fieldName) {
+       }
+
+       // ---- get ----------------
+
+       /**
+        * Returns the workspace root.
+        * 
+        * @return the workspace root
+        */
+       protected IWorkspaceRoot getWorkspaceRoot() {
+               return fWorkspaceRoot;
+       }
+
+       /**
+        * Returns the <code>IPackageFragmentRoot</code> that corresponds to the
+        * current value of the source folder field.
+        * 
+        * @return the IPackageFragmentRoot or <code>null</code> if the current
+        *         source folder value is not a valid package fragment root
+        * 
+        */
+       public IPackageFragmentRoot getPackageFragmentRoot() {
+               return fCurrRoot;
+       }
+
+       /**
+        * Returns the current text of source folder text field.
+        * 
+        * @return the text of the source folder text field
+        */
+       public String getPackageFragmentRootText() {
+               return fContainerDialogField.getText();
+       }
+
+       /**
+        * Sets the current source folder (model and text field) to the given
+        * package fragment root.
+        * 
+        * @param canBeModified
+        *            if <code>false</code> the source folder field can not be
+        *            changed by the user. If <code>true</code> the field is
+        *            editable
+        */
+       // public void setPackageFragmentRoot(IPackageFragmentRoot root, boolean
+       // canBeModified) {
+       // fCurrRoot= root;
+       // String str= (root == null) ? "" :
+       // root.getPath().makeRelative().toString(); //$NON-NLS-1$
+       // fContainerDialogField.setText(str);
+       // fContainerDialogField.setEnabled(canBeModified);
+       // }
+       // ------------- choose source container dialog
+       // private IPackageFragmentRoot chooseSourceContainer(IJavaElement
+       // initElement) {
+       // Class[] acceptedClasses= new Class[] { IPackageFragmentRoot.class,
+       // IJavaProject.class };
+       // TypedElementSelectionValidator validator= new
+       // TypedElementSelectionValidator(acceptedClasses, false) {
+       // public boolean isSelectedValid(Object element) {
+       // try {
+       // if (element instanceof IJavaProject) {
+       // IJavaProject jproject= (IJavaProject)element;
+       // IPath path= jproject.getProject().getFullPath();
+       // return (jproject.findPackageFragmentRoot(path) != null);
+       // } else if (element instanceof IPackageFragmentRoot) {
+       // return (((IPackageFragmentRoot)element).getKind() ==
+       // IPackageFragmentRoot.K_SOURCE);
+       // }
+       // return true;
+       // } catch (JavaModelException e) {
+       // PHPeclipsePlugin.log(e.getStatus()); // just log, no ui in validation
+       // }
+       // return false;
+       // }
+       // };
+       //              
+       // acceptedClasses= new Class[] { IJavaModel.class,
+       // IPackageFragmentRoot.class, IJavaProject.class };
+       // ViewerFilter filter= new TypedViewerFilter(acceptedClasses) {
+       // public boolean select(Viewer viewer, Object parent, Object element) {
+       // if (element instanceof IPackageFragmentRoot) {
+       // try {
+       // return (((IPackageFragmentRoot)element).getKind() ==
+       // IPackageFragmentRoot.K_SOURCE);
+       // } catch (JavaModelException e) {
+       // PHPeclipsePlugin.log(e.getStatus()); // just log, no ui in validation
+       // return false;
+       // }
+       // }
+       // return super.select(viewer, parent, element);
+       // }
+       // };
+       //
+       // StandardJavaElementContentProvider provider= new
+       // StandardJavaElementContentProvider();
+       // ILabelProvider labelProvider= new
+       // JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
+       // ElementTreeSelectionDialog dialog= new
+       // ElementTreeSelectionDialog(getShell(), labelProvider, provider);
+       // dialog.setValidator(validator);
+       // dialog.setSorter(new JavaElementSorter());
+       // dialog.setTitle(NewWizardMessages.getString("NewContainerWizardPage.ChooseSourceContainerDialog.title"));
+       // //$NON-NLS-1$
+       // dialog.setMessage(NewWizardMessages.getString("NewContainerWizardPage.ChooseSourceContainerDialog.description"));
+       // //$NON-NLS-1$
+       // dialog.addFilter(filter);
+       // dialog.setInput(JavaCore.create(fWorkspaceRoot));
+       // dialog.setInitialSelection(initElement);
+       //              
+       // if (dialog.open() == ElementTreeSelectionDialog.OK) {
+       // Object element= dialog.getFirstResult();
+       // if (element instanceof IJavaProject) {
+       // IJavaProject jproject= (IJavaProject)element;
+       // return jproject.getPackageFragmentRoot(jproject.getProject());
+       // } else if (element instanceof IPackageFragmentRoot) {
+       // return (IPackageFragmentRoot)element;
+       // }
+       // return null;
+       // }
+       // return null;
+       // }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewElementWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewElementWizardPage.java
new file mode 100644 (file)
index 0000000..653d4a0
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.wizards;
+
+import net.sourceforge.phpdt.externaltools.internal.ui.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.wizard.WizardPage;
+
+/**
+ * Base class for wizard page responsible to create PHP elements. The class
+ * provides API to update the wizard's statis line and OK button according to
+ * the value of a <code>IStatus</code> object.
+ * 
+ * @since 2.0
+ */
+public abstract class NewElementWizardPage extends WizardPage {
+
+       private IStatus fCurrStatus;
+
+       private boolean fPageVisible;
+
+       /**
+        * Creates a <code>NewElementWizardPage</code>.
+        * 
+        * @param name
+        *            the wizard page's name
+        */
+       public NewElementWizardPage(String name) {
+               super(name);
+               fPageVisible = false;
+               fCurrStatus = new StatusInfo();
+       }
+
+       // ---- WizardPage ----------------
+
+       /*
+        * @see WizardPage#becomesVisible
+        */
+       public void setVisible(boolean visible) {
+               super.setVisible(visible);
+               fPageVisible = visible;
+               // policy: wizards are not allowed to come up with an error message
+               if (visible && fCurrStatus.matches(IStatus.ERROR)) {
+                       StatusInfo status = new StatusInfo();
+                       status.setError(""); //$NON-NLS-1$
+                       fCurrStatus = status;
+               }
+               updateStatus(fCurrStatus);
+       }
+
+       /**
+        * Updates the status line and the ok button according to the given status
+        * 
+        * @param status
+        *            status to apply
+        */
+       protected void updateStatus(IStatus status) {
+               fCurrStatus = status;
+               setPageComplete(!status.matches(IStatus.ERROR));
+               if (fPageVisible) {
+                       StatusUtil.applyToStatusLine(this, status);
+               }
+       }
+
+       /**
+        * Updates the status line and the ok button according to the status
+        * evaluate from an array of status. The most severe error is taken. In case
+        * that two status with the same severity exists, the status with lower
+        * index is taken.
+        * 
+        * @param status
+        *            the array of status
+        */
+       protected void updateStatus(IStatus[] status) {
+               updateStatus(StatusUtil.getMostSevere(status));
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewTypeWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/ui/wizards/NewTypeWizardPage.java
new file mode 100644 (file)
index 0000000..a73147a
--- /dev/null
@@ -0,0 +1,1954 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IBuffer;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.ToolFactory;
+import net.sourceforge.phpdt.core.compiler.IScanner;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.externaltools.internal.ui.StatusInfo;
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.corext.template.php.Templates;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.NewWizardMessages;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IListAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ListDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogFieldGroup;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.Separator;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringButtonStatusDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringDialogField;
+import net.sourceforge.phpdt.ui.CodeGeneration;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+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;
+
+/**
+ * The class <code>NewTypeWizardPage</code> contains controls and validation
+ * routines for a 'New Type WizardPage'. Implementors decide which components to
+ * add and to enable. Implementors can also customize the validation code.
+ * <code>NewTypeWizardPage</code> is intended to serve as base class of all
+ * wizards that create types like applets, servlets, classes, interfaces, etc.
+ * <p>
+ * See <code>NewClassWizardPage</code> or <code>NewInterfaceWizardPage</code>
+ * for an example usage of <code>NewTypeWizardPage</code>.
+ * </p>
+ * 
+ * @see net.sourceforge.phpdt.ui.wizards.NewClassWizardPage
+ * @see net.sourceforge.phpdt.ui.wizards.NewInterfaceWizardPage
+ * 
+ * @since 2.0
+ */
+public abstract class NewTypeWizardPage extends NewContainerWizardPage {
+
+       /**
+        * Class used in stub creation routines to add needed imports to a
+        * compilation unit.
+        */
+       // public static class ImportsManager {
+       //
+       // private IImportsStructure fImportsStructure;
+       //
+       // /* package */ ImportsManager(IImportsStructure structure) {
+       // fImportsStructure= structure;
+       // }
+       //
+       // /* package */ IImportsStructure getImportsStructure() {
+       // return fImportsStructure;
+       // }
+       //                              
+       // /**
+       // * Adds a new import declaration that is sorted in the existing imports.
+       // * If an import already exists or the import would conflict with another
+       // import
+       // * of an other type with the same simple name the import is not added.
+       // *
+       // * @param qualifiedTypeName The fully qualified name of the type to import
+       // * (dot separated)
+       // * @return Returns the simple type name that can be used in the code or
+       // the
+       // * fully qualified type name if an import conflict prevented the import
+       // */
+       // public String addImport(String qualifiedTypeName) {
+       // return fImportsStructure.addImport(qualifiedTypeName);
+       // }
+       // }
+       /**
+        * Public access flag. See The Java Virtual Machine Specification for more
+        * details.
+        */
+       public int F_PUBLIC = Flags.AccPublic;
+
+       /**
+        * Private access flag. See The Java Virtual Machine Specification for more
+        * details.
+        */
+       public int F_PRIVATE = Flags.AccPrivate;
+
+       /**
+        * Protected access flag. See The Java Virtual Machine Specification for
+        * more details.
+        */
+       public int F_PROTECTED = Flags.AccProtected;
+
+       /**
+        * Static access flag. See The Java Virtual Machine Specification for more
+        * details.
+        */
+       public int F_STATIC = Flags.AccStatic;
+
+       /**
+        * Final access flag. See The Java Virtual Machine Specification for more
+        * details.
+        */
+       public int F_FINAL = Flags.AccFinal;
+
+       /**
+        * Abstract property flag. See The Java Virtual Machine Specification for
+        * more details.
+        */
+       // public int F_ABSTRACT = Flags.AccAbstract;
+       private final static String PAGE_NAME = "NewTypeWizardPage"; //$NON-NLS-1$
+
+       /** Field ID of the package input field */
+       protected final static String PACKAGE = PAGE_NAME + ".package"; //$NON-NLS-1$
+
+       /** Field ID of the eclosing type input field */
+       protected final static String ENCLOSING = PAGE_NAME + ".enclosing"; //$NON-NLS-1$
+
+       /** Field ID of the enclosing type checkbox */
+       protected final static String ENCLOSINGSELECTION = ENCLOSING + ".selection"; //$NON-NLS-1$
+
+       /** Field ID of the type name input field */
+       protected final static String TYPENAME = PAGE_NAME + ".typename"; //$NON-NLS-1$
+
+       /** Field ID of the super type input field */
+       protected final static String SUPER = PAGE_NAME + ".superclass"; //$NON-NLS-1$
+
+       /** Field ID of the super interfaces input field */
+       protected final static String INTERFACES = PAGE_NAME + ".interfaces"; //$NON-NLS-1$
+
+       /** Field ID of the modifier checkboxes */
+       protected final static String MODIFIERS = PAGE_NAME + ".modifiers"; //$NON-NLS-1$
+
+       /** Field ID of the method stubs checkboxes */
+       protected final static String METHODS = PAGE_NAME + ".methods"; //$NON-NLS-1$
+
+       private class InterfacesListLabelProvider extends LabelProvider {
+
+               private Image fInterfaceImage;
+
+               public InterfacesListLabelProvider() {
+                       super();
+                       fInterfaceImage = PHPUiImages.get(PHPUiImages.IMG_OBJS_INTERFACE);
+               }
+
+               public Image getImage(Object element) {
+                       return fInterfaceImage;
+               }
+       }
+
+       private StringButtonStatusDialogField fPackageDialogField;
+
+       private SelectionButtonDialogField fEnclosingTypeSelection;
+
+       private StringButtonDialogField fEnclosingTypeDialogField;
+
+       private boolean fCanModifyPackage;
+
+       private boolean fCanModifyEnclosingType;
+
+       private IPackageFragment fCurrPackage;
+
+       // private IType fCurrEnclosingType;
+       private StringDialogField fTypeNameDialogField;
+
+       private StringButtonDialogField fSuperClassDialogField;
+
+       private ListDialogField fSuperInterfacesDialogField;
+
+       // private IType fSuperClass;
+
+       private SelectionButtonDialogFieldGroup fAccMdfButtons;
+
+       private SelectionButtonDialogFieldGroup fOtherMdfButtons;
+
+       private IType fCreatedType;
+
+       protected IStatus fEnclosingTypeStatus;
+
+       protected IStatus fPackageStatus;
+
+       protected IStatus fTypeNameStatus;
+
+       // protected IStatus fSuperClassStatus;
+       protected IStatus fModifierStatus;
+
+       // protected IStatus fSuperInterfacesStatus;
+
+       private boolean fIsClass;
+
+       private int fStaticMdfIndex;
+
+       private final int PUBLIC_INDEX = 0, DEFAULT_INDEX = 1, PRIVATE_INDEX = 2,
+                       PROTECTED_INDEX = 3;
+
+       private final int ABSTRACT_INDEX = 0, FINAL_INDEX = 1;
+
+       /**
+        * Creates a new <code>NewTypeWizardPage</code>
+        * 
+        * @param isClass
+        *            <code>true</code> if a new class is to be created; otherwise
+        *            an interface is to be created
+        * @param pageName
+        *            the wizard page's name
+        */
+       public NewTypeWizardPage(boolean isClass, String pageName) {
+               super(pageName);
+               fCreatedType = null;
+
+               fIsClass = isClass;
+
+               TypeFieldsAdapter adapter = new TypeFieldsAdapter();
+
+               fPackageDialogField = new StringButtonStatusDialogField(adapter);
+               fPackageDialogField.setDialogFieldListener(adapter);
+               fPackageDialogField.setLabelText(NewWizardMessages
+                               .getString("NewTypeWizardPage.package.label")); //$NON-NLS-1$
+               fPackageDialogField.setButtonLabel(NewWizardMessages
+                               .getString("NewTypeWizardPage.package.button")); //$NON-NLS-1$
+               fPackageDialogField.setStatusWidthHint(NewWizardMessages
+                               .getString("NewTypeWizardPage.default")); //$NON-NLS-1$
+
+               fEnclosingTypeSelection = new SelectionButtonDialogField(SWT.CHECK);
+               fEnclosingTypeSelection.setDialogFieldListener(adapter);
+               fEnclosingTypeSelection.setLabelText(NewWizardMessages
+                               .getString("NewTypeWizardPage.enclosing.selection.label")); //$NON-NLS-1$
+
+               fEnclosingTypeDialogField = new StringButtonDialogField(adapter);
+               fEnclosingTypeDialogField.setDialogFieldListener(adapter);
+               fEnclosingTypeDialogField.setButtonLabel(NewWizardMessages
+                               .getString("NewTypeWizardPage.enclosing.button")); //$NON-NLS-1$
+
+               fTypeNameDialogField = new StringDialogField();
+               fTypeNameDialogField.setDialogFieldListener(adapter);
+               fTypeNameDialogField.setLabelText(NewWizardMessages
+                               .getString("NewTypeWizardPage.typename.label")); //$NON-NLS-1$
+
+               fSuperClassDialogField = new StringButtonDialogField(adapter);
+               fSuperClassDialogField.setDialogFieldListener(adapter);
+               fSuperClassDialogField.setLabelText(NewWizardMessages
+                               .getString("NewTypeWizardPage.superclass.label")); //$NON-NLS-1$
+               fSuperClassDialogField.setButtonLabel(NewWizardMessages
+                               .getString("NewTypeWizardPage.superclass.button")); //$NON-NLS-1$
+
+               String[] addButtons = new String[] {
+                               /* 0 */
+                               NewWizardMessages.getString("NewTypeWizardPage.interfaces.add"), //$NON-NLS-1$
+                               /* 1 */
+                               null,
+                               /* 2 */
+                               NewWizardMessages
+                                               .getString("NewTypeWizardPage.interfaces.remove") //$NON-NLS-1$
+               };
+               fSuperInterfacesDialogField = new ListDialogField(adapter, addButtons,
+                               new InterfacesListLabelProvider());
+               fSuperInterfacesDialogField.setDialogFieldListener(adapter);
+               String interfaceLabel = fIsClass ? NewWizardMessages
+                               .getString("NewTypeWizardPage.interfaces.class.label") : NewWizardMessages.getString("NewTypeWizardPage.interfaces.ifc.label"); //$NON-NLS-1$ //$NON-NLS-2$
+               fSuperInterfacesDialogField.setLabelText(interfaceLabel);
+               fSuperInterfacesDialogField.setRemoveButtonIndex(2);
+
+               String[] buttonNames1 = new String[] {
+                               /* 0 == PUBLIC_INDEX */
+                               NewWizardMessages
+                                               .getString("NewTypeWizardPage.modifiers.public"), //$NON-NLS-1$
+                               /* 1 == DEFAULT_INDEX */
+                               NewWizardMessages
+                                               .getString("NewTypeWizardPage.modifiers.default"), //$NON-NLS-1$
+                               /* 2 == PRIVATE_INDEX */
+                               NewWizardMessages
+                                               .getString("NewTypeWizardPage.modifiers.private"), //$NON-NLS-1$
+                               /* 3 == PROTECTED_INDEX */
+                               NewWizardMessages
+                                               .getString("NewTypeWizardPage.modifiers.protected") //$NON-NLS-1$
+               };
+               fAccMdfButtons = new SelectionButtonDialogFieldGroup(SWT.RADIO,
+                               buttonNames1, 4);
+               fAccMdfButtons.setDialogFieldListener(adapter);
+               fAccMdfButtons.setLabelText(NewWizardMessages
+                               .getString("NewTypeWizardPage.modifiers.acc.label")); //$NON-NLS-1$
+               fAccMdfButtons.setSelection(0, true);
+
+               String[] buttonNames2;
+               if (fIsClass) {
+                       buttonNames2 = new String[] {
+                                       /* 0 == ABSTRACT_INDEX */
+                                       NewWizardMessages
+                                                       .getString("NewTypeWizardPage.modifiers.abstract"), //$NON-NLS-1$
+                                       /* 1 == FINAL_INDEX */
+                                       NewWizardMessages
+                                                       .getString("NewTypeWizardPage.modifiers.final"), //$NON-NLS-1$
+                                       /* 2 */
+                                       NewWizardMessages
+                                                       .getString("NewTypeWizardPage.modifiers.static") //$NON-NLS-1$
+                       };
+                       fStaticMdfIndex = 2; // index of the static checkbox is 2
+               } else {
+                       buttonNames2 = new String[] { NewWizardMessages
+                                       .getString("NewTypeWizardPage.modifiers.static") //$NON-NLS-1$
+                       };
+                       fStaticMdfIndex = 0; // index of the static checkbox is 0
+               }
+
+               fOtherMdfButtons = new SelectionButtonDialogFieldGroup(SWT.CHECK,
+                               buttonNames2, 4);
+               fOtherMdfButtons.setDialogFieldListener(adapter);
+
+               fAccMdfButtons.enableSelectionButton(PRIVATE_INDEX, false);
+               fAccMdfButtons.enableSelectionButton(PROTECTED_INDEX, false);
+               fOtherMdfButtons.enableSelectionButton(fStaticMdfIndex, false);
+
+               fPackageStatus = new StatusInfo();
+               fEnclosingTypeStatus = new StatusInfo();
+
+               fCanModifyPackage = true;
+               fCanModifyEnclosingType = true;
+               updateEnableState();
+
+               fTypeNameStatus = new StatusInfo();
+               // fSuperClassStatus= new StatusInfo();
+               // fSuperInterfacesStatus= new StatusInfo();
+               fModifierStatus = new StatusInfo();
+       }
+
+       /**
+        * Initializes all fields provided by the page with a given selection.
+        * 
+        * @param elem
+        *            the selection used to intialize this page or <code>
+        * null</code>
+        *            if no selection was available
+        */
+       protected void initTypePage(IJavaElement elem) {
+               String initSuperclass = "java.lang.Object"; //$NON-NLS-1$
+               ArrayList initSuperinterfaces = new ArrayList(5);
+
+               IPackageFragment pack = null;
+               IType enclosingType = null;
+
+               if (elem != null) {
+                       // evaluate the enclosing type
+                       pack = (IPackageFragment) elem
+                                       .getAncestor(IJavaElement.PACKAGE_FRAGMENT);
+                       IType typeInCU = (IType) elem.getAncestor(IJavaElement.TYPE);
+                       if (typeInCU != null) {
+                               if (typeInCU.getCompilationUnit() != null) {
+                                       enclosingType = typeInCU;
+                               }
+                       } else {
+                               ICompilationUnit cu = (ICompilationUnit) elem
+                                               .getAncestor(IJavaElement.COMPILATION_UNIT);
+                               if (cu != null) {
+                                       // enclosingType= cu.findPrimaryType();
+                               }
+                       }
+
+                       // try {
+                       // IType type= null;
+                       // if (elem.getElementType() == IJavaElement.TYPE) {
+                       // type= (IType)elem;
+                       // if (type.exists()) {
+                       // String superName= JavaModelUtil.getFullyQualifiedName(type);
+                       // if (type.isInterface()) {
+                       // initSuperinterfaces.add(superName);
+                       // } else {
+                       // initSuperclass= superName;
+                       // }
+                       // }
+                       // }
+                       // } catch (JavaModelException e) {
+                       // PHPeclipsePlugin.log(e);
+                       // // ignore this exception now
+                       // }
+               }
+
+               setPackageFragment(pack, true);
+               // setEnclosingType(enclosingType, true);
+               setEnclosingTypeSelection(false, true);
+
+               setTypeName("", true); //$NON-NLS-1$
+               setSuperClass(initSuperclass, true);
+               setSuperInterfaces(initSuperinterfaces, true);
+       }
+
+       // -------- UI Creation ---------
+
+       /**
+        * Creates a separator line. Expects a <code>GridLayout</code> with at
+        * least 1 column.
+        * 
+        * @param composite
+        *            the parent composite
+        * @param nColumns
+        *            number of columns to span
+        */
+       protected void createSeparator(Composite composite, int nColumns) {
+               (new Separator(SWT.SEPARATOR | SWT.HORIZONTAL)).doFillIntoGrid(
+                               composite, nColumns, convertHeightInCharsToPixels(1));
+       }
+
+       /**
+        * Creates the controls for the package name field. Expects a
+        * <code>GridLayout</code> with at least 4 columns.
+        * 
+        * @param composite
+        *            the parent composite
+        * @param nColumns
+        *            number of columns to span
+        */
+       protected void createPackageControls(Composite composite, int nColumns) {
+               fPackageDialogField.doFillIntoGrid(composite, nColumns);
+               LayoutUtil.setWidthHint(fPackageDialogField.getTextControl(null),
+                               getMaxFieldWidth());
+               LayoutUtil.setHorizontalGrabbing(fPackageDialogField
+                               .getTextControl(null));
+       }
+
+       /**
+        * Creates the controls for the enclosing type name field. Expects a
+        * <code>GridLayout</code> with at least 4 columns.
+        * 
+        * @param composite
+        *            the parent composite
+        * @param nColumns
+        *            number of columns to span
+        */
+       protected void createEnclosingTypeControls(Composite composite, int nColumns) {
+               // #6891
+               Composite tabGroup = new Composite(composite, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.marginWidth = 0;
+               layout.marginHeight = 0;
+               tabGroup.setLayout(layout);
+
+               fEnclosingTypeSelection.doFillIntoGrid(tabGroup, 1);
+
+               Control c = fEnclosingTypeDialogField.getTextControl(composite);
+               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.widthHint = getMaxFieldWidth();
+               gd.horizontalSpan = 2;
+               c.setLayoutData(gd);
+
+               Button button = fEnclosingTypeDialogField.getChangeControl(composite);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.heightHint = SWTUtil.getButtonHeightHint(button);
+               gd.widthHint = SWTUtil.getButtonWidthHint(button);
+               button.setLayoutData(gd);
+       }
+
+       /**
+        * Creates the controls for the type name field. Expects a
+        * <code>GridLayout</code> with at least 2 columns.
+        * 
+        * @param composite
+        *            the parent composite
+        * @param nColumns
+        *            number of columns to span
+        */
+       protected void createTypeNameControls(Composite composite, int nColumns) {
+               fTypeNameDialogField.doFillIntoGrid(composite, nColumns - 1);
+               DialogField.createEmptySpace(composite);
+
+               LayoutUtil.setWidthHint(fTypeNameDialogField.getTextControl(null),
+                               getMaxFieldWidth());
+       }
+
+       /**
+        * Creates the controls for the modifiers radio/ceckbox buttons. Expects a
+        * <code>GridLayout</code> with at least 3 columns.
+        * 
+        * @param composite
+        *            the parent composite
+        * @param nColumns
+        *            number of columns to span
+        */
+       protected void createModifierControls(Composite composite, int nColumns) {
+               LayoutUtil.setHorizontalSpan(fAccMdfButtons.getLabelControl(composite),
+                               1);
+
+               Control control = fAccMdfButtons.getSelectionButtonsGroup(composite);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = nColumns - 2;
+               control.setLayoutData(gd);
+
+               DialogField.createEmptySpace(composite);
+
+               DialogField.createEmptySpace(composite);
+
+               control = fOtherMdfButtons.getSelectionButtonsGroup(composite);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan = nColumns - 2;
+               control.setLayoutData(gd);
+
+               DialogField.createEmptySpace(composite);
+       }
+
+       /**
+        * Creates the controls for the superclass name field. Expects a
+        * <code>GridLayout</code> with at least 3 columns.
+        * 
+        * @param composite
+        *            the parent composite
+        * @param nColumns
+        *            number of columns to span
+        */
+       protected void createSuperClassControls(Composite composite, int nColumns) {
+               fSuperClassDialogField.doFillIntoGrid(composite, nColumns);
+               LayoutUtil.setWidthHint(fSuperClassDialogField.getTextControl(null),
+                               getMaxFieldWidth());
+       }
+
+       /**
+        * Creates the controls for the superclass name field. Expects a
+        * <code>GridLayout</code> with at least 3 columns.
+        * 
+        * @param composite
+        *            the parent composite
+        * @param nColumns
+        *            number of columns to span
+        */
+       protected void createSuperInterfacesControls(Composite composite,
+                       int nColumns) {
+               fSuperInterfacesDialogField.doFillIntoGrid(composite, nColumns);
+               GridData gd = (GridData) fSuperInterfacesDialogField.getListControl(
+                               null).getLayoutData();
+               if (fIsClass) {
+                       gd.heightHint = convertHeightInCharsToPixels(3);
+               } else {
+                       gd.heightHint = convertHeightInCharsToPixels(6);
+               }
+               gd.grabExcessVerticalSpace = false;
+               gd.widthHint = getMaxFieldWidth();
+       }
+
+       /**
+        * Sets the focus on the type name input field.
+        */
+       protected void setFocus() {
+               fTypeNameDialogField.setFocus();
+       }
+
+       // -------- TypeFieldsAdapter --------
+
+       private class TypeFieldsAdapter implements IStringButtonAdapter,
+                       IDialogFieldListener, IListAdapter {
+
+               // -------- IStringButtonAdapter
+               public void changeControlPressed(DialogField field) {
+                       // typePageChangeControlPressed(field);
+               }
+
+               // -------- IListAdapter
+               public void customButtonPressed(ListDialogField field, int index) {
+                       // typePageCustomButtonPressed(field, index);
+               }
+
+               public void selectionChanged(ListDialogField field) {
+               }
+
+               // -------- IDialogFieldListener
+               public void dialogFieldChanged(DialogField field) {
+                       typePageDialogFieldChanged(field);
+               }
+
+               public void doubleClicked(ListDialogField field) {
+               }
+       }
+
+       // private void typePageChangeControlPressed(DialogField field) {
+       // if (field == fPackageDialogField) {
+       // IPackageFragment pack= choosePackage();
+       // if (pack != null) {
+       // fPackageDialogField.setText(pack.getElementName());
+       // }
+       // } else if (field == fEnclosingTypeDialogField) {
+       // IType type= chooseEnclosingType();
+       // if (type != null) {
+       // fEnclosingTypeDialogField.setText(JavaModelUtil.getFullyQualifiedName(type));
+       // }
+       // } else if (field == fSuperClassDialogField) {
+       // IType type= chooseSuperType();
+       // if (type != null) {
+       // fSuperClassDialogField.setText(JavaModelUtil.getFullyQualifiedName(type));
+       // }
+       // }
+       // }
+
+       // private void typePageCustomButtonPressed(DialogField field, int index) {
+       // if (field == fSuperInterfacesDialogField) {
+       // chooseSuperInterfaces();
+       // }
+       // }
+
+       /*
+        * A field on the type has changed. The fields' status and all dependend
+        * status are updated.
+        */
+       private void typePageDialogFieldChanged(DialogField field) {
+               String fieldName = null;
+               if (field == fPackageDialogField) {
+                       fPackageStatus = packageChanged();
+                       updatePackageStatusLabel();
+                       fTypeNameStatus = typeNameChanged();
+                       // fSuperClassStatus= superClassChanged();
+                       fieldName = PACKAGE;
+               } else if (field == fEnclosingTypeDialogField) {
+                       // fEnclosingTypeStatus= enclosingTypeChanged();
+                       fTypeNameStatus = typeNameChanged();
+                       // fSuperClassStatus= superClassChanged();
+                       fieldName = ENCLOSING;
+               } else if (field == fEnclosingTypeSelection) {
+                       updateEnableState();
+                       boolean isEnclosedType = isEnclosingTypeSelected();
+                       if (!isEnclosedType) {
+                               if (fAccMdfButtons.isSelected(PRIVATE_INDEX)
+                                               || fAccMdfButtons.isSelected(PROTECTED_INDEX)) {
+                                       fAccMdfButtons.setSelection(PRIVATE_INDEX, false);
+                                       fAccMdfButtons.setSelection(PROTECTED_INDEX, false);
+                                       fAccMdfButtons.setSelection(PUBLIC_INDEX, true);
+                               }
+                               if (fOtherMdfButtons.isSelected(fStaticMdfIndex)) {
+                                       fOtherMdfButtons.setSelection(fStaticMdfIndex, false);
+                               }
+                       }
+                       fAccMdfButtons.enableSelectionButton(PRIVATE_INDEX, isEnclosedType
+                                       && fIsClass);
+                       fAccMdfButtons.enableSelectionButton(PROTECTED_INDEX,
+                                       isEnclosedType && fIsClass);
+                       fOtherMdfButtons.enableSelectionButton(fStaticMdfIndex,
+                                       isEnclosedType);
+                       fTypeNameStatus = typeNameChanged();
+                       // fSuperClassStatus= superClassChanged();
+                       fieldName = ENCLOSINGSELECTION;
+               } else if (field == fTypeNameDialogField) {
+                       fTypeNameStatus = typeNameChanged();
+                       fieldName = TYPENAME;
+               } else if (field == fSuperClassDialogField) {
+                       // fSuperClassStatus= superClassChanged();
+                       fieldName = SUPER;
+               } else if (field == fSuperInterfacesDialogField) {
+                       // fSuperInterfacesStatus= superInterfacesChanged();
+                       fieldName = INTERFACES;
+               } else if (field == fOtherMdfButtons) {
+                       fModifierStatus = modifiersChanged();
+                       fieldName = MODIFIERS;
+               } else {
+                       fieldName = METHODS;
+               }
+               // tell all others
+               handleFieldChanged(fieldName);
+       }
+
+       // -------- update message ----------------
+
+       /*
+        * @see net.sourceforge.phpdt.ui.wizards.NewContainerWizardPage#handleFieldChanged(String)
+        */
+       protected void handleFieldChanged(String fieldName) {
+               super.handleFieldChanged(fieldName);
+               if (fieldName == CONTAINER) {
+                       fPackageStatus = packageChanged();
+                       // fEnclosingTypeStatus= enclosingTypeChanged();
+                       fTypeNameStatus = typeNameChanged();
+                       // fSuperClassStatus= superClassChanged();
+                       // fSuperInterfacesStatus= superInterfacesChanged();
+               }
+       }
+
+       // ---- set / get ----------------
+
+       /**
+        * Returns the text of the package input field.
+        * 
+        * @return the text of the package input field
+        */
+       public String getPackageText() {
+               return fPackageDialogField.getText();
+       }
+
+       /**
+        * Returns the text of the enclosing type input field.
+        * 
+        * @return the text of the enclosing type input field
+        */
+       public String getEnclosingTypeText() {
+               return fEnclosingTypeDialogField.getText();
+       }
+
+       /**
+        * Returns the package fragment corresponding to the current input.
+        * 
+        * @return a package fragement or <code>null</code> if the input could not
+        *         be resolved.
+        */
+       public IPackageFragment getPackageFragment() {
+               if (!isEnclosingTypeSelected()) {
+                       return fCurrPackage;
+               } else {
+                       // if (fCurrEnclosingType != null) {
+                       // return fCurrEnclosingType.getPackageFragment();
+                       // }
+               }
+               return null;
+       }
+
+       /**
+        * Sets the package fragment to the given value. The method updates the
+        * model and the text of the control.
+        * 
+        * @param pack
+        *            the package fragement to be set
+        * @param canBeModified
+        *            if <code>true</code> the package fragment is editable;
+        *            otherwise it is read-only.
+        */
+       public void setPackageFragment(IPackageFragment pack, boolean canBeModified) {
+               fCurrPackage = pack;
+               fCanModifyPackage = canBeModified;
+               String str = (pack == null) ? "" : pack.getElementName(); //$NON-NLS-1$
+               fPackageDialogField.setText(str);
+               updateEnableState();
+       }
+
+       /**
+        * Returns the enclosing type corresponding to the current input.
+        * 
+        * @return the enclosing type or <code>null</code> if the enclosing type
+        *         is not selected or the input could not be resolved
+        */
+       public IType getEnclosingType() {
+               // if (isEnclosingTypeSelected()) {
+               // return fCurrEnclosingType;
+               // }
+               return null;
+       }
+
+       /**
+        * Sets the enclosing type. The method updates the underlying model and the
+        * text of the control.
+        * 
+        * @param type
+        *            the enclosing type
+        * @param canBeModified
+        *            if <code>true</code> the enclosing type field is editable;
+        *            otherwise it is read-only.
+        */
+       // public void setEnclosingType(IType type, boolean canBeModified) {
+       // fCurrEnclosingType= type;
+       // fCanModifyEnclosingType= canBeModified;
+       // String str= (type == null) ? "" :
+       // JavaModelUtil.getFullyQualifiedName(type); //$NON-NLS-1$
+       // fEnclosingTypeDialogField.setText(str);
+       // updateEnableState();
+       // }
+       /**
+        * Returns the selection state of the enclosing type checkbox.
+        * 
+        * @return the seleciton state of the enclosing type checkbox
+        */
+       public boolean isEnclosingTypeSelected() {
+               return fEnclosingTypeSelection.isSelected();
+       }
+
+       /**
+        * Sets the enclosing type checkbox's selection state.
+        * 
+        * @param isSelected
+        *            the checkbox's selection state
+        * @param canBeModified
+        *            if <code>true</code> the enclosing type checkbox is
+        *            modifiable; otherwise it is read-only.
+        */
+       public void setEnclosingTypeSelection(boolean isSelected,
+                       boolean canBeModified) {
+               fEnclosingTypeSelection.setSelection(isSelected);
+               fEnclosingTypeSelection.setEnabled(canBeModified);
+               updateEnableState();
+       }
+
+       /**
+        * Returns the type name entered into the type input field.
+        * 
+        * @return the type name
+        */
+       public String getTypeName() {
+               return fTypeNameDialogField.getText();
+       }
+
+       /**
+        * Sets the type name input field's text to the given value. Method doesn't
+        * update the model.
+        * 
+        * @param name
+        *            the new type name
+        * @param canBeModified
+        *            if <code>true</code> the enclosing type name field is
+        *            editable; otherwise it is read-only.
+        */
+       public void setTypeName(String name, boolean canBeModified) {
+               fTypeNameDialogField.setText(name);
+               fTypeNameDialogField.setEnabled(canBeModified);
+       }
+
+       /**
+        * Returns the selected modifiers.
+        * 
+        * @return the selected modifiers
+        * @see Flags
+        */
+       public int getModifiers() {
+               int mdf = 0;
+               if (fAccMdfButtons.isSelected(PUBLIC_INDEX)) {
+                       mdf += F_PUBLIC;
+               } else if (fAccMdfButtons.isSelected(PRIVATE_INDEX)) {
+                       mdf += F_PRIVATE;
+               } else if (fAccMdfButtons.isSelected(PROTECTED_INDEX)) {
+                       mdf += F_PROTECTED;
+               }
+               // if (fOtherMdfButtons.isSelected(ABSTRACT_INDEX) && (fStaticMdfIndex
+               // != 0)) {
+               // mdf+= F_ABSTRACT;
+               // }
+               if (fOtherMdfButtons.isSelected(FINAL_INDEX)) {
+                       mdf += F_FINAL;
+               }
+               if (fOtherMdfButtons.isSelected(fStaticMdfIndex)) {
+                       mdf += F_STATIC;
+               }
+               return mdf;
+       }
+
+       /**
+        * Sets the modifiers.
+        * 
+        * @param modifiers
+        *            <code>F_PUBLIC</code>, <code>F_PRIVATE</code>,
+        *            <code>F_PROTECTED</code>, <code>F_ABSTRACT, F_FINAL</code>
+        *            or <code>F_STATIC</code> or, a valid combination.
+        * @param canBeModified
+        *            if <code>true</code> the modifier fields are editable;
+        *            otherwise they are read-only
+        * @see Flags
+        */
+       public void setModifiers(int modifiers, boolean canBeModified) {
+               if (Flags.isPublic(modifiers)) {
+                       fAccMdfButtons.setSelection(PUBLIC_INDEX, true);
+               } else if (Flags.isPrivate(modifiers)) {
+                       fAccMdfButtons.setSelection(PRIVATE_INDEX, true);
+               } else if (Flags.isProtected(modifiers)) {
+                       fAccMdfButtons.setSelection(PROTECTED_INDEX, true);
+               } else {
+                       fAccMdfButtons.setSelection(DEFAULT_INDEX, true);
+               }
+               // if (Flags.isAbstract(modifiers)) {
+               // fOtherMdfButtons.setSelection(ABSTRACT_INDEX, true);
+               // }
+               if (Flags.isFinal(modifiers)) {
+                       fOtherMdfButtons.setSelection(FINAL_INDEX, true);
+               }
+               if (Flags.isStatic(modifiers)) {
+                       fOtherMdfButtons.setSelection(fStaticMdfIndex, true);
+               }
+
+               fAccMdfButtons.setEnabled(canBeModified);
+               fOtherMdfButtons.setEnabled(canBeModified);
+       }
+
+       /**
+        * Returns the content of the superclass input field.
+        * 
+        * @return the superclass name
+        */
+       public String getSuperClass() {
+               return fSuperClassDialogField.getText();
+       }
+
+       /**
+        * Sets the super class name.
+        * 
+        * @param name
+        *            the new superclass name
+        * @param canBeModified
+        *            if <code>true</code> the superclass name field is editable;
+        *            otherwise it is read-only.
+        */
+       public void setSuperClass(String name, boolean canBeModified) {
+               fSuperClassDialogField.setText(name);
+               fSuperClassDialogField.setEnabled(canBeModified);
+       }
+
+       /**
+        * Returns the chosen super interfaces.
+        * 
+        * @return a list of chosen super interfaces. The list's elements are of
+        *         type <code>String</code>
+        */
+       public List getSuperInterfaces() {
+               return fSuperInterfacesDialogField.getElements();
+       }
+
+       /**
+        * Sets the super interfaces.
+        * 
+        * @param interfacesNames
+        *            a list of super interface. The method requires that the list's
+        *            elements are of type <code>String</code>
+        * @param canBeModified
+        *            if <code>true</code> the super interface field is editable;
+        *            otherwise it is read-only.
+        */
+       public void setSuperInterfaces(List interfacesNames, boolean canBeModified) {
+               fSuperInterfacesDialogField.setElements(interfacesNames);
+               fSuperInterfacesDialogField.setEnabled(canBeModified);
+       }
+
+       // ----------- validation ----------
+
+       /**
+        * A hook method that gets called when the package field has changed. The
+        * method validates the package name and returns the status of the
+        * validation. The validation also updates the package fragment model.
+        * <p>
+        * Subclasses may extend this method to perform their own validation.
+        * </p>
+        * 
+        * @return the status of the validation
+        */
+       protected IStatus packageChanged() {
+               StatusInfo status = new StatusInfo();
+               fPackageDialogField.enableButton(getPackageFragmentRoot() != null);
+
+               // String packName= getPackageText();
+               // if (packName.length() > 0) {
+               // IStatus val= JavaConventions.validatePackageName(packName);
+               // if (val.getSeverity() == IStatus.ERROR) {
+               // status.setError(NewWizardMessages.getFormattedString("NewTypeWizardPage.error.InvalidPackageName",
+               // val.getMessage())); //$NON-NLS-1$
+               // return status;
+               // } else if (val.getSeverity() == IStatus.WARNING) {
+               // status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.DiscouragedPackageName",
+               // val.getMessage())); //$NON-NLS-1$
+               // // continue
+               // }
+               // }
+
+               // IPackageFragmentRoot root= getPackageFragmentRoot();
+               // if (root != null) {
+               // if (root.getJavaProject().exists() && packName.length() > 0) {
+               // try {
+               // IPath rootPath= root.getPath();
+               // IPath outputPath= root.getJavaProject().getOutputLocation();
+               // if (rootPath.isPrefixOf(outputPath) && !rootPath.equals(outputPath))
+               // {
+               // // if the bin folder is inside of our root, dont allow to name a
+               // package
+               // // like the bin folder
+               // IPath packagePath= rootPath.append(packName.replace('.', '/'));
+               // if (outputPath.isPrefixOf(packagePath)) {
+               // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.ClashOutputLocation"));
+               // //$NON-NLS-1$
+               // return status;
+               // }
+               // }
+               // } catch (JavaModelException e) {
+               // PHPeclipsePlugin.log(e);
+               // // let pass
+               // }
+               // }
+               //                      
+               // fCurrPackage= root.getPackageFragment(packName);
+               // } else {
+               // status.setError(""); //$NON-NLS-1$
+               // }
+               return status;
+       }
+
+       /*
+        * Updates the 'default' label next to the package field.
+        */
+       private void updatePackageStatusLabel() {
+               String packName = getPackageText();
+
+               if (packName.length() == 0) {
+                       fPackageDialogField.setStatus(NewWizardMessages
+                                       .getString("NewTypeWizardPage.default")); //$NON-NLS-1$
+               } else {
+                       fPackageDialogField.setStatus(""); //$NON-NLS-1$
+               }
+       }
+
+       /*
+        * Updates the enable state of buttons related to the enclosing type
+        * selection checkbox.
+        */
+       private void updateEnableState() {
+               boolean enclosing = isEnclosingTypeSelected();
+               fPackageDialogField.setEnabled(fCanModifyPackage && !enclosing);
+               fEnclosingTypeDialogField.setEnabled(fCanModifyEnclosingType
+                               && enclosing);
+       }
+
+       /**
+        * Hook method that gets called when the enclosing type name has changed.
+        * The method validates the enclosing type and returns the status of the
+        * validation. It also updates the enclosing type model.
+        * <p>
+        * Subclasses may extend this method to perform their own validation.
+        * </p>
+        * 
+        * @return the status of the validation
+        */
+       // protected IStatus enclosingTypeChanged() {
+       // StatusInfo status= new StatusInfo();
+       // fCurrEnclosingType= null;
+       //              
+       // IPackageFragmentRoot root= getPackageFragmentRoot();
+       //              
+       // fEnclosingTypeDialogField.enableButton(root != null);
+       // if (root == null) {
+       // status.setError(""); //$NON-NLS-1$
+       // return status;
+       // }
+       //              
+       // String enclName= getEnclosingTypeText();
+       // if (enclName.length() == 0) {
+       // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingTypeEnterName"));
+       // //$NON-NLS-1$
+       // return status;
+       // }
+       // try {
+       // IType type= findType(root.getJavaProject(), enclName);
+       // if (type == null) {
+       // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingTypeNotExists"));
+       // //$NON-NLS-1$
+       // return status;
+       // }
+       //
+       // if (type.getCompilationUnit() == null) {
+       // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingNotInCU"));
+       // //$NON-NLS-1$
+       // return status;
+       // }
+       // if (!JavaModelUtil.isEditable(type.getCompilationUnit())) {
+       // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingNotEditable"));
+       // //$NON-NLS-1$
+       // return status;
+       // }
+       //                      
+       // fCurrEnclosingType= type;
+       // IPackageFragmentRoot enclosingRoot=
+       // JavaModelUtil.getPackageFragmentRoot(type);
+       // if (!enclosingRoot.equals(root)) {
+       // status.setWarning(NewWizardMessages.getString("NewTypeWizardPage.warning.EnclosingNotInSourceFolder"));
+       // //$NON-NLS-1$
+       // }
+       // return status;
+       // } catch (JavaModelException e) {
+       // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingTypeNotExists"));
+       // //$NON-NLS-1$
+       // PHPeclipsePlugin.log(e);
+       // return status;
+       // }
+       // }
+       /**
+        * Hook method that gets called when the type name has changed. The method
+        * validates the type name and returns the status of the validation.
+        * <p>
+        * Subclasses may extend this method to perform their own validation.
+        * </p>
+        * 
+        * @return the status of the validation
+        */
+       protected IStatus typeNameChanged() {
+               StatusInfo status = new StatusInfo();
+               String typeName = getTypeName();
+               // must not be empty
+               if (typeName.length() == 0) {
+                       status.setError(NewWizardMessages
+                                       .getString("NewTypeWizardPage.error.EnterTypeName")); //$NON-NLS-1$
+                       return status;
+               }
+               if (typeName.indexOf('.') != -1) {
+                       status.setError(NewWizardMessages
+                                       .getString("NewTypeWizardPage.error.QualifiedName")); //$NON-NLS-1$
+                       return status;
+               }
+               // IStatus val= JavaConventions.validateJavaTypeName(typeName);
+               // if (val.getSeverity() == IStatus.ERROR) {
+               // status.setError(NewWizardMessages.getFormattedString("NewTypeWizardPage.error.InvalidTypeName",
+               // val.getMessage())); //$NON-NLS-1$
+               // return status;
+               // } else if (val.getSeverity() == IStatus.WARNING) {
+               // status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.TypeNameDiscouraged",
+               // val.getMessage())); //$NON-NLS-1$
+               // // continue checking
+               // }
+
+               // must not exist
+               if (!isEnclosingTypeSelected()) {
+                       IPackageFragment pack = getPackageFragment();
+                       if (pack != null) {
+                               ICompilationUnit cu = pack.getCompilationUnit(typeName
+                                               + ".java"); //$NON-NLS-1$
+                               if (cu.getResource().exists()) {
+                                       status
+                                                       .setError(NewWizardMessages
+                                                                       .getString("NewTypeWizardPage.error.TypeNameExists")); //$NON-NLS-1$
+                                       return status;
+                               }
+                       }
+               } else {
+                       IType type = getEnclosingType();
+                       if (type != null) {
+                               IType member = type.getType(typeName);
+                               if (member.exists()) {
+                                       status
+                                                       .setError(NewWizardMessages
+                                                                       .getString("NewTypeWizardPage.error.TypeNameExists")); //$NON-NLS-1$
+                                       return status;
+                               }
+                       }
+               }
+               return status;
+       }
+
+       /**
+        * Hook method that gets called when the superclass name has changed. The
+        * method validates the superclass name and returns the status of the
+        * validation.
+        * <p>
+        * Subclasses may extend this method to perform their own validation.
+        * </p>
+        * 
+        * @return the status of the validation
+        */
+       // protected IStatus superClassChanged() {
+       // StatusInfo status= new StatusInfo();
+       // IPackageFragmentRoot root= getPackageFragmentRoot();
+       // fSuperClassDialogField.enableButton(root != null);
+       //              
+       // fSuperClass= null;
+       //              
+       // String sclassName= getSuperClass();
+       // if (sclassName.length() == 0) {
+       // // accept the empty field (stands for java.lang.Object)
+       // return status;
+       // }
+       // IStatus val= JavaConventions.validateJavaTypeName(sclassName);
+       // if (val.getSeverity() == IStatus.ERROR) {
+       // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.InvalidSuperClassName"));
+       // //$NON-NLS-1$
+       // return status;
+       // }
+       // if (root != null) {
+       // try {
+       // IType type= resolveSuperTypeName(root.getJavaProject(), sclassName);
+       // if (type == null) {
+       // status.setWarning(NewWizardMessages.getString("NewTypeWizardPage.warning.SuperClassNotExists"));
+       // //$NON-NLS-1$
+       // return status;
+       // } else {
+       // if (type.isInterface()) {
+       // status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.SuperClassIsNotClass",
+       // sclassName)); //$NON-NLS-1$
+       // return status;
+       // }
+       // int flags= type.getFlags();
+       // if (Flags.isFinal(flags)) {
+       // status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.SuperClassIsFinal",
+       // sclassName)); //$NON-NLS-1$
+       // return status;
+       // } else if (!JavaModelUtil.isVisible(type, getPackageFragment())) {
+       // status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.SuperClassIsNotVisible",
+       // sclassName)); //$NON-NLS-1$
+       // return status;
+       // }
+       // }
+       // fSuperClass= type;
+       // } catch (JavaModelException e) {
+       // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.InvalidSuperClassName"));
+       // //$NON-NLS-1$
+       // PHPeclipsePlugin.log(e);
+       // }
+       // } else {
+       // status.setError(""); //$NON-NLS-1$
+       // }
+       // return status;
+       //              
+       // }
+       // private IType resolveSuperTypeName(IJavaProject jproject, String
+       // sclassName) throws JavaModelException {
+       // if (!jproject.exists()) {
+       // return null;
+       // }
+       // IType type= null;
+       // if (isEnclosingTypeSelected()) {
+       // // search in the context of the enclosing type
+       // IType enclosingType= getEnclosingType();
+       // if (enclosingType != null) {
+       // String[][] res= enclosingType.resolveType(sclassName);
+       // if (res != null && res.length > 0) {
+       // type= jproject.findType(res[0][0], res[0][1]);
+       // }
+       // }
+       // } else {
+       // IPackageFragment currPack= getPackageFragment();
+       // if (type == null && currPack != null) {
+       // String packName= currPack.getElementName();
+       // // search in own package
+       // if (!currPack.isDefaultPackage()) {
+       // type= jproject.findType(packName, sclassName);
+       // }
+       // // search in java.lang
+       // if (type == null && !"java.lang".equals(packName)) { //$NON-NLS-1$
+       // type= jproject.findType("java.lang", sclassName); //$NON-NLS-1$
+       // }
+       // }
+       // // search fully qualified
+       // if (type == null) {
+       // type= jproject.findType(sclassName);
+       // }
+       // }
+       // return type;
+       // }
+       // private IType findType(IJavaProject project, String typeName) throws
+       // JavaModelException {
+       // if (project.exists()) {
+       // return project.findType(typeName);
+       // }
+       // return null;
+       // }
+       /**
+        * Hook method that gets called when the list of super interface has
+        * changed. The method validates the superinterfaces and returns the status
+        * of the validation.
+        * <p>
+        * Subclasses may extend this method to perform their own validation.
+        * </p>
+        * 
+        * @return the status of the validation
+        */
+       // protected IStatus superInterfacesChanged() {
+       // StatusInfo status= new StatusInfo();
+       //              
+       // IPackageFragmentRoot root= getPackageFragmentRoot();
+       // fSuperInterfacesDialogField.enableButton(0, root != null);
+       //                                              
+       // if (root != null) {
+       // List elements= fSuperInterfacesDialogField.getElements();
+       // int nElements= elements.size();
+       // for (int i= 0; i < nElements; i++) {
+       // String intfname= (String)elements.get(i);
+       // try {
+       // IType type= findType(root.getJavaProject(), intfname);
+       // if (type == null) {
+       // status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.InterfaceNotExists",
+       // intfname)); //$NON-NLS-1$
+       // return status;
+       // } else {
+       // if (type.isClass()) {
+       // status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.InterfaceIsNotInterface",
+       // intfname)); //$NON-NLS-1$
+       // return status;
+       // }
+       // if (!JavaModelUtil.isVisible(type, getPackageFragment())) {
+       // status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.InterfaceIsNotVisible",
+       // intfname)); //$NON-NLS-1$
+       // return status;
+       // }
+       // }
+       // } catch (JavaModelException e) {
+       // PHPeclipsePlugin.log(e);
+       // // let pass, checking is an extra
+       // }
+       // }
+       // }
+       // return status;
+       // }
+       /**
+        * Hook method that gets called when the modifiers have changed. The method
+        * validates the modifiers and returns the status of the validation.
+        * <p>
+        * Subclasses may extend this method to perform their own validation.
+        * </p>
+        * 
+        * @return the status of the validation
+        */
+       protected IStatus modifiersChanged() {
+               StatusInfo status = new StatusInfo();
+               int modifiers = getModifiers();
+               // if (Flags.isFinal(modifiers) && Flags.isAbstract(modifiers)) {
+               // status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.ModifiersFinalAndAbstract"));
+               // //$NON-NLS-1$
+               // }
+               return status;
+       }
+
+       // selection dialogs
+
+       // private IPackageFragment choosePackage() {
+       // IPackageFragmentRoot froot= getPackageFragmentRoot();
+       // IJavaElement[] packages= null;
+       // try {
+       // if (froot != null && froot.exists()) {
+       // packages= froot.getChildren();
+       // }
+       // } catch (JavaModelException e) {
+       // PHPeclipsePlugin.log(e);
+       // }
+       // if (packages == null) {
+       // packages= new IJavaElement[0];
+       // }
+       //              
+       // ElementListSelectionDialog dialog= new
+       // ElementListSelectionDialog(getShell(), new
+       // JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT));
+       // dialog.setIgnoreCase(false);
+       // dialog.setTitle(NewWizardMessages.getString("NewTypeWizardPage.ChoosePackageDialog.title"));
+       // //$NON-NLS-1$
+       // dialog.setMessage(NewWizardMessages.getString("NewTypeWizardPage.ChoosePackageDialog.description"));
+       // //$NON-NLS-1$
+       // dialog.setEmptyListMessage(NewWizardMessages.getString("NewTypeWizardPage.ChoosePackageDialog.empty"));
+       // //$NON-NLS-1$
+       // dialog.setElements(packages);
+       // IPackageFragment pack= getPackageFragment();
+       // if (pack != null) {
+       // dialog.setInitialSelections(new Object[] { pack });
+       // }
+       //
+       // if (dialog.open() == ElementListSelectionDialog.OK) {
+       // return (IPackageFragment) dialog.getFirstResult();
+       // }
+       // return null;
+       // }
+
+       // private IType chooseEnclosingType() {
+       // IPackageFragmentRoot root= getPackageFragmentRoot();
+       // if (root == null) {
+       // return null;
+       // }
+       //              
+       // IJavaSearchScope scope= SearchEngine.createJavaSearchScope(new
+       // IJavaElement[] { root });
+       //      
+       // TypeSelectionDialog dialog= new TypeSelectionDialog(getShell(),
+       // getWizard().getContainer(), IJavaSearchConstants.TYPE, scope);
+       // dialog.setTitle(NewWizardMessages.getString("NewTypeWizardPage.ChooseEnclosingTypeDialog.title"));
+       // //$NON-NLS-1$
+       // dialog.setMessage(NewWizardMessages.getString("NewTypeWizardPage.ChooseEnclosingTypeDialog.description"));
+       // //$NON-NLS-1$
+       // dialog.setFilter(Signature.getSimpleName(getEnclosingTypeText()));
+       //              
+       // if (dialog.open() == TypeSelectionDialog.OK) {
+       // return (IType) dialog.getFirstResult();
+       // }
+       // return null;
+       // }
+
+       // private IType chooseSuperType() {
+       // IPackageFragmentRoot root= getPackageFragmentRoot();
+       // if (root == null) {
+       // return null;
+       // }
+       //              
+       // IJavaElement[] elements= new IJavaElement[] { root.getJavaProject() };
+       // IJavaSearchScope scope= SearchEngine.createJavaSearchScope(elements);
+       //
+       // TypeSelectionDialog dialog= new TypeSelectionDialog(getShell(),
+       // getWizard().getContainer(), IJavaSearchConstants.CLASS, scope);
+       // dialog.setTitle(NewWizardMessages.getString("NewTypeWizardPage.SuperClassDialog.title"));
+       // //$NON-NLS-1$
+       // dialog.setMessage(NewWizardMessages.getString("NewTypeWizardPage.SuperClassDialog.message"));
+       // //$NON-NLS-1$
+       // dialog.setFilter(getSuperClass());
+       //
+       // if (dialog.open() == TypeSelectionDialog.OK) {
+       // return (IType) dialog.getFirstResult();
+       // }
+       // return null;
+       // }
+
+       // private void chooseSuperInterfaces() {
+       // IPackageFragmentRoot root= getPackageFragmentRoot();
+       // if (root == null) {
+       // return;
+       // }
+       //
+       // IJavaProject project= root.getJavaProject();
+       // SuperInterfaceSelectionDialog dialog= new
+       // SuperInterfaceSelectionDialog(getShell(), getWizard().getContainer(),
+       // fSuperInterfacesDialogField, project);
+       // dialog.setTitle(fIsClass ?
+       // NewWizardMessages.getString("NewTypeWizardPage.InterfacesDialog.class.title")
+       // :
+       // NewWizardMessages.getString("NewTypeWizardPage.InterfacesDialog.interface.title"));
+       // //$NON-NLS-1$ //$NON-NLS-2$
+       // dialog.setMessage(NewWizardMessages.getString("NewTypeWizardPage.InterfacesDialog.message"));
+       // //$NON-NLS-1$
+       // dialog.open();
+       // return;
+       // }
+
+       // ---- creation ----------------
+
+       /**
+        * Creates the new type using the entered field values.
+        * 
+        * @param monitor
+        *            a progress monitor to report progress.
+        */
+       public void createType(IProgressMonitor monitor) throws CoreException,
+                       InterruptedException {
+               if (monitor == null) {
+                       monitor = new NullProgressMonitor();
+               }
+
+               monitor.beginTask(NewWizardMessages
+                               .getString("NewTypeWizardPage.operationdesc"), 10); //$NON-NLS-1$
+               ICompilationUnit createdWorkingCopy = null;
+               try {
+                       // IPackageFragmentRoot root = getPackageFragmentRoot();
+                       // IPackageFragment pack = getPackageFragment();
+                       // if (pack == null) {
+                       // pack = root.getPackageFragment(""); //$NON-NLS-1$
+                       // }
+                       //
+                       // if (!pack.exists()) {
+                       // String packName = pack.getElementName();
+                       // pack = root.createPackageFragment(packName, true, null);
+                       // }
+
+                       monitor.worked(1);
+
+                       String clName = getTypeName();
+
+                       boolean isInnerClass = isEnclosingTypeSelected();
+
+                       IType createdType;
+                       // ImportsStructure imports;
+                       int indent = 0;
+
+                       IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+                       // String[] prefOrder =
+                       // JavaPreferencesSettings.getImportOrderPreference(store);
+                       // int threshold =
+                       // JavaPreferencesSettings.getImportNumberThreshold(store);
+                       //
+                       String lineDelimiter = null;
+                       // if (!isInnerClass) {
+                       lineDelimiter = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+                       //
+                       // ICompilationUnit parentCU = pack.createCompilationUnit(clName +
+                       // ".php", "", false, new SubProgressMonitor(monitor, 2));
+                       // //$NON-NLS-1$ //$NON-NLS-2$
+                       // createdWorkingCopy = (ICompilationUnit)
+                       // parentCU.getSharedWorkingCopy(null, JavaUI.getBufferFactory(),
+                       // null);
+                       //
+                       // imports = new ImportsStructure(createdWorkingCopy, prefOrder,
+                       // threshold, false);
+                       // // add an import that will be removed again. Having this import
+                       // solves 14661
+                       // imports.addImport(pack.getElementName(), getTypeName());
+                       //
+                       String typeContent = constructTypeStub(lineDelimiter);// new
+                                                                                                                                       // ImportsManager(imports),
+                                                                                                                                       // lineDelimiter);
+
+                       // String cuContent = constructCUContent(parentCU, typeContent,
+                       // lineDelimiter);
+
+                       // createdWorkingCopy.getBuffer().setContents(cuContent);
+                       //
+                       createdType = createdWorkingCopy.getType(clName);
+                       // } else {
+                       // IType enclosingType = getEnclosingType();
+                       //
+                       // // if we are working on a enclosed type that is open in an
+                       // editor,
+                       // // then replace the enclosing type with its working copy
+                       // IType workingCopy = (IType)
+                       // EditorUtility.getWorkingCopy(enclosingType);
+                       // if (workingCopy != null) {
+                       // enclosingType = workingCopy;
+                       // }
+                       //
+                       // ICompilationUnit parentCU = enclosingType.getCompilationUnit();
+                       // imports = new ImportsStructure(parentCU, prefOrder, threshold,
+                       // true);
+                       //
+                       // // add imports that will be removed again. Having the imports
+                       // solves 14661
+                       // IType[] topLevelTypes = parentCU.getTypes();
+                       // for (int i = 0; i < topLevelTypes.length; i++) {
+                       // imports.addImport(topLevelTypes[i].getFullyQualifiedName('.'));
+                       // }
+                       //
+                       // lineDelimiter = StubUtility.getLineDelimiterUsed(enclosingType);
+                       // StringBuffer content = new StringBuffer();
+                       // String comment = getTypeComment(parentCU);
+                       // if (comment != null) {
+                       // content.append(comment);
+                       // content.append(lineDelimiter);
+                       // }
+                       // content.append(constructTypeStub(new ImportsManager(imports),
+                       // lineDelimiter));
+                       // IJavaElement[] elems = enclosingType.getChildren();
+                       // IJavaElement sibling = elems.length > 0 ? elems[0] : null;
+                       //
+                       // createdType = enclosingType.createType(content.toString(),
+                       // sibling, false, new SubProgressMonitor(monitor, 1));
+                       //
+                       // indent = StubUtility.getIndentUsed(enclosingType) + 1;
+                       // }
+                       //
+                       // // add imports for superclass/interfaces, so types can be
+                       // resolved correctly
+                       // imports.create(false, new SubProgressMonitor(monitor, 1));
+                       //
+                       ICompilationUnit cu = createdType.getCompilationUnit();
+                       synchronized (cu) {
+                               cu.reconcile();
+                       }
+                       // createTypeMembers(createdType, new ImportsManager(imports), new
+                       // SubProgressMonitor(monitor, 1));
+                       //
+                       // // add imports
+                       // imports.create(false, new SubProgressMonitor(monitor, 1));
+
+                       synchronized (cu) {
+                               cu.reconcile();
+                       }
+                       ISourceRange range = createdType.getSourceRange();
+
+                       IBuffer buf = cu.getBuffer();
+                       String originalContent = buf.getText(range.getOffset(), range
+                                       .getLength());
+                       String formattedContent = StubUtility.codeFormat(originalContent,
+                                       indent, lineDelimiter);
+                       buf.replace(range.getOffset(), range.getLength(), formattedContent);
+                       if (!isInnerClass) {
+                               String fileComment = getFileComment(cu);
+                               if (fileComment != null && fileComment.length() > 0) {
+                                       buf.replace(0, 0, fileComment + lineDelimiter);
+                               }
+                               cu.commit(false, new SubProgressMonitor(monitor, 1));
+                       } else {
+                               monitor.worked(1);
+                       }
+                       fCreatedType = createdType;
+               } finally {
+                       if (createdWorkingCopy != null) {
+                               createdWorkingCopy.destroy();
+                       }
+                       monitor.done();
+               }
+       }
+
+       /**
+        * Uses the New Java file template from the code template page to generate a
+        * compilation unit with the given type content.
+        * 
+        * @param cu
+        *            The new created compilation unit
+        * @param typeContent
+        *            The content of the type, including signature and type body.
+        * @param lineDelimiter
+        *            The line delimiter to be used.
+        * @return String Returns the result of evaluating the new file template
+        *         with the given type content.
+        * @throws CoreException
+        * @since 2.1
+        */
+       // protected String constructCUContent(ICompilationUnit cu, String
+       // typeContent, String lineDelimiter) throws CoreException {
+       // StringBuffer typeQualifiedName= new StringBuffer();
+       // if (isEnclosingTypeSelected()) {
+       // typeQualifiedName.append(JavaModelUtil.getTypeQualifiedName(getEnclosingType())).append('.');
+       // }
+       // typeQualifiedName.append(getTypeName());
+       // String typeComment= CodeGeneration.getTypeComment(cu,
+       // typeQualifiedName.toString(), lineDelimiter);
+       // IPackageFragment pack= (IPackageFragment) cu.getParent();
+       // String content= CodeGeneration.getCompilationUnitContent(cu, typeComment,
+       // typeContent, lineDelimiter);
+       // if (content != null) {
+       // CompilationUnit unit= AST.parseCompilationUnit(content.toCharArray());
+       // if ((pack.isDefaultPackage() || unit.getPackage() != null) &&
+       // !unit.types().isEmpty()) {
+       // return content;
+       // }
+       // }
+       // StringBuffer buf= new StringBuffer();
+       // if (!pack.isDefaultPackage()) {
+       // buf.append("package ").append(pack.getElementName()).append(';');
+       // //$NON-NLS-1$
+       // }
+       // buf.append(lineDelimiter).append(lineDelimiter);
+       // if (typeComment != null) {
+       // buf.append(typeComment).append(lineDelimiter);
+       // }
+       // buf.append(typeContent);
+       // return buf.toString();
+       // }
+       /**
+        * Returns the created type. The method only returns a valid type after
+        * <code>createType</code> has been called.
+        * 
+        * @return the created type
+        * @see #createType(IProgressMonitor)
+        */
+       public IType getCreatedType() {
+               return fCreatedType;
+       }
+
+       // ---- construct cu body----------------
+
+       // private void writeSuperClass(StringBuffer buf, ImportsManager imports) {
+       // String typename= getSuperClass();
+       // if (fIsClass && typename.length() > 0 &&
+       // !"java.lang.Object".equals(typename)) { //$NON-NLS-1$
+       // buf.append(" extends "); //$NON-NLS-1$
+       //                      
+       // String qualifiedName= fSuperClass != null ?
+       // JavaModelUtil.getFullyQualifiedName(fSuperClass) : typename;
+       // buf.append(imports.addImport(qualifiedName));
+       // }
+       // }
+
+       // private void writeSuperInterfaces(StringBuffer buf, ImportsManager
+       // imports) {
+       // List interfaces= getSuperInterfaces();
+       // int last= interfaces.size() - 1;
+       // if (last >= 0) {
+       // if (fIsClass) {
+       // buf.append(" implements "); //$NON-NLS-1$
+       // } else {
+       // buf.append(" extends "); //$NON-NLS-1$
+       // }
+       // for (int i= 0; i <= last; i++) {
+       // String typename= (String) interfaces.get(i);
+       // buf.append(imports.addImport(typename));
+       // if (i < last) {
+       // buf.append(',');
+       // }
+       // }
+       // }
+       // }
+
+       /*
+        * Called from createType to construct the source for this type
+        */
+       private String constructTypeStub(String lineDelimiter) { // ImportsManager
+                                                                                                                               // imports,
+                                                                                                                               // String
+                                                                                                                               // lineDelimiter)
+                                                                                                                               // {
+               StringBuffer buf = new StringBuffer();
+
+               int modifiers = getModifiers();
+               buf.append(Flags.toString(modifiers));
+               if (modifiers != 0) {
+                       buf.append(' ');
+               }
+               buf.append(fIsClass ? "class " : "interface "); //$NON-NLS-2$ //$NON-NLS-1$
+               buf.append(getTypeName());
+               // writeSuperClass(buf, imports);
+               // writeSuperInterfaces(buf, imports);
+               buf.append('{');
+               buf.append(lineDelimiter);
+               buf.append(lineDelimiter);
+               buf.append('}');
+               buf.append(lineDelimiter);
+               return buf.toString();
+       }
+
+       /**
+        * @deprecated Overwrite createTypeMembers(IType, IImportsManager,
+        *             IProgressMonitor) instead
+        */
+       // protected void createTypeMembers(IType newType, IImportsStructure
+       // imports, IProgressMonitor monitor) throws CoreException {
+       // //deprecated
+       // }
+       /**
+        * Hook method that gets called from <code>createType</code> to support
+        * adding of unanticipated methods, fields, and inner types to the created
+        * type.
+        * <p>
+        * Implementers can use any methods defined on <code>IType</code> to
+        * manipulate the new type.
+        * </p>
+        * <p>
+        * The source code of the new type will be formtted using the platform's
+        * formatter. Needed imports are added by the wizard at the end of the type
+        * creation process using the given import manager.
+        * </p>
+        * 
+        * @param newType
+        *            the new type created via <code>createType</code>
+        * @param imports
+        *            an import manager which can be used to add new imports
+        * @param monitor
+        *            a progress monitor to report progress. Must not be
+        *            <code>null</code>
+        * 
+        * @see #createType(IProgressMonitor)
+        */
+       // protected void createTypeMembers(IType newType, ImportsManager imports,
+       // IProgressMonitor monitor) throws CoreException {
+       // // call for compatibility
+       // createTypeMembers(newType,
+       // ((ImportsManager)imports).getImportsStructure(), monitor);
+       //              
+       // // default implementation does nothing
+       // // example would be
+       // // String mainMathod= "public void foo(Vector vec) {}"
+       // // createdType.createMethod(main, null, false, null);
+       // // imports.addImport("java.lang.Vector");
+       // }
+       /**
+        * @deprecated Instead of file templates, the new type code template
+        *             specifies the stub for a compilation unit.
+        */
+       protected String getFileComment(ICompilationUnit parentCU) {
+               return null;
+       }
+
+       private boolean isValidComment(String template) {
+               IScanner scanner = ToolFactory.createScanner(true, false, false); // ,
+                                                                                                                                                       // false);
+               scanner.setSource(template.toCharArray());
+               try {
+                       int next = scanner.getNextToken();
+                       while (next == ITerminalSymbols.TokenNameCOMMENT_LINE
+                                       || next == ITerminalSymbols.TokenNameCOMMENT_PHPDOC
+                                       || next == ITerminalSymbols.TokenNameCOMMENT_BLOCK) {
+                               next = scanner.getNextToken();
+                       }
+                       return next == ITerminalSymbols.TokenNameEOF;
+               } catch (InvalidInputException e) {
+               }
+               return false;
+       }
+
+       /**
+        * Hook method that gets called from <code>createType</code> to retrieve a
+        * type comment. This default implementation returns the content of the
+        * 'typecomment' template.
+        * 
+        * @return the type comment or <code>null</code> if a type comment is not
+        *         desired
+        */
+       protected String getTypeComment(ICompilationUnit parentCU) {
+               if (PreferenceConstants.getPreferenceStore().getBoolean(
+                               PreferenceConstants.CODEGEN_ADD_COMMENTS)) {
+                       try {
+                               StringBuffer typeName = new StringBuffer();
+                               if (isEnclosingTypeSelected()) {
+                                       typeName.append(
+                                                       JavaModelUtil
+                                                                       .getTypeQualifiedName(getEnclosingType()))
+                                                       .append('.');
+                               }
+                               typeName.append(getTypeName());
+                               String comment = CodeGeneration.getTypeComment(parentCU,
+                                               typeName.toString(), String.valueOf('\n'));
+                               if (comment != null && isValidComment(comment)) {
+                                       return comment;
+                               }
+                       } catch (CoreException e) {
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * @deprecated Use getTemplate(String,ICompilationUnit,int)
+        */
+       protected String getTemplate(String name, ICompilationUnit parentCU) {
+               return getTemplate(name, parentCU, 0);
+       }
+
+       /**
+        * Returns the string resulting from evaluation the given template in the
+        * context of the given compilation unit. This accesses the normal template
+        * page, not the code templates. To use code templates use
+        * <code>constructCUContent</code> to construct a compilation unit stub or
+        * getTypeComment for the comment of the type.
+        * 
+        * @param name
+        *            the template to be evaluated
+        * @param parentCU
+        *            the templates evaluation context
+        * @param pos
+        *            a source offset into the parent compilation unit. The template
+        *            is evalutated at the given source offset
+        */
+       protected String getTemplate(String name, ICompilationUnit parentCU, int pos) {
+               try {
+                       Template[] templates = Templates.getInstance().getTemplates(name);
+                       if (templates.length > 0) {
+                               return JavaContext
+                                               .evaluateTemplate(templates[0], parentCU, pos);
+                       }
+               } catch (CoreException e) {
+                       PHPeclipsePlugin.log(e);
+               } catch (BadLocationException e1) {
+                       // TODO Auto-generated catch block
+                       e1.printStackTrace();
+               } catch (TemplateException e1) {
+                       // TODO Auto-generated catch block
+                       e1.printStackTrace();
+               }
+               return null;
+       }
+
+       /**
+        * @deprecated Use
+        *             createInheritedMethods(IType,boolean,boolean,IImportsManager,IProgressMonitor)
+        */
+       // protected IMethod[] createInheritedMethods(IType type, boolean
+       // doConstructors, boolean doUnimplementedMethods, IImportsStructure
+       // imports, IProgressMonitor monitor) throws CoreException {
+       // return createInheritedMethods(type, doConstructors,
+       // doUnimplementedMethods, new ImportsManager(imports), monitor);
+       // }
+       /**
+        * Creates the bodies of all unimplemented methods and constructors and adds
+        * them to the type. Method is typically called by implementers of
+        * <code>NewTypeWizardPage</code> to add needed method and constructors.
+        * 
+        * @param type
+        *            the type for which the new methods and constructor are to be
+        *            created
+        * @param doConstructors
+        *            if <code>true</code> unimplemented constructors are created
+        * @param doUnimplementedMethods
+        *            if <code>true</code> unimplemented methods are created
+        * @param imports
+        *            an import manager to add all neded import statements
+        * @param monitor
+        *            a progress monitor to report progress
+        */
+       // protected IMethod[] createInheritedMethods(IType type, boolean
+       // doConstructors, boolean doUnimplementedMethods, ImportsManager imports,
+       // IProgressMonitor monitor) throws CoreException {
+       // ArrayList newMethods= new ArrayList();
+       // ITypeHierarchy hierarchy= null;
+       // CodeGenerationSettings settings=
+       // JavaPreferencesSettings.getCodeGenerationSettings();
+       //
+       // if (doConstructors) {
+       // hierarchy= type.newSupertypeHierarchy(monitor);
+       // IType superclass= hierarchy.getSuperclass(type);
+       // if (superclass != null) {
+       // String[] constructors= StubUtility.evalConstructors(type, superclass,
+       // settings, imports.getImportsStructure());
+       // if (constructors != null) {
+       // for (int i= 0; i < constructors.length; i++) {
+       // newMethods.add(constructors[i]);
+       // }
+       // }
+       //                      
+       // }
+       // }
+       // if (doUnimplementedMethods) {
+       // if (hierarchy == null) {
+       // hierarchy= type.newSupertypeHierarchy(monitor);
+       // }
+       // String[] unimplemented= StubUtility.evalUnimplementedMethods(type,
+       // hierarchy, false, settings, null, imports.getImportsStructure());
+       // if (unimplemented != null) {
+       // for (int i= 0; i < unimplemented.length; i++) {
+       // newMethods.add(unimplemented[i]);
+       // }
+       // }
+       // }
+       // IMethod[] createdMethods= new IMethod[newMethods.size()];
+       // for (int i= 0; i < newMethods.size(); i++) {
+       // String content= (String) newMethods.get(i) + '\n'; // content will be
+       // formatted, ok to use \n
+       // createdMethods[i]= type.createMethod(content, null, false, null);
+       // }
+       // return createdMethods;
+       // }
+       // ---- creation ----------------
+       /**
+        * Returns the runnable that creates the type using the current settings.
+        * The returned runnable must be executed in the UI thread.
+        * 
+        * @return the runnable to create the new type
+        */
+       // public IRunnableWithProgress getRunnable() {
+       // return new IRunnableWithProgress() {
+       // public void run(IProgressMonitor monitor) throws
+       // InvocationTargetException, InterruptedException {
+       // try {
+       // if (monitor == null) {
+       // monitor= new NullProgressMonitor();
+       // }
+       // createType(monitor);
+       // } catch (CoreException e) {
+       // throw new InvocationTargetException(e);
+       // }
+       // }
+       // };
+       // }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/IncludesScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/IncludesScanner.java
new file mode 100644 (file)
index 0000000..3858ed8
--- /dev/null
@@ -0,0 +1,183 @@
+package net.sourceforge.phpeclipse.actions;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.ui.IFileEditorInput;
+
+public class IncludesScanner implements ITerminalSymbols {
+       // private final PHPOpenAllIncludesEditorAction fOpenAllIncludesAction;
+       private IProject fProject;
+
+       private IFileEditorInput fEditorInput;
+
+       private HashSet fSet;
+
+       public IncludesScanner(IProject project, IFileEditorInput editorInput) {
+               fProject = project;
+               // fOpenAllIncludesAction = action;
+               fEditorInput = editorInput;
+               fSet = new HashSet();
+       }
+
+       /**
+        * Add the information for a given IFile resource
+        * 
+        */
+       public void addFile(IFile fileToParse) {
+
+               try {
+                       if (fileToParse.exists()) {
+                               addInputStream(new BufferedInputStream(fileToParse
+                                               .getContents()), fileToParse.getProjectRelativePath()
+                                               .toString());
+                       }
+               } catch (CoreException e1) {
+                       e1.printStackTrace();
+               }
+       }
+
+       private void addInputStream(InputStream stream, String filePath)
+                       throws CoreException {
+               try {
+                       if (fSet.add(filePath)) { // new entry in set
+                               parseIdentifiers(Util.getInputStreamAsCharArray(stream, -1,
+                                               null));
+                       }
+               } catch (IOException e) {
+                       e.printStackTrace();
+               } finally {
+                       try {
+                               if (stream != null) {
+                                       stream.close();
+                               }
+                       } catch (IOException e) {
+                       }
+               }
+       }
+
+       /**
+        * Get the next token from input
+        */
+       private int getNextToken(Scanner scanner) {
+               int token;
+               try {
+                       token = scanner.getNextToken();
+                       if (Scanner.DEBUG) {
+                               int currentEndPosition = scanner.getCurrentTokenEndPosition();
+                               int currentStartPosition = scanner
+                                               .getCurrentTokenStartPosition();
+                               System.out.print(currentStartPosition + ","
+                                               + currentEndPosition + ": ");
+                               System.out.println(scanner.toStringAction(token));
+                       }
+                       return token;
+               } catch (InvalidInputException e) {
+               }
+               return TokenNameERROR;
+       }
+
+       private void parseIdentifiers(char[] charArray) {
+               IFile file;
+               Scanner scanner = new Scanner(false, false, false, false, true, null,
+                               null, true /* taskCaseSensitive */);
+               scanner.setSource(charArray);
+               scanner.setPHPMode(false);
+               int token = getNextToken(scanner);
+               try {
+                       while (token != TokenNameEOF) { // && fToken != TokenNameERROR) {
+                               if (token == TokenNameinclude || token == TokenNameinclude_once
+                                               || token == TokenNamerequire
+                                               || token == TokenNamerequire_once) {
+                                       while (token != TokenNameEOF && token != TokenNameERROR
+                                                       && token != TokenNameSEMICOLON
+                                                       && token != TokenNameRPAREN
+                                                       && token != TokenNameLBRACE
+                                                       && token != TokenNameRBRACE) {
+                                               token = getNextToken(scanner);
+                                               if (token == TokenNameStringDoubleQuote
+                                                               || token == TokenNameStringSingleQuote) {
+                                                       char[] includeName = scanner
+                                                                       .getCurrentStringLiteralSource();
+                                                       try {
+                                                           System.out.println(includeName);
+                                                               file = getIncludeFile(new String(includeName));
+                                                               addFile(file);
+                                                       } catch (Exception e) {
+                                                               // ignore
+                                                       }
+                                                       break;
+                                               }
+                                       }
+                               }
+                               token = getNextToken(scanner);
+                       }
+               } catch (SyntaxError e) {
+                       // e.printStackTrace();
+               }
+       }
+
+       private IContainer getWorkingLocation(IFileEditorInput editorInput) {
+               if (editorInput == null || editorInput.getFile() == null) {
+                       return null;
+               }
+               return editorInput.getFile().getParent();
+       }
+
+       public IFile getIncludeFile(String relativeFilename) {
+               IContainer container = getWorkingLocation(fEditorInput);
+               IFile file = null;
+               if (relativeFilename.startsWith("../")) {
+                       Path path = new Path(relativeFilename);
+                       file = container.getFile(path);
+                       return file;
+               }
+               int index = relativeFilename.lastIndexOf('/');
+
+               if (index >= 0) {
+                       Path path = new Path(relativeFilename);
+                       file = fProject.getFile(path);
+                       if (file.exists()) {
+                               return file;
+                       }
+               }
+               Path path = new Path(relativeFilename);
+               file = container.getFile(path);
+
+               return file;
+       }
+
+       /**
+        * Returns a list of includes
+        * 
+        * @return the determined list of includes
+        */
+       public List getList() {
+               ArrayList list = new ArrayList();
+               list.addAll(fSet);
+               return list;
+       }
+
+       /**
+        * @return Returns the set.
+        */
+       public Set getSet() {
+               return fSet;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/OpenDeclarationEditorAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/OpenDeclarationEditorAction.java
new file mode 100644 (file)
index 0000000..7492195
--- /dev/null
@@ -0,0 +1,308 @@
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: www.phpeclipse.de
+ **********************************************************************************************************************************/
+package net.sourceforge.phpeclipse.actions;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ListContentProvider;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.dialogs.ListSelectionDialog;
+
+public class OpenDeclarationEditorAction {
+
+       private PHPEditor fEditor;
+
+       private IProject fProject;
+
+       private boolean isIncludeString;
+
+       public OpenDeclarationEditorAction(PHPEditor editor) {
+               fEditor = editor;
+               fProject = null;
+               isIncludeString = false;
+       }
+
+       /**
+        * @param selection
+        */
+       protected void openSelectedElement(ITextSelection selection) {
+               IDocument doc = fEditor.getDocumentProvider().getDocument(
+                               fEditor.getEditorInput());
+               int pos = selection.getOffset();
+               openSelectedPosition(doc, pos);
+       }
+
+       protected void openSelectedPosition(IDocument doc, int position) {
+               IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile();
+               fProject = f.getProject();
+               // System.out.println(selection.getText());
+               String identifierOrInclude = getIdentifierOrInclude(doc, position);
+               // System.out.println(word);
+               if (identifierOrInclude != null && !identifierOrInclude.equals("")) {
+                       if (isIncludeString) {
+                               openIncludeFile(identifierOrInclude);
+                       } else {
+                               openIdentifierDeclaration(f, identifierOrInclude);
+                       }
+               }
+       }
+
+       /**
+        * @param filename
+        */
+       private void openIncludeFile(String filename) {
+               if (filename != null && !filename.equals("")) {
+                       try {
+                               IFile currentFile = ((IFileEditorInput) fEditor
+                                               .getEditorInput()).getFile();
+                               IPath path = PHPFileUtil.determineFilePath(filename,
+                                               currentFile, fProject);
+                               if (path != null) {
+                                       //IFile file = PHPFileUtil.createFile(path, fProject);
+                                       //if (file != null && file.exists()) {
+                                       //      PHPeclipsePlugin.getDefault().openFileInTextEditor(
+                                       //                      file.getLocation().toString());
+                                       //      return;
+                                       //}
+                                       WebUI.getDefault().openFileInTextEditor(
+                                                       path.toString());
+                                       return;
+                               }
+                       } catch (Exception e) {
+                               // ignore
+                       }
+
+                       try {
+
+                               IdentifierIndexManager indexManager = WebUI
+                                               .getDefault().getIndexManager(fProject);
+                               // filename = StringUtil.replaceRegExChars(filename);
+                               List list = indexManager.getFileList(filename);
+                               if (list != null && list.size() > 0) {
+                                       // String workspaceLocation =
+                                       // PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+                                       String workspaceLocation = fProject.getFullPath()
+                                                       .toString()
+                                                       + java.io.File.separatorChar;
+
+                                       ListSelectionDialog listSelectionDialog = new ListSelectionDialog(
+                                                       WebUI.getDefault().getWorkbench()
+                                                                       .getActiveWorkbenchWindow().getShell(),
+                                                       list, new ListContentProvider(),
+                                                       new LabelProvider(), "Select the includes to open.");
+                                       listSelectionDialog.setTitle("Multiple includes found");
+                                       if (listSelectionDialog.open() == Window.OK) {
+                                               Object[] locations = listSelectionDialog.getResult();
+                                               if (locations != null) {
+                                                       try {
+                                                               for (int i = 0; i < locations.length; i++) {
+                                                                       // PHPIdentifierLocation location =
+                                                                       // (PHPIdentifierLocation)
+                                                                       // locations[i];
+                                                                       String openFilename = workspaceLocation
+                                                                                       + ((String) locations[i]);
+                                                                       WebUI.getDefault()
+                                                                                       .openFileInTextEditor(openFilename);
+                                                               }
+                                                       } catch (CoreException e) {
+                                                               // TODO Auto-generated catch block
+                                                               e.printStackTrace();
+                                                       }
+                                               }
+                                       }
+
+                               }
+                       } catch (Exception e) {
+                       }
+
+               }
+               return;
+       }
+
+       /**
+        * @param f
+        * @param identiifer
+        */
+       private void openIdentifierDeclaration(IFile f, String identiifer) {
+               if (identiifer != null && !identiifer.equals("")) {
+                       IdentifierIndexManager indexManager = WebUI.getDefault()
+                                       .getIndexManager(fProject);
+                       List locationsList = indexManager.getLocations(identiifer);
+                       if (locationsList != null && locationsList.size() > 0) {
+
+                               // String workspaceLocation =
+                               // PHPeclipsePlugin.getWorkspace().getRoot()
+                               // .getLocation().toString();
+
+                               String workspaceLocation = fProject.getFullPath().toString()
+                                               + java.io.File.separatorChar;
+                               // TODO show all entries of the list in a dialog box
+                               // at the moment always the first entry will be opened
+                               if (locationsList.size() > 1) {
+                                       // determine all includes:
+                                       IncludesScanner includesScanner = new IncludesScanner(
+                                                       fProject, (IFileEditorInput) fEditor
+                                                                       .getEditorInput());
+                                       includesScanner.addFile(f);
+                                       Set exactIncludeSet = includesScanner.getSet();
+
+                                       PHPIdentifierLocation includeName;
+                                       for (int i = 0; i < locationsList.size(); i++) {
+                                               includeName = (PHPIdentifierLocation) locationsList
+                                                               .get(i);
+                                               if (exactIncludeSet.contains(includeName.getFilename())) {
+                                                       includeName
+                                                                       .setMatch(PHPIdentifierLocation.EXACT_MATCH);
+                                               } else {
+                                                       includeName
+                                                                       .setMatch(PHPIdentifierLocation.UNDEFINED_MATCH);
+                                               }
+                                       }
+                                       Collections.sort(locationsList);
+
+                                       ListSelectionDialog listSelectionDialog = new ListSelectionDialog(
+                                                       WebUI.getDefault().getWorkbench()
+                                                                       .getActiveWorkbenchWindow().getShell(),
+                                                       locationsList, new ListContentProvider(),
+                                                       new LabelProvider(),
+                                                       "Select the resources to open.");
+                                       listSelectionDialog.setTitle("Multiple declarations found");
+                                       if (listSelectionDialog.open() == Window.OK) {
+                                               Object[] locations = listSelectionDialog.getResult();
+                                               if (locations != null) {
+                                                       try {
+                                                               for (int i = 0; i < locations.length; i++) {
+                                                                       PHPIdentifierLocation location = (PHPIdentifierLocation) locations[i];
+                                                                       String filename = workspaceLocation
+                                                                                       + location.getFilename();
+                                                                       // System.out.println(filename);
+                                                                       if (location.getOffset() >= 0) {
+                                                                               WebUI.getDefault()
+                                                                                               .openFileAndGotoOffset(
+                                                                                                               filename,
+                                                                                                               location.getOffset(),
+                                                                                                               identiifer.length());
+                                                                       } else {
+                                                                               WebUI.getDefault()
+                                                                                               .openFileAndFindString(
+                                                                                                               filename, identiifer);
+                                                                       }
+                                                               }
+                                                       } catch (CoreException e) {
+                                                               // TODO Auto-generated catch block
+                                                               e.printStackTrace();
+                                                       }
+                                               }
+                                       }
+                               } else {
+                                       try {
+                                               PHPIdentifierLocation location = (PHPIdentifierLocation) locationsList
+                                                               .get(0);
+                                               String filename = workspaceLocation
+                                                               + location.getFilename();
+                                               // System.out.println(filename);
+                                               if (location.getOffset() >= 0) {
+                                                       WebUI.getDefault()
+                                                                       .openFileAndGotoOffset(filename,
+                                                                                       location.getOffset(),
+                                                                                       identiifer.length());
+                                               } else {
+                                                       WebUI
+                                                                       .getDefault()
+                                                                       .openFileAndFindString(filename, identiifer);
+                                               }
+                                       } catch (CoreException e) {
+                                               // TODO Auto-generated catch block
+                                               e.printStackTrace();
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private String getIdentifierOrInclude(IDocument doc, int pos) {
+               // private String getPHPIncludeText(IDocument doc, int pos) {
+               Point word = null;
+               int start = -1;
+               int end = -1;
+               isIncludeString = false;
+               try {
+                       // try to find an include string
+                       int position = pos;
+                       char character = ' ';
+
+                       while (position >= 0) {
+                               character = doc.getChar(position);
+                               if ((character == '\"') || (character == '\'')
+                                               || (character == '\r') || (character == '\n'))
+                                       break;
+                               --position;
+                       }
+                       if ((character == '\"') || (character == '\'')) {
+                               start = position;
+
+                               position = pos;
+                               int length = doc.getLength();
+                               character = ' ';
+                               while (position < length) {
+                                       character = doc.getChar(position);
+                                       if ((character == '\"') || (character == '\'')
+                                                       || (character == '\r') || (character == '\n'))
+                                               break;
+                                       ++position;
+                               }
+                               if ((character == '\"') || (character == '\'')) {
+                                       start++;
+                                       end = position;
+
+                                       if (end > start) {
+                                               word = new Point(start, end - start); // include name
+                                                                                                                               // found
+                                               isIncludeString = true;
+                                       }
+                               }
+                       }
+
+                       // try to find an identifier
+                       if (word == null) {
+                               word = PHPWordExtractor.findWord(doc, pos); // identifier found
+                               isIncludeString = false;
+                       }
+               } catch (BadLocationException x) {
+               }
+
+               if (word != null) {
+                       try {
+                               return doc.get(word.x, word.y);
+                       } catch (BadLocationException e) {
+                       }
+               }
+               return "";
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPActionMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPActionMessages.java
new file mode 100644 (file)
index 0000000..7851c84
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * (c) Copyright Improve S.A., 2002.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpeclipse.actions;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class PHPActionMessages {
+
+       private static final String RESOURCE_BUNDLE = "net.sourceforge.phpeclipse.actions.PHPActionMessages";//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private PHPActionMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       public static ResourceBundle getResourceBundle() {
+               return fgResourceBundle;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPActionMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPActionMessages.properties
new file mode 100644 (file)
index 0000000..417a814
--- /dev/null
@@ -0,0 +1,4 @@
+## Actions
+
+PHPStartApacheAction.consoleViewOpeningProblem=A problem occured while opening the PHP console view
+
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPEclipseShowAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPEclipseShowAction.java
new file mode 100644 (file)
index 0000000..d9f7db6
--- /dev/null
@@ -0,0 +1,160 @@
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: IBM Corporation - Initial implementation
+ *               www.phpeclipse.de
+ **********************************************************************************************************************************/
+package net.sourceforge.phpeclipse.actions;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.IPreferenceConstants;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.editor.ShowExternalPreviewAction;
+import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
+import net.sourceforge.phpeclipse.webbrowser.IWebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.internal.BrowserManager;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionDelegate;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+public class PHPEclipseShowAction implements IObjectActionDelegate {
+       private IWorkbenchPart workbenchPart;
+
+       /**
+        * Constructor for Action1.
+        */
+       public PHPEclipseShowAction() {
+               super();
+       }
+
+       /**
+        * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
+        */
+       public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+               workbenchPart = targetPart;
+       }
+
+       public void run(IAction action) {
+               ISelectionProvider selectionProvider = null;
+               selectionProvider = workbenchPart.getSite().getSelectionProvider();
+               StructuredSelection selection = null;
+               selection = (StructuredSelection) selectionProvider.getSelection();
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               Shell shell = null;
+               Iterator iterator = null;
+               iterator = selection.iterator();
+               while (iterator.hasNext()) {
+                       // obj => selected object in the view
+                       Object obj = iterator.next();
+                       // is it a resource
+                       if (obj instanceof IResource) {
+                               IResource resource = (IResource) obj;
+                               // check if it's a file resource
+                               switch (resource.getType()) {
+                               case IResource.FILE:
+                                       // single file:
+                                       IFile previewFile = (IFile) resource;
+                                       String extension = previewFile.getFileExtension()
+                                                       .toLowerCase();
+                                       boolean bringToTopPreview = ProjectPrefUtil
+                                                       .getPreviewBooleanValue(
+                                                                       previewFile,
+                                                                       IPreferenceConstants.PHP_BRING_TO_TOP_PREVIEW_DEFAULT);
+                                       // boolean showHTMLFilesLocal =
+                                       // ProjectPrefUtil.getPreviewBooleanValue(previewFile,
+                                       // IPreferenceConstants.PHP_SHOW_HTML_FILES_LOCAL);
+                                       // boolean showXMLFilesLocal =
+                                       // ProjectPrefUtil.getPreviewBooleanValue(previewFile,
+                                       // IPreferenceConstants.PHP_SHOW_XML_FILES_LOCAL);
+                                       boolean isHTMLFileName = "html".equals(extension)
+                                                       || "htm".equals(extension)
+                                                       || "xhtml".equals(extension);
+                                       boolean isXMLFileName = "xml".equals(extension)
+                                                       || "xsd".equals(extension)
+                                                       || "dtd".equals(extension);
+
+                                       String localhostURL;
+                                       // if (showHTMLFilesLocal && isHTMLFileName) {
+                                       // localhostURL =
+                                       // "file://"+previewFile.getLocation().toString();
+                                       // } else if (showXMLFilesLocal && isXMLFileName) {
+                                       // localhostURL =
+                                       // "file://"+previewFile.getLocation().toString();
+                                       // } else
+                                       if ((localhostURL = ShowExternalPreviewAction
+                                                       .getLocalhostURL(store, previewFile)) == null) {
+                                               MessageDialog
+                                                               .openInformation(shell,
+                                                                               "Couldn't create localhost URL",
+                                                                               "Please configure your localhost and documentRoot");
+                                               return;
+                                       }
+
+                                       try {
+                                               // if
+                                               // (store.getBoolean(PHPeclipsePlugin.USE_EXTERNAL_BROWSER_PREF))
+                                               // {
+                                               // String[] arguments = { localhostURL };
+                                               // MessageFormat form = new
+                                               // MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_BROWSER_PREF));
+                                               // Runtime runtime = Runtime.getRuntime();
+                                               // String command = form.format(arguments);
+                                               // // console.write("External Browser command: " +
+                                               // command + "\n");
+                                               // runtime.exec(command);
+                                               // } else {
+                                               open(new URL(localhostURL), shell, localhostURL);
+                                               // }
+                                       } catch (MalformedURLException e) {
+                                               MessageDialog.openInformation(shell,
+                                                               "MalformedURLException: ", e.toString());
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * @see IActionDelegate#selectionChanged(IAction, ISelection)
+        */
+       public void selectionChanged(IAction action, ISelection selection) {
+       }
+
+       public static void open(final URL url, final Shell shell,
+                       final String dialogTitle) {
+               // if (WebBrowserUtil.canUseInternalWebBrowser()) {
+               // IWorkbenchPage page = PHPeclipsePlugin.getActivePage();
+               // try {
+               // IViewPart part = page.findView(BrowserView.ID_BROWSER);
+               // if (part == null) {
+               // part = page.showView(BrowserView.ID_BROWSER);
+               // } else {
+               // page.bringToTop(part);
+               // }
+               // ((BrowserView) part).setUrl(url.toExternalForm());
+               // } catch (Exception e) {
+               // }
+               // } else {
+               BrowserManager manager = BrowserManager.getInstance();
+               IWebBrowser browser = manager.getCurrentWebBrowser();
+               browser.openURL(url);
+               // }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenAllIncludesEditorAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenAllIncludesEditorAction.java
new file mode 100644 (file)
index 0000000..86d2090
--- /dev/null
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Common Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: www.phpeclipse.de
+ ******************************************************************************/
+package net.sourceforge.phpeclipse.actions;
+
+import java.io.File;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.ListContentProvider;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionDelegate;
+import org.eclipse.ui.dialogs.ListSelectionDialog;
+
+public class PHPOpenAllIncludesEditorAction extends ActionDelegate implements
+               IEditorActionDelegate {
+
+       private IWorkbenchWindow fWindow;
+
+       private PHPEditor fEditor;
+
+       private IProject fProject;
+
+       private IncludesScanner fIncludesScanner;
+
+       public void dispose() {
+       }
+
+       public void init(IWorkbenchWindow window) {
+               this.fWindow = window;
+       }
+
+       public void selectionChanged(IAction action, ISelection selection) {
+               if (!selection.isEmpty()) {
+                       if (selection instanceof TextSelection) {
+                               action.setEnabled(true);
+                       } else if (fWindow.getActivePage() != null
+                                       && fWindow.getActivePage().getActivePart() != null) {
+                               //
+                       }
+               }
+       }
+
+       private IWorkbenchPage getActivePage() {
+               IWorkbenchWindow workbenchWindow = fEditor.getEditorSite()
+                               .getWorkbenchWindow();
+               IWorkbenchPage page = workbenchWindow.getActivePage();
+               return page;
+       }
+
+       public IContainer getWorkingLocation(IFileEditorInput editorInput) {
+               if (editorInput == null || editorInput.getFile() == null) {
+                       return null;
+               }
+               return editorInput.getFile().getParent();
+       }
+
+       private IFile getIncludeFile(IProject project,
+                       IFileEditorInput editorInput, String relativeFilename) {
+               IContainer container = getWorkingLocation(editorInput);
+               String fullPath = project.getFullPath().toString();
+               IFile file = null;
+               if (relativeFilename.startsWith("../")) {
+                       Path path = new Path(relativeFilename);
+                       file = container.getFile(path);
+                       return file;
+               }
+               int index = relativeFilename.lastIndexOf('/');
+
+               if (index >= 0) {
+                       Path path = new Path(relativeFilename);
+                       file = project.getFile(path);
+                       if (file.exists()) {
+                               return file;
+                       }
+               }
+
+               Path path = new Path(relativeFilename);
+               file = container.getFile(path);
+
+               return file;
+       }
+
+       public void run(IAction action) {
+               if (fEditor == null) {
+                       IEditorPart targetEditor = fWindow.getActivePage()
+                                       .getActiveEditor();
+                       if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
+                               fEditor = (PHPEditor) targetEditor;
+                       }
+               }
+               if (fEditor != null) {
+                       // determine the current Project from a (file-based) Editor
+                       IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile();
+                       fProject = f.getProject();
+                       // System.out.println(fProject.toString());
+
+                       ITextSelection selection = (ITextSelection) fEditor
+                                       .getSelectionProvider().getSelection();
+                       IDocument doc = fEditor.getDocumentProvider().getDocument(
+                                       fEditor.getEditorInput());
+                       fIncludesScanner = new IncludesScanner(fProject,
+                                       (IFileEditorInput) fEditor.getEditorInput());
+                       int pos = selection.getOffset();
+                       // System.out.println(selection.getText());
+                       String filename = getPHPIncludeText(doc, pos);
+
+                       if (filename != null && !filename.equals("")) {
+                               try {
+                                       IFile file = fIncludesScanner.getIncludeFile(filename);
+                                       fIncludesScanner.addFile(file);
+                               } catch (Exception e) {
+                                       // ignore
+                               }
+
+                               try {
+
+                                       List list = fIncludesScanner.getList();
+                                       if (list != null && list.size() > 0) {
+                                               // String workspaceLocation =
+                                               // PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+                                               String workspaceLocation = fProject.getFullPath()
+                                                               .toString()
+                                                               + File.separatorChar;
+
+                                               ListSelectionDialog listSelectionDialog = new ListSelectionDialog(
+                                                               WebUI.getDefault().getWorkbench()
+                                                                               .getActiveWorkbenchWindow().getShell(),
+                                                               list, new ListContentProvider(),
+                                                               new LabelProvider(),
+                                                               "Select the includes to open.");
+                                               listSelectionDialog.setTitle("Multiple includes found");
+                                               if (listSelectionDialog.open() == Window.OK) {
+                                                       Object[] locations = listSelectionDialog
+                                                                       .getResult();
+                                                       if (locations != null) {
+                                                               try {
+                                                                       for (int i = 0; i < locations.length; i++) {
+                                                                               // PHPIdentifierLocation location =
+                                                                               // (PHPIdentifierLocation)
+                                                                               // locations[i];
+                                                                               String openFilename = workspaceLocation
+                                                                                               + ((String) locations[i]);
+                                                                               WebUI.getDefault()
+                                                                                               .openFileInTextEditor(
+                                                                                                               openFilename);
+                                                                       }
+                                                               } catch (CoreException e) {
+                                                                       // TODO Auto-generated catch block
+                                                                       e.printStackTrace();
+                                                               }
+                                                       }
+                                               }
+
+                                       }
+                               } catch (Exception e) {
+                               }
+
+                       }
+               }
+       }
+
+       public void setActiveEditor(IAction action, IEditorPart targetEditor) {
+               if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
+                       fEditor = (PHPEditor) targetEditor;
+               }
+       }
+
+       private String getPHPIncludeText(IDocument doc, int pos) {
+               Point word = null;
+               int start = -1;
+               int end = -1;
+
+               try {
+
+                       int position = pos;
+                       char character;
+
+                       while (position >= 0) {
+                               character = doc.getChar(position);
+                               if ((character == '\"') || (character == '\'')
+                                               || (character == '\r') || (character == '\n'))
+                                       break;
+                               --position;
+                       }
+
+                       start = position;
+
+                       position = pos;
+                       int length = doc.getLength();
+
+                       while (position < length) {
+                               character = doc.getChar(position);
+                               if ((character == '\"') || (character == '\'')
+                                               || (character == '\r') || (character == '\n'))
+                                       break;
+                               ++position;
+                       }
+
+                       start++;
+                       end = position;
+
+                       if (end > start)
+                               word = new Point(start, end - start);
+
+               } catch (BadLocationException x) {
+               }
+
+               if (word != null) {
+                       try {
+                               return doc.get(word.x, word.y);
+                       } catch (BadLocationException e) {
+                       }
+               }
+               return "";
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationAction.java
new file mode 100644 (file)
index 0000000..47edccb
--- /dev/null
@@ -0,0 +1,113 @@
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: www.phpeclipse.de
+ **********************************************************************************************************************************/
+package net.sourceforge.phpeclipse.actions;
+
+import net.sourceforge.phpdt.internal.ui.actions.ActionUtil;
+import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter;
+import net.sourceforge.phpdt.ui.actions.SelectionDispatchAction;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.IWorkbenchWindow;
+
+public class PHPOpenDeclarationAction extends SelectionDispatchAction {
+       private IWorkbenchWindow fWindow;
+
+       private PHPEditor fEditor;
+
+       public void dispose() {
+       }
+
+       public PHPOpenDeclarationAction(IWorkbenchSite site) {
+               super(site);
+               // setText(ActionMessages.getString("OpenAction.label")); //$NON-NLS-1$
+               // setToolTipText(ActionMessages.getString("OpenAction.tooltip"));
+               // //$NON-NLS-1$
+               // setDescription(ActionMessages.getString("OpenAction.description"));
+               // //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(this, IJavaHelpContextIds.OPEN_ACTION);
+       }
+
+       /**
+        * Note: This constructor is for internal use only. Clients should not call
+        * this constructor.
+        */
+       public PHPOpenDeclarationAction(PHPEditor editor) {
+               this(editor.getEditorSite());
+               fEditor = editor;
+               // setText(ActionMessages.getString("OpenAction.declaration.label"));
+               // //$NON-NLS-1$
+               setEnabled(SelectionConverter.canOperateOn(fEditor));
+       }
+
+       public void init(IWorkbenchWindow window) {
+               this.fWindow = window;
+       }
+
+       public void selectionChanged(IAction action, ISelection selection) {
+               if (!selection.isEmpty()) {
+                       if (selection instanceof TextSelection) {
+                               action.setEnabled(true);
+                       } else if (fWindow.getActivePage() != null
+                                       && fWindow.getActivePage().getActivePart() != null) {
+                               //
+                       }
+               }
+       }
+
+       private boolean checkEnabled(IStructuredSelection selection) {
+               if (selection.isEmpty())
+                       return false;
+               return true;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on SelectionDispatchAction.
+        */
+       public void run(ITextSelection selection) {
+               if (!ActionUtil.isProcessable(getShell(), fEditor))
+                       return;
+               OpenDeclarationEditorAction openAction = new OpenDeclarationEditorAction(
+                               fEditor);
+               openAction.openSelectedElement(selection);
+       }
+
+       /*
+        * (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.
+        */
+       public void run(Object[] elements) {
+               if (elements != null && elements.length > 0) {
+                       ITextSelection selection = (ITextSelection) fEditor
+                                       .getSelectionProvider().getSelection();
+                       IDocument doc = fEditor.getDocumentProvider().getDocument(
+                                       fEditor.getEditorInput());
+                       int pos = selection.getOffset();
+
+                       OpenDeclarationEditorAction openAction = new OpenDeclarationEditorAction(
+                                       fEditor);
+                       openAction.openSelectedPosition(doc, pos);
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationEditorAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationEditorAction.java
new file mode 100644 (file)
index 0000000..d800960
--- /dev/null
@@ -0,0 +1,72 @@
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: www.phpeclipse.de
+ **********************************************************************************************************************************/
+package net.sourceforge.phpeclipse.actions;
+
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionDelegate;
+
+public class PHPOpenDeclarationEditorAction extends ActionDelegate implements
+               IEditorActionDelegate {
+       private IWorkbenchWindow fWindow;
+
+       private PHPEditor fEditor;
+
+       public void init(IWorkbenchWindow window) {
+               this.fWindow = window;
+       }
+
+       public void selectionChanged(IAction action, ISelection selection) {
+               if (!selection.isEmpty()) {
+                       if (selection instanceof TextSelection) {
+                               action.setEnabled(true);
+                       } else if (fWindow.getActivePage() != null
+                                       && fWindow.getActivePage().getActivePart() != null) {
+                               //
+                       }
+               }
+       }
+
+       private boolean checkEnabled(IStructuredSelection selection) {
+               if (selection.isEmpty())
+                       return false;
+               return true;
+       }
+
+       public void run(IAction action) {
+               if (fEditor == null) {
+                       IEditorPart targetEditor = fWindow.getActivePage()
+                                       .getActiveEditor();
+                       if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
+                               fEditor = (PHPEditor) targetEditor;
+                       }
+               }
+               if (fEditor != null) {
+                       ITextSelection selection = (ITextSelection) fEditor
+                                       .getSelectionProvider().getSelection();
+                       OpenDeclarationEditorAction openAction = new OpenDeclarationEditorAction(
+                                       fEditor);
+                       openAction.openSelectedElement(selection);
+               }
+       }
+
+       public void setActiveEditor(IAction action, IEditorPart targetEditor) {
+               if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
+                       fEditor = (PHPEditor) targetEditor;
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/ExternalEditorInput.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/ExternalEditorInput.java
new file mode 100644 (file)
index 0000000..07be7dc
--- /dev/null
@@ -0,0 +1,101 @@
+package net.sourceforge.phpeclipse.builder;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * An EditorInput for an external file.
+ */
+public class ExternalEditorInput implements IStorageEditorInput {
+
+       IStorage externalFile;
+
+       /**
+        * Two ExternalEditorInputs are equal if their IStorage's are equal.
+        * 
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (!(obj instanceof ExternalEditorInput))
+                       return false;
+               ExternalEditorInput other = (ExternalEditorInput) obj;
+               return externalFile.equals(other.externalFile);
+       }
+
+       /*
+        * @see IEditorInput#exists()
+        */
+       public boolean exists() {
+               // External file can not be deleted
+               return true;
+       }
+
+       /*
+        * @see IAdaptable#getAdapter(Class)
+        */
+       public Object getAdapter(Class adapter) {
+               return null;
+       }
+
+       /*
+        * @see IEditorInput#getContentType()
+        */
+       public String getContentType() {
+               return externalFile.getFullPath().getFileExtension();
+       }
+
+       /*
+        * @see IEditorInput#getFullPath()
+        */
+       public String getFullPath() {
+               return externalFile.getFullPath().toString();
+       }
+
+       /*
+        * @see IEditorInput#getImageDescriptor()
+        */
+       public ImageDescriptor getImageDescriptor() {
+               IEditorRegistry registry = PlatformUI.getWorkbench()
+                               .getEditorRegistry();
+               return registry.getImageDescriptor(externalFile.getFullPath()
+                               .getFileExtension());
+       }
+
+       /*
+        * @see IEditorInput#getName()
+        */
+       public String getName() {
+               return externalFile.getName();
+       }
+
+       /*
+        * @see IEditorInput#getPersistable()
+        */
+       public IPersistableElement getPersistable() {
+               return null;
+       }
+
+       /*
+        * see IStorageEditorInput#getStorage()
+        */
+       public IStorage getStorage() {
+               return externalFile;
+       }
+
+       /*
+        * @see IEditorInput#getToolTipText()
+        */
+       public String getToolTipText() {
+               return externalFile.getFullPath().toString();
+       }
+
+       public ExternalEditorInput(IStorage exFile) {
+               externalFile = exFile;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/ExternalStorageDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/ExternalStorageDocumentProvider.java
new file mode 100644 (file)
index 0000000..c1d2ad5
--- /dev/null
@@ -0,0 +1,60 @@
+package net.sourceforge.phpeclipse.builder;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.editors.text.StorageDocumentProvider;
+
+/**
+ * @author ed
+ * @version 1.0, May 19, 2003
+ */
+public class ExternalStorageDocumentProvider extends StorageDocumentProvider {
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor,
+        *      java.lang.Object, org.eclipse.jface.text.IDocument, boolean)
+        */
+       protected void doSaveDocument(IProgressMonitor monitor, Object element,
+                       IDocument document, boolean overwrite) throws CoreException {
+               if (element instanceof ExternalEditorInput) {
+                       ExternalEditorInput external = (ExternalEditorInput) element;
+                       FileStorage storage = (FileStorage) external.getStorage();
+                       String encoding = getEncoding(element);
+                       if (encoding == null)
+                               encoding = getDefaultEncoding();
+                       try {
+                               InputStream stream = new ByteArrayInputStream(document.get()
+                                               .getBytes(encoding));
+                               try {
+                                       // inform about the upcoming content change
+                                       fireElementStateChanging(element);
+                                       storage.setContents(stream, overwrite, true, monitor);
+                               } catch (RuntimeException e) {
+                                       // inform about failure
+                                       fireElementStateChangeFailed(element);
+                                       throw e;
+                               }
+                       } catch (IOException e) {
+                               IStatus s = new Status(IStatus.ERROR,
+                                               PHPeclipsePlugin.PLUGIN_ID, IStatus.OK, e.getMessage(),
+                                               e);
+                               throw new CoreException(s);
+                       }
+
+               } else {
+                       super.doSaveDocument(monitor, element, document, overwrite);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/FileStorage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/FileStorage.java
new file mode 100644 (file)
index 0000000..685ff79
--- /dev/null
@@ -0,0 +1,137 @@
+package net.sourceforge.phpeclipse.builder;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.sourceforge.phpdt.internal.core.util.StreamUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.Status;
+
+/*
+ * (c) Copyright QNX Software Systems Ltd. 2002.
+ * All Rights Reserved.
+ */
+
+/**
+ * 
+ * @see IStorage
+ */
+public class FileStorage extends PlatformObject implements IStorage {
+       private boolean forceReadOnly;
+
+       private final IPath path;
+
+       private final File file;
+
+       /**
+        * Two FileStorages are equal if their IPaths are equal.
+        * 
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (!(obj instanceof FileStorage))
+                       return false;
+               FileStorage other = (FileStorage) obj;
+               return path.equals(other.path);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.core.resources.IStorage#getContents()
+        */
+       public InputStream getContents() throws CoreException {
+               try {
+                       return new FileInputStream(file);
+               } catch (FileNotFoundException e) {
+                       throw new CoreException(new Status(IStatus.ERROR,
+                                       PHPeclipsePlugin.PLUGIN_ID, IStatus.ERROR, e.toString(), e));
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.core.resources.IStorage#getFullPath()
+        */
+       public IPath getFullPath() {
+               return this.path;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.core.resources.IStorage#getName()
+        */
+       public String getName() {
+               return this.path.lastSegment();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.core.resources.IStorage#isReadOnly()
+        */
+       public boolean isReadOnly() {
+               return forceReadOnly || !file.canWrite();
+       }
+
+       /**
+        * Method FileStorage.
+        * 
+        * @param path
+        */
+       public FileStorage(IPath path) {
+               this.path = path;
+               this.file = path.toFile();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#toString()
+        */
+       public String toString() {
+               return path.toOSString();
+       }
+
+       /**
+        * @param stream
+        * @param overwrite
+        * @param b
+        * @param monitor
+        */
+       public void setContents(InputStream stream, boolean overwrite, boolean b,
+                       IProgressMonitor monitor) throws CoreException {
+               try {
+                       StreamUtil.transferStreams(stream, new FileOutputStream(file));
+               } catch (FileNotFoundException e) {
+                       throw new CoreException(new Status(IStatus.ERROR,
+                                       PHPeclipsePlugin.PLUGIN_ID, IStatus.ERROR, e.toString(), e));
+               } catch (IOException e) {
+                       throw new CoreException(new Status(IStatus.ERROR,
+                                       PHPeclipsePlugin.PLUGIN_ID, IStatus.ERROR, e.toString(), e));
+               }
+       }
+
+       /**
+        * Some document providers (notably CompilationUnitDocumentProvider) can't
+        * handle read/write storage.
+        */
+       public void setReadOnly() {
+               forceReadOnly = true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java
new file mode 100644 (file)
index 0000000..18f3458
--- /dev/null
@@ -0,0 +1,1029 @@
+package net.sourceforge.phpeclipse.builder;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.obfuscator.PHPIdentifier;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * Manages the identifer index information for a specific project
+ * 
+ */
+public class IdentifierIndexManager {
+       public class LineCreator implements ITerminalSymbols {
+               private Scanner fScanner;
+
+               private int fToken;
+
+               public LineCreator() {
+                       fScanner = new Scanner(true, false, false, false, true, null, null,
+                                       true /* taskCaseSensitive */);
+               }
+
+               /**
+                * Add the information of the current identifier to the line
+                * 
+                * @param typeOfIdentifier
+                *            the type of the identifier ('c'lass, 'd'efine, 'f'unction,
+                *            'm'ethod(class), 'v'ariable(class) 'g'lobal variable)
+                * @param identifier
+                *            current identifier
+                * @param line
+                *            Buffer for the current index line
+                */
+               private void addIdentifierInformation(char typeOfIdentifier,
+                               char[] identifier, StringBuffer line) {
+                       line.append('\t');
+                       line.append(typeOfIdentifier);
+                       line.append(identifier);
+               }
+
+               /**
+                * Add the information of the current identifier to the line
+                * 
+                * @param typeOfIdentifier
+                *            the type of the identifier ('c'lass, 'd'efine, 'f'unction,
+                *            'm'ethod(class), 'v'ariable(class) 'g'lobal variable)
+                * @param identifier
+                *            current identifier
+                * @param line
+                *            Buffer for the current index line
+                * @param phpdocOffset
+                *            the offset of the PHPdoc comment if available
+                * @param phpdocLength
+                *            the length of the PHPdoc comment if available
+                */
+               private void addIdentifierInformation(char typeOfIdentifier,
+                               char[] identifier, StringBuffer line, int phpdocOffset,
+                               int phpdocLength) {
+                       line.append('\t');
+                       line.append(typeOfIdentifier);
+                       line.append(identifier);
+                       line.append("\to"); // Offset
+                       line.append(fScanner.getCurrentTokenStartPosition());
+                       if (phpdocOffset >= 0) {
+                               line.append("\tp"); // phpdoc offset
+                               line.append(phpdocOffset);
+                               line.append("\tl"); // phpdoc length
+                               line.append(phpdocLength);
+                       }
+               }
+
+               private void addClassVariableInformation(char typeOfIdentifier,
+                               char[] identifier, StringBuffer line, int phpdocOffset,
+                               int phpdocLength) {
+                       line.append('\t');
+                       line.append(typeOfIdentifier);
+                       line.append(identifier);
+                       line.append("\to"); // Offset
+                       // we don't store the '$' in the index for class variables:
+                       line.append(fScanner.getCurrentTokenStartPosition() + 1);
+                       if (phpdocOffset >= 0) {
+                               line.append("\tp"); // phpdoc offset
+                               line.append(phpdocOffset);
+                               line.append("\tl"); // phpdoc length
+                               line.append(phpdocLength);
+                       }
+               }
+
+               /**
+                * Get the next token from input
+                */
+               private void getNextToken() throws InvalidInputException {
+                       // try {
+                       fToken = fScanner.getNextToken();
+                       if (Scanner.DEBUG) {
+                               int currentEndPosition = fScanner.getCurrentTokenEndPosition();
+                               int currentStartPosition = fScanner
+                                               .getCurrentTokenStartPosition();
+                               System.out.print(currentStartPosition + ","
+                                               + currentEndPosition + ": ");
+                               System.out.println(fScanner.toStringAction(fToken));
+                       }
+                       return;
+               }
+
+               private void skipComments()
+               {
+                       try {
+                               getNextToken();
+                               while (fToken == TokenNameCOMMENT_BLOCK  || fToken == TokenNameCOMMENT_PHPDOC) {
+                                               getNextToken();
+                               }
+                       } catch (InvalidInputException e1) {
+                               // TODO Auto-generated catch block
+                               e1.printStackTrace();
+                       }
+               }
+               
+               private void parseDeclarations(char[] parent, StringBuffer buf,
+                               boolean goBack) {
+                       char[] ident;
+                       char[] classVariable;
+                       int counter = 0;
+                       boolean hasModifiers = false;
+                       int phpdocOffset = -1;
+                       int phpdocLength = -1;
+                       try {
+                               while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
+                                       phpdocOffset = -1;
+                                       hasModifiers = false;
+                                       if (fToken == TokenNameCOMMENT_PHPDOC) {
+                                               phpdocOffset = fScanner.getCurrentTokenStartPosition();
+                                               phpdocLength = fScanner.getCurrentTokenEndPosition()
+                                                               - fScanner.getCurrentTokenStartPosition() + 1;
+                                               getNextToken();
+                                               while (fToken == TokenNamestatic
+                                                               || fToken == TokenNamefinal
+                                                               || fToken == TokenNamepublic
+                                                               || fToken == TokenNameprotected
+                                                               || fToken == TokenNameprivate
+                                                               || fToken == TokenNameabstract) {
+                                                       hasModifiers = true;
+                                                       getNextToken();
+                                               }
+                                               if (fToken == TokenNameEOF || fToken == TokenNameERROR) {
+                                                       break;
+                                               }
+                                       }
+                                       if (fToken == TokenNamefunction) {
+                                               skipComments();
+                                               if (fToken == TokenNameAND) {
+                                                       getNextToken();
+                                               }
+                                               if (fToken == TokenNameIdentifier) {
+                                                       ident = fScanner.getCurrentIdentifierSource();
+                                                       if (parent != null
+                                                                       && equalCharArrays(parent, ident)) {
+                                                               // constructor function
+                                                               addIdentifierInformation('k', ident, buf,
+                                                                               phpdocOffset, phpdocLength);
+                                                       } else {
+                                                               if (parent != null) {
+                                                                       // class method function
+                                                                       addIdentifierInformation('m', ident, buf,
+                                                                                       phpdocOffset, phpdocLength);
+                                                               } else {
+                                                                       // nested function ?!
+                                                                       addIdentifierInformation('f', ident, buf,
+                                                                                       phpdocOffset, phpdocLength);
+                                                               }
+                                                       }
+                                                       skipComments();
+                                                       parseDeclarations(null, buf, true);
+                                               }
+                                       } else if (fToken == TokenNameclass
+                                                       || fToken == TokenNameinterface) {
+                                               skipComments();
+                                               if (fToken == TokenNameIdentifier) {
+                                                       ident = fScanner.getCurrentIdentifierSource();
+                                                       addIdentifierInformation('c', ident, buf,
+                                                                       phpdocOffset, phpdocLength);
+                                                       skipComments();
+                                                       if (fToken == TokenNameextends) {
+                                                               skipComments();
+                                                               while (fToken == TokenNameIdentifier) {
+                                                                       ident = fScanner
+                                                                                       .getCurrentIdentifierSource();
+                                                                       // extends ident
+                                                                       addIdentifierInformation('e', ident, buf);
+                                                                       skipComments();
+                                                               if (fToken == TokenNameCOMMA) {
+                                                                       skipComments();
+                                                                       }
+                                                               }
+                                                       }
+                                                       if (fToken == TokenNameimplements) {
+                                                               skipComments();
+                                                               while (fToken == TokenNameIdentifier) {
+                                                                       ident = fScanner
+                                                                                       .getCurrentIdentifierSource();
+                                                                       // implements ident
+                                                                       addIdentifierInformation('e', ident, buf);
+                                                                       skipComments();
+                                                                       if (fToken == TokenNameCOMMA) {
+                                                                               skipComments();
+//                                                                             getNextToken();
+                                                                       }
+                                                               }
+                                                       }
+                                                       // skip tokens for classname, extends and others
+                                                       // until we have
+                                                       // the opening '{'
+                                                       while (fToken != TokenNameLBRACE
+                                                                       && fToken != TokenNameEOF
+                                                                       && fToken != TokenNameERROR) {
+                                                               getNextToken();
+                                                       }
+                                                       parseDeclarations(ident, buf, true);
+                                               }
+                                       } else if (fToken == TokenNamevar || hasModifiers
+                                                       || fToken == TokenNamestatic
+                                                       || fToken == TokenNamefinal
+                                                       || fToken == TokenNamepublic
+                                                       || fToken == TokenNameprotected
+                                                       || fToken == TokenNameprivate) {
+                                               while (fToken == TokenNamevar
+                                                               || fToken == TokenNamestatic
+                                                               || fToken == TokenNamefinal
+                                                               || fToken == TokenNamepublic
+                                                               || fToken == TokenNameprotected
+                                                               || fToken == TokenNameprivate) {
+                                                       skipComments();
+                                               }
+                                               while (fToken == TokenNameVariable) {
+                                                       ident = fScanner.getCurrentIdentifierSource();
+                                                       classVariable = new char[ident.length - 1];
+                                                       System.arraycopy(ident, 1, classVariable, 0,
+                                                                       ident.length - 1);
+                                                       addClassVariableInformation('v', classVariable,
+                                                                       buf, phpdocOffset, phpdocLength);
+                                                       skipComments();
+                                                       if (fToken == TokenNameCOMMA) {
+                                                               skipComments();
+                                                       }
+                                               }
+                                       } else if (!hasModifiers && fToken == TokenNameIdentifier) {
+                                               ident = fScanner.getCurrentIdentifierSource();
+                                               getNextToken();
+                                               if (ident.length == 6 && ident[0] == 'd'
+                                                               && ident[1] == 'e' && ident[2] == 'f'
+                                                               && ident[3] == 'i' && ident[4] == 'n'
+                                                               && ident[5] == 'e') {
+                                                       if (fToken == TokenNameLPAREN) {
+                                                               getNextToken();
+                                                               if (fToken == TokenNameStringDoubleQuote) {
+                                                                       ident = fScanner
+                                                                                       .getCurrentStringLiteralSource();
+                                                                       addIdentifierInformation('d', ident, buf,
+                                                                                       phpdocOffset, phpdocLength);
+                                                                       getNextToken();
+                                                               } else if (fToken == TokenNameStringSingleQuote) {
+                                                                       ident = fScanner
+                                                                                       .getCurrentStringLiteralSource();
+                                                                       addIdentifierInformation('d', ident, buf,
+                                                                                       phpdocOffset, phpdocLength);
+                                                                       getNextToken();
+                                                               }
+                                                       }
+                                               }
+                                       } else if (fToken == TokenNameglobal) {
+                                               // global variable
+                                               while (fToken != TokenNameEOF
+                                                               && fToken != TokenNameERROR
+                                                               && fToken != TokenNameSEMICOLON
+                                                               && fToken != TokenNameLBRACE
+                                                               && fToken != TokenNameRBRACE) {
+                                                       getNextToken();
+                                                       if (fToken == TokenNameVariable) {
+                                                               ident = fScanner.getCurrentIdentifierSource();
+                                                               addIdentifierInformation('g', ident, buf,
+                                                                               phpdocOffset, phpdocLength);
+                                                       }
+                                               }
+                                       } else if (fToken == TokenNameLBRACE) {
+                                               getNextToken();
+                                               counter++;
+                                       } else if (fToken == TokenNameRBRACE) {
+                                               getNextToken();
+                                               --counter;
+                                               if (counter == 0 && goBack) {
+                                                       return;
+                                               }
+                                       } else {
+                                               getNextToken();
+                                       }
+                               }
+                       } catch (InvalidInputException e) {
+                               // ignore errors
+                       } catch (SyntaxError e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+               }
+
+               synchronized public void parseIdentifiers(char[] charArray,
+                               StringBuffer buf) {
+                       char[] ident;
+                       String identifier;
+                       boolean hasModifiers = false;
+                       int phpdocOffset = -1;
+                       int phpdocLength = -1;
+                       fScanner.setSource(charArray);
+                       fScanner.setPHPMode(false);
+                       fToken = TokenNameEOF;
+                       try {
+                               getNextToken();
+                               while (fToken != TokenNameEOF) { // && fToken !=
+                                       // TokenNameERROR) {
+                                       phpdocOffset = -1;
+                                       hasModifiers = false;
+                                       switch (fToken) {
+                                       case TokenNameCOMMENT_PHPDOC:
+                                               phpdocOffset = fScanner.getCurrentTokenStartPosition();
+                                               phpdocLength = fScanner.getCurrentTokenEndPosition()
+                                                               - fScanner.getCurrentTokenStartPosition() + 1;
+                                               getNextToken();
+                                               while (fToken == TokenNamestatic
+                                                               || fToken == TokenNamefinal
+                                                               || fToken == TokenNamepublic
+                                                               || fToken == TokenNameprotected
+                                                               || fToken == TokenNameprivate
+                                                               || fToken == TokenNameabstract) {
+                                                       hasModifiers = true;
+                                                       getNextToken();
+                                               }
+                                               if (fToken == TokenNameEOF || fToken == TokenNameERROR) {
+                                                       break;
+                                               }
+                                               break;
+                                               
+                                       case TokenNamefunction:
+                                               skipComments();
+                                               if (fToken == TokenNameAND) {
+                                                       getNextToken();
+                                               }
+                                               if (fToken == TokenNameIdentifier) {
+                                                       ident = fScanner.getCurrentIdentifierSource();
+                                                       addIdentifierInformation('f', ident, buf,
+                                                                       phpdocOffset, phpdocLength);
+                                                       skipComments();
+                                                       if (fToken == TokenNameLPAREN) {
+                                                               skipComments();
+                                                               do {
+                                                                       if (fToken == TokenNameVariable) {
+                                                                               ident = fScanner.getCurrentIdentifierSource();
+                                                                               addIdentifierInformation('v', ident, buf,
+                                                                                               phpdocOffset, phpdocLength);
+                                                                               skipComments();
+                                                                               if (fToken == TokenNameCOMMA) {
+                                                                                       skipComments();
+                                                                               }
+                                                                       }       
+                                                               } while (fToken != TokenNameRPAREN );
+                                                       }
+                                                       parseDeclarations(null, buf, true);
+                                               }
+                                               break;
+                                               
+                                       case TokenNameclass:
+                                       case TokenNameinterface:
+                                               skipComments();
+                                               if (fToken == TokenNameIdentifier) {
+                                                       ident = fScanner.getCurrentIdentifierSource();
+                                                       addIdentifierInformation('c', ident, buf,
+                                                                       phpdocOffset, phpdocLength);
+                                                       skipComments();
+                                                       if (fToken == TokenNameextends) {
+                                                               skipComments();
+                                                               while (fToken == TokenNameIdentifier) {
+                                                                       ident = fScanner
+                                                                                       .getCurrentIdentifierSource();
+                                                                       // extends ident
+                                                                       addIdentifierInformation('e', ident, buf);
+                                                                       skipComments();
+                                                                       if (fToken == TokenNameCOMMA) {
+                                                                               skipComments();
+                                                                       }
+                                                               }
+                                                       }
+                                                       if (fToken == TokenNameimplements) {
+                                                               skipComments();
+                                                               while (fToken == TokenNameIdentifier) {
+                                                                       ident = fScanner
+                                                                                       .getCurrentIdentifierSource();
+                                                                       // implements ident
+                                                                       addIdentifierInformation('e', ident, buf);
+                                                                       skipComments();
+                                                                       if (fToken == TokenNameCOMMA) {
+                                                                               skipComments();
+                                                                       }
+                                                               }
+                                                       }
+                                                       // skip fTokens for classname, extends and others
+                                                       // until we have
+                                                       // the opening '{'
+                                                       while (fToken != TokenNameLBRACE
+                                                                       && fToken != TokenNameEOF
+                                                                       && fToken != TokenNameERROR) {
+                                                               getNextToken();
+                                                       }
+                                                       parseDeclarations(ident, buf, true);
+                                               }
+                                               break;
+
+                                       case TokenNameVariable:
+                                               // global variable
+                                               ident = fScanner.getCurrentIdentifierSource();
+                                               addIdentifierInformation('g', ident, buf, phpdocOffset,
+                                                               phpdocLength);
+                                               getNextToken();
+                                               break;
+
+                                       default:
+                                               getNextToken();
+                                       }
+                                       
+                               }
+                       } catch (InvalidInputException e) {
+                               // ignore errors
+                       } catch (SyntaxError e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+               }
+       }
+               
+       class StringComparator implements Comparator {
+               public int compare(Object o1, Object o2) {
+                       String s1 = (String) o1;
+                       String s2 = (String) o2;
+                       return s1.compareTo(s2);
+                       // return s1.toUpperCase().compareTo(s2.toUpperCase());
+               }
+
+               public boolean equals(Object o) {
+                       String s = (String) o;
+                       return compare(this, o) == 0;
+               }
+       }
+
+       private HashMap fFileMap;
+
+       private String fFilename;
+
+       private TreeMap fIndentifierMap;
+
+       public IdentifierIndexManager(String filename) {
+               fFilename = filename;
+               initialize();
+               readFile();
+       }
+
+       /**
+        * Check if 2 char arrays are equal
+        * 
+        * @param a
+        * @param b
+        * @return
+        */
+       private static boolean equalCharArrays(char[] a, char[] b) {
+               if (a.length != b.length) {
+                       return false;
+               }
+               for (int i = 0; i < b.length; i++) {
+                       if (a[i] != b[i]) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       public LineCreator createLineCreator() {
+               return new LineCreator();
+       }
+
+       /**
+        * Add the information for a given IFile resource
+        * 
+        */
+       public void addFile(IFile fileToParse) {
+               LineCreator lineCreator = createLineCreator();
+               try {
+                       addInputStream(new BufferedInputStream(fileToParse.getContents()),
+                                       fileToParse.getProjectRelativePath().toString(),
+                                       lineCreator, fileToParse.getCharset());
+               } catch (CoreException e1) {
+                       // TODO Auto-generated catch block
+                       e1.printStackTrace();
+               }
+       }
+
+       /**
+        * @param fileToParse
+        * @param lineCreator
+        * @throws CoreException
+        */
+       public void addInputStream(InputStream stream, String filePath,
+                       LineCreator lineCreator, String charset) throws CoreException {
+               try {
+                       StringBuffer lineBuffer = new StringBuffer();
+                       lineBuffer.append(filePath);
+                       lineCreator.parseIdentifiers(Util.getInputStreamAsCharArray(stream,
+                                       -1, charset), lineBuffer);
+                       addLine(lineBuffer.toString());
+               } catch (IOException e) {
+                       e.printStackTrace();
+               } finally {
+                       try {
+                               if (stream != null) {
+                                       stream.close();
+                               }
+                       } catch (IOException e) {
+                               // do nothing
+                       }
+               }
+       }
+
+       /**
+        * Adds a line of the index file for function, class, class-method and
+        * class-variable names
+        * 
+        * @param line
+        */
+       private void addLine(String line) {
+               addLine(fIndentifierMap, fFileMap, line, null);
+       }
+
+       public TreeMap getIdentifiers(IFile file) {
+               TreeMap treeMap = new TreeMap(new StringComparator());
+               addIdentifiers(treeMap, file);
+               return treeMap;
+       }
+
+       public TreeMap getIdentifiers(String startClazz) {
+               TreeMap treeMap = new TreeMap(new StringComparator());
+               addIdentifiers(treeMap, startClazz);
+               return treeMap;
+       }
+
+       public void addIdentifiers(TreeMap treeMap, IFile file) {
+               String line = (String) fFileMap.get(file.getProjectRelativePath()
+                               .toString());
+               if (line != null) {
+                       PHPIdentifierLocation ident;
+                       ArrayList allClassNames = new ArrayList();
+                       addLine(treeMap, null, line, allClassNames);
+                       int i = 0;
+                       while (i < allClassNames.size()) {
+                               String clazz = (String) allClassNames.get(i++);
+                               addClassName(treeMap, clazz, allClassNames);
+                       }
+               }
+       }
+
+       public void addIdentifiers(TreeMap treeMap, String startClazz) {
+               PHPIdentifierLocation ident;
+               ArrayList allClassNames = new ArrayList();
+               addClassName(treeMap, startClazz, allClassNames);
+               int i = 0;
+               while (i < allClassNames.size()) {
+                       String clazz = (String) allClassNames.get(i++);
+                       addClassName(treeMap, clazz, allClassNames);
+               }
+       }
+
+       /**
+        * @param treeMap
+        * @param clazz
+        * @param allClassNames
+        */
+       private boolean addClassName(TreeMap treeMap, String clazz,
+                       List allClassNames) {
+               String line;
+               PHPIdentifierLocation ident;
+               List list = getLocations(clazz);
+               if (list == null) {
+                       return false;
+               }
+               boolean result = false;
+               for (int i = 0; i < list.size(); i++) {
+                       ident = (PHPIdentifierLocation) list.get(i);
+                       if (ident.isClass()) {
+                               line = (String) fFileMap.get(ident.getFilename());
+                               addLine(treeMap, null, line, allClassNames);
+                               result = true;
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * Adds a line of the index file for function, class, class-method and
+        * class-variable names
+        * 
+        * @param line
+        */
+       public void addLine(TreeMap treeMap, HashMap fileMap, String line,
+                       List allClassNames) {
+               StringTokenizer tokenizer;
+               String phpFileName = null;
+               String token;
+               String identifier = null;
+               String classname = null;
+               String offset = null;
+               PHPIdentifierLocation phpIdentifier = null;
+               boolean tokenExists = false;
+               tokenizer = new StringTokenizer(line, "\t");
+               // first token contains the filename:
+               try {
+                       if (tokenizer.hasMoreTokens()) {
+                               phpFileName = tokenizer.nextToken();
+                               // System.out.println(token);
+                       } else {
+                               return;
+                       }
+                       // all the other tokens are identifiers:
+                       while (tokenizer.hasMoreTokens()) {
+                               token = tokenizer.nextToken();
+                               // System.out.println(token);
+                               switch (token.charAt(0)) {
+                               case 'c':
+                                       // class name
+                                       identifier = token.substring(1);
+                                       classname = identifier;
+                                       phpIdentifier = new PHPIdentifierLocation(identifier,
+                                                       PHPIdentifier.CLASS, phpFileName);
+                                       break;
+                               case 'd':
+                                       // define
+                                       identifier = token.substring(1);
+                                       phpIdentifier = new PHPIdentifierLocation(identifier,
+                                                       PHPIdentifier.DEFINE, phpFileName);
+                                       break;
+                               case 'e':
+                                       // extends <class name>
+                                       // not in map
+                                       identifier = null;
+                                       phpIdentifier = null;
+                                       if (allClassNames != null) {
+                                               String extName = token.substring(1);
+                                               if (!allClassNames.contains(extName)) {
+                                                       allClassNames.add(extName);
+                                               }
+                                       }
+                                       break;
+                               case 'f':
+                                       // function name
+                                       identifier = token.substring(1);
+                                       phpIdentifier = new PHPIdentifierLocation(identifier,
+                                                       PHPIdentifier.FUNCTION, phpFileName);
+                                       break;
+                               case 'g':
+                                       // global variable
+                                       identifier = token.substring(1);
+                                       phpIdentifier = new PHPIdentifierLocation(identifier,
+                                                       PHPIdentifier.GLOBAL_VARIABLE, phpFileName);
+                                       break;
+                               case 'i':
+                                       // implements <class name>
+                                       // not in map
+                                       identifier = null;
+                                       phpIdentifier = null;
+                                       if (allClassNames != null) {
+                                               String implName = token.substring(1);
+                                               if (!allClassNames.contains(implName)) {
+                                                       allClassNames.add(implName);
+                                               }
+                                       }
+                                       break;
+                               case 'k':
+                                       // constructor function name
+                                       identifier = token.substring(1);
+                                       phpIdentifier = new PHPIdentifierLocation(identifier,
+                                                       PHPIdentifier.CONSTRUCTOR, phpFileName);
+                                       break;
+                               case 'm':
+                                       // method inside a class
+                                       identifier = token.substring(1);
+                                       phpIdentifier = new PHPIdentifierLocation(identifier,
+                                                       PHPIdentifier.METHOD, phpFileName, classname);
+                                       break;
+                               case 'v':
+                                       // variable inside a class
+                                       identifier = token.substring(1);
+                                       phpIdentifier = new PHPIdentifierLocation(identifier,
+                                                       PHPIdentifier.VARIABLE, phpFileName, classname);
+                                       break;
+                               case 'o':
+                                       // offset information
+                                       identifier = null;
+                                       if (phpIdentifier != null) {
+                                               offset = token.substring(1);
+                                               phpIdentifier.setOffset(Integer.parseInt(offset));
+                                       }
+                                       break;
+                               case 'p':
+                                       // PHPdoc offset information
+                                       identifier = null;
+                                       if (phpIdentifier != null) {
+                                               offset = token.substring(1);
+                                               phpIdentifier.setPHPDocOffset(Integer.parseInt(offset));
+                                       }
+                                       break;
+                               case 'l':
+                                       // PHPdoc length information
+                                       identifier = null;
+                                       if (phpIdentifier != null) {
+                                               offset = token.substring(1);
+                                               phpIdentifier.setPHPDocLength(Integer.parseInt(offset));
+                                       }
+                                       break;
+                               default:
+                                       PHPeclipsePlugin.log(IStatus.ERROR,
+                                                       "Unknown token character in IdentifierIndexManager: "
+                                                                       + token.charAt(0));
+                                       identifier = null;
+                                       phpIdentifier = null;
+                                       classname = null;
+                               }
+                               if (identifier != null && phpIdentifier != null) {
+                                       tokenExists = true;
+                                       ArrayList list = (ArrayList) treeMap.get(identifier);
+                                       if (list == null) {
+                                               list = new ArrayList();
+                                               list.add(phpIdentifier);
+                                               treeMap.put(identifier, list);
+                                       } else {
+                                               boolean flag = false;
+                                               for (int i = 0; i < list.size(); i++) {
+                                                       if (list.get(i).equals(phpIdentifier)) {
+                                                               flag = true;
+                                                               break;
+                                                       }
+                                               }
+                                               if (flag == false) {
+                                                       list.add(phpIdentifier);
+                                               }
+                                       }
+                               }
+                       }
+                       if (fileMap != null) {
+                               fileMap.put(phpFileName, line);
+                       }
+               } catch (Throwable e) {
+                       // write to workspace/.metadata/.log file
+                       PHPeclipsePlugin.log(e);
+               }
+               // if (tokenExists) {
+
+               // }
+       }
+
+       /**
+        * Change the information for a given IFile resource
+        * 
+        */
+       public void changeFile(IFile fileToParse) {
+               removeFile(fileToParse);
+               addFile(fileToParse);
+       }
+
+       /**
+        * Get a list of all PHPIdentifierLocation object's associated with an
+        * identifier
+        * 
+        * @param identifier
+        * @return
+        */
+       public List getLocations(String identifier) {
+               List list = (List) fIndentifierMap.get(identifier);
+               if (list != null) {
+                       return list;
+               }
+               return new ArrayList();
+       }
+
+       /**
+        * Initialize (i.e. clear) the current index information
+        * 
+        */
+       public void initialize() {
+               fIndentifierMap = new TreeMap(new StringComparator());
+               fFileMap = new HashMap();
+       }
+
+       private void readFile() {
+               FileReader fileReader;
+               try {
+                       fileReader = new FileReader(fFilename);
+                       BufferedReader bufferedReader = new BufferedReader(fileReader);
+                       String line;
+                       while (bufferedReader.ready()) {
+                               // all entries for one file are in a line
+                               // separated by tabs !
+                               line = bufferedReader.readLine();
+                               addLine(line);
+                       }
+                       fileReader.close();
+               } catch (FileNotFoundException e) {
+                       // ignore this
+                       // TODO DialogBox which asks the user if she/he likes to build new
+                       // index?
+               } catch (IOException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Remove the information for a given IFile resource
+        * 
+        */
+       public void removeFile(IFile fileToParse) {
+               // String line = (String)
+               // fFileMap.get(fileToParse.getLocation().toString());
+               String line = (String) fFileMap.get(fileToParse
+                               .getProjectRelativePath().toString());
+               if (line != null) {
+                       removeLine(line);
+               }
+       }
+
+       /**
+        * Removes a line of the index file for function, class, class-method and
+        * class-variable names
+        * 
+        * @param line
+        */
+       private void removeLine(String line) {
+               StringTokenizer tokenizer;
+               String phpFileName = null;
+               String token;
+               String identifier = null;
+               String classname = null;
+               PHPIdentifier phpIdentifier = null;
+               boolean tokenExists = false;
+               tokenizer = new StringTokenizer(line, "\t");
+               // first token contains the filename:
+               if (tokenizer.hasMoreTokens()) {
+                       phpFileName = tokenizer.nextToken();
+                       // System.out.println(token);
+               } else {
+                       return;
+               }
+               int offset = -1;
+               // all the other tokens are identifiers:
+               while (tokenizer.hasMoreTokens()) {
+                       token = tokenizer.nextToken();
+                       // System.out.println(token);
+                       switch (token.charAt(0)) {
+                       case 'c':
+                               // class name
+                               identifier = token.substring(1);
+                               classname = identifier;
+                               phpIdentifier = new PHPIdentifierLocation(identifier,
+                                               PHPIdentifier.CLASS, phpFileName);
+                               break;
+                       case 'd':
+                               // define
+                               identifier = token.substring(1);
+                               phpIdentifier = new PHPIdentifierLocation(identifier,
+                                               PHPIdentifier.DEFINE, phpFileName);
+                               break;
+                       case 'e':
+                               // extends <class name>
+                               identifier = null;
+                               phpIdentifier = null;
+                               break;
+                       case 'f':
+                               // function name
+                               identifier = token.substring(1);
+                               phpIdentifier = new PHPIdentifierLocation(identifier,
+                                               PHPIdentifier.FUNCTION, phpFileName);
+                               break;
+                       case 'g':
+                               // global variable
+                               identifier = token.substring(1);
+                               phpIdentifier = new PHPIdentifierLocation(identifier,
+                                               PHPIdentifier.GLOBAL_VARIABLE, phpFileName);
+                               break;
+                       case 'i':
+                               // implements <class name>
+                               identifier = null;
+                               phpIdentifier = null;
+                               break;
+                       case 'k':
+                               // constructor function name
+                               identifier = token.substring(1);
+                               phpIdentifier = new PHPIdentifierLocation(identifier,
+                                               PHPIdentifier.CONSTRUCTOR, phpFileName);
+                               break;
+                       case 'm':
+                               // method inside a class
+                               identifier = token.substring(1);
+                               phpIdentifier = new PHPIdentifierLocation(identifier,
+                                               PHPIdentifier.METHOD, phpFileName, classname);
+                               break;
+                       case 'o':
+                               // offset information
+                               identifier = null;
+                               break;
+                       case 'p':
+                               // PHPdoc offset information
+                               identifier = null;
+                               break;
+                       case 'l':
+                               // PHPdoc length information
+                               identifier = null;
+                               break;
+                       case 'v':
+                               // variable inside a class
+                               identifier = token.substring(1);
+                               phpIdentifier = new PHPIdentifierLocation(identifier,
+                                               PHPIdentifier.VARIABLE, phpFileName, classname);
+                               break;
+                       default:
+                               PHPeclipsePlugin.log(IStatus.ERROR,
+                                               "Unknown token character in IdentifierIndexManager: "
+                                                               + token.charAt(0));
+                               identifier = null;
+                               phpIdentifier = null;
+                               classname = null;
+                       }
+                       if (identifier != null && phpIdentifier != null) {
+                               ArrayList list = (ArrayList) fIndentifierMap.get(identifier);
+                               if (list == null) {
+                               } else {
+                                       for (int i = 0; i < list.size(); i++) {
+                                               if (list.get(i).equals(phpIdentifier)) {
+                                                       list.remove(i);
+                                                       break;
+                                               }
+                                       }
+                                       if (list.size() == 0) {
+                                               fIndentifierMap.remove(identifier);
+                                       }
+                               }
+                       }
+               }
+               fFileMap.remove(phpFileName);
+       }
+
+       /**
+        * Save the current index information in the projects index file
+        * 
+        */
+       public void writeFile() {
+               FileWriter fileWriter;
+               try {
+                       fileWriter = new FileWriter(fFilename);
+                       String line;
+                       Collection collection = fFileMap.values();
+                       Iterator iterator = collection.iterator();
+                       while (iterator.hasNext()) {
+                               line = (String) iterator.next();
+                               fileWriter.write(line + '\n');
+                       }
+                       fileWriter.close();
+               } catch (FileNotFoundException e) {
+                       // ignore exception; project is deleted by user
+               } catch (IOException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * @param fromKey
+        * @param toKey
+        * @return
+        */
+       public SortedMap getIdentifierMap() {
+               return fIndentifierMap;
+       }
+
+       synchronized public List getFileList(String filePattern) {
+               Set set = fFileMap.keySet();
+               if (set.isEmpty()) {
+                       return null;
+               }
+               Iterator iter = set.iterator();
+               ArrayList list = new ArrayList();
+               String fileName;
+               int index;
+               while (iter.hasNext()) {
+                       fileName = (String) iter.next();
+                       if ((index = fileName.indexOf(filePattern)) != -1
+                                       && fileName.length() == (index + filePattern.length())) {
+                               list.add(fileName);
+                       }
+               }
+               return list;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/PHPIdentifierLocation.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/builder/PHPIdentifierLocation.java
new file mode 100644 (file)
index 0000000..afad5af
--- /dev/null
@@ -0,0 +1,193 @@
+package net.sourceforge.phpeclipse.builder;
+
+import net.sourceforge.phpeclipse.obfuscator.PHPIdentifier;
+
+/**
+ * 
+ */
+public class PHPIdentifierLocation extends PHPIdentifier implements Comparable {
+       final public static int UNDEFINED_MATCH = 0;
+
+       final public static int PATTERN_MATCH = 1;
+
+       final public static int EXACT_MATCH = 2;
+
+       private int fMatch;
+
+       private String fClassname;
+
+       private String fFilename;
+
+       private int fOffset;
+
+       private int fPHPDocLength;
+
+       private int fPHPDocOffset;
+
+       private String fUsage;
+
+       public PHPIdentifierLocation(String identifier, int type, String filename) {
+               this(identifier, type, filename, null);
+       }
+
+       public PHPIdentifierLocation(String identifier, int type, String filename,
+                       String classname) {
+               super(identifier, type);
+               fFilename = filename;
+               fClassname = classname;
+               fOffset = -1;
+               fPHPDocLength = -1;
+               fPHPDocOffset = -1;
+               fUsage = null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object obj) {
+               if (!(obj instanceof PHPIdentifierLocation)) {
+                       return false;
+               }
+               return super.equals(obj)
+                               && fFilename.equals(((PHPIdentifierLocation) obj).fFilename);
+       }
+
+       /**
+        * @return
+        */
+       public String getClassname() {
+               return fClassname;
+       }
+
+       /**
+        * @return
+        */
+       public String getFilename() {
+               return fFilename;
+       }
+
+       /**
+        * @return
+        */
+       public int getOffset() {
+               return fOffset;
+       }
+
+       /**
+        * @return
+        */
+       public int getPHPDocLength() {
+               return fPHPDocLength;
+       }
+
+       /**
+        * @return
+        */
+       public int getPHPDocOffset() {
+               return fPHPDocOffset;
+       }
+
+       /**
+        * @return
+        */
+       public String getUsage() {
+               return fUsage;
+       }
+
+       /**
+        * @param string
+        */
+       public void setClassname(String string) {
+               fClassname = string;
+       }
+
+       /**
+        * @param string
+        */
+       public void setFilename(String string) {
+               fFilename = string;
+       }
+
+       /**
+        * @param i
+        */
+       public void setOffset(int i) {
+               fOffset = i;
+       }
+
+       /**
+        * @param i
+        */
+       public void setPHPDocLength(int i) {
+               fPHPDocLength = i;
+       }
+
+       /**
+        * @param i
+        */
+       public void setPHPDocOffset(int i) {
+               fPHPDocOffset = i;
+       }
+
+       /**
+        * @param string
+        */
+       public void setUsage(String string) {
+               fUsage = string;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#toString()
+        */
+       public String toString() {
+               String result = null;
+               switch (fMatch) {
+               case UNDEFINED_MATCH:
+                       result = " [";
+                       break;
+               case PATTERN_MATCH:
+                       result = " [pattern include][";
+                       break;
+               case EXACT_MATCH:
+                       result = " [exact include][";
+                       break;
+               default:
+                       result = "";
+               }
+               return super.toString() + result + fFilename + "]";
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Comparable#compareTo(java.lang.Object)
+        */
+       public int compareTo(Object o) {
+               PHPIdentifierLocation i = (PHPIdentifierLocation) o;
+               if (fMatch > i.fMatch) {
+                       return -1;
+               } else if (fMatch < i.fMatch) {
+                       return 1;
+               }
+               return fFilename.compareTo(i.fFilename);
+       }
+
+       /**
+        * @return Returns the match.
+        */
+       public int getMatch() {
+               return fMatch;
+       }
+
+       /**
+        * @param match
+        *            The match to set.
+        */
+       public void setMatch(int match) {
+               fMatch = match;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorIgnoreSet.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorIgnoreSet.java
new file mode 100644 (file)
index 0000000..3c323aa
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpeclipse.obfuscator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * <code>ObfuscatorIgnoreSet</code> manages a collection of templates and
+ * makes them persistent.
+ */
+public class ObfuscatorIgnoreSet {
+
+       // private static class TemplateComparator implements Comparator {
+       // public int compare(Object arg0, Object arg1) {
+       // if (arg0 == arg1)
+       // return 0;
+       //                      
+       // if (arg0 == null)
+       // return -1;
+       //                              
+       // Template template0= (Template) arg0;
+       // Template template1= (Template) arg1;
+       //                      
+       // return template0.getName().compareTo(template1.getName());
+       // }
+       // }
+
+       private static final String TEMPLATE_TAG = "ignore"; //$NON-NLS-1$
+
+       // private static final String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$
+       // private static final String DESCRIPTION_ATTRIBUTE= "description";
+       // //$NON-NLS-1$
+       // private static final String CONTEXT_ATTRIBUTE= "context"; //$NON-NLS-1$
+       // private static final String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$
+
+       // private List fTemplates= new ArrayList();
+       private HashMap fIdentifierMap = new HashMap();
+
+       // private Comparator fTemplateComparator= new TemplateComparator();
+       // private Template[] fSortedTemplates= new Template[0];
+
+       /**
+        * Convenience method for reading templates from a file.
+        * 
+        * @see #addFromStream(InputStream)
+        */
+       public void addFromFile(File file) throws CoreException {
+               InputStream stream = null;
+
+               try {
+                       stream = new FileInputStream(file);
+                       addFromStream(stream);
+
+               } catch (IOException e) {
+                       throwReadException(e);
+
+               } finally {
+                       try {
+                               if (stream != null)
+                                       stream.close();
+                       } catch (IOException e) {
+                       }
+               }
+       }
+
+       /**
+        * Reads templates from a XML stream and adds them to the template set.
+        */
+       public void addFromStream(InputStream stream) throws CoreException {
+               try {
+                       DocumentBuilderFactory factory = DocumentBuilderFactory
+                                       .newInstance();
+                       DocumentBuilder parser = factory.newDocumentBuilder();
+                       Document document = parser.parse(new InputSource(stream));
+                       NodeList elements = document.getElementsByTagName(TEMPLATE_TAG);
+
+                       int count = elements.getLength();
+                       for (int i = 0; i != count; i++) {
+                               Node node = elements.item(i);
+                               NamedNodeMap attributes = node.getAttributes();
+
+                               if (attributes == null)
+                                       continue;
+
+                               // String name= getAttributeValue(attributes, NAME_ATTRIBUTE);
+                               // String description= getAttributeValue(attributes,
+                               // DESCRIPTION_ATTRIBUTE);
+                               // String context= getAttributeValue(attributes,
+                               // CONTEXT_ATTRIBUTE);
+                               // Node enabledNode= attributes.getNamedItem(ENABLED_ATTRIBUTE);
+
+                               // if (name == null || description == null || context == null)
+                               // throw new
+                               // SAXException(ObfuscatorMessages.getString("TemplateSet.error.missing.attribute"));
+                               // //$NON-NLS-1$
+
+                               // boolean enabled= true; //(enabledNode == null) ||
+                               // (enabledNode.getNodeValue().equals("true")); //$NON-NLS-1$
+
+                               StringBuffer buffer = new StringBuffer();
+                               NodeList children = node.getChildNodes();
+                               for (int j = 0; j != children.getLength(); j++) {
+                                       String value = children.item(j).getNodeValue();
+                                       if (value != null)
+                                               buffer.append(value);
+                               }
+                               String pattern = buffer.toString().trim();
+                               fIdentifierMap.put(pattern, new PHPIdentifier(pattern,
+                                               PHPIdentifier.VARIABLE));
+                               // Template template= new Template(name, description, context,
+                               // pattern);
+                               // template.setEnabled(enabled);
+                               // add(template);
+                       }
+
+                       // sort();
+
+               } catch (ParserConfigurationException e) {
+                       throwReadException(e);
+               } catch (IOException e) {
+                       throwReadException(e);
+               } catch (SAXException e) {
+                       throwReadException(e);
+               }
+       }
+
+       private String getAttributeValue(NamedNodeMap attributes, String name) {
+               Node node = attributes.getNamedItem(name);
+
+               return node == null ? null : node.getNodeValue();
+       }
+
+       /**
+        * Convenience method for saving to a file.
+        * 
+        * @see #saveToStream(OutputStream)
+        */
+       public void saveToFile(File file) throws CoreException {
+               OutputStream stream = null;
+
+               try {
+                       stream = new FileOutputStream(file);
+                       saveToStream(stream);
+               } catch (IOException e) {
+                       throwWriteException(e);
+
+               } finally {
+                       try {
+                               if (stream != null)
+                                       stream.close();
+                       } catch (IOException e) {
+                       }
+               }
+       }
+
+       /**
+        * Saves the template set as XML.
+        */
+       public void saveToStream(OutputStream stream) throws CoreException {
+               try {
+                       DocumentBuilderFactory factory = DocumentBuilderFactory
+                                       .newInstance();
+                       DocumentBuilder builder = factory.newDocumentBuilder();
+                       Document document = builder.newDocument();
+
+                       Node root = document.createElement("obfuscator"); // $NON-NLS-1$
+                                                                                                                               // //$NON-NLS-1$
+                       document.appendChild(root);
+                       Iterator iter = fIdentifierMap.keySet().iterator();
+                       while (iter.hasNext()) {
+                               // for (int i= 0; i != fTemplates.size(); i++) {
+                               // Template template= (Template) fTemplates.get(i);
+
+                               Node node = document.createElement("ignore"); // $NON-NLS-1$
+                                                                                                                               // //$NON-NLS-1$
+                               root.appendChild(node);
+
+                               // NamedNodeMap attributes= node.getAttributes();
+                               //                              
+                               // Attr name= document.createAttribute(NAME_ATTRIBUTE);
+                               // name.setValue(template.getName());
+                               // attributes.setNamedItem(name);
+                               //      
+                               // Attr description=
+                               // document.createAttribute(DESCRIPTION_ATTRIBUTE);
+                               // description.setValue(template.getDescription());
+                               // attributes.setNamedItem(description);
+                               //      
+                               // Attr context= document.createAttribute(CONTEXT_ATTRIBUTE);
+                               // context.setValue(template.getContextTypeName());
+                               // attributes.setNamedItem(context);
+                               //
+                               // Attr enabled= document.createAttribute(ENABLED_ATTRIBUTE);
+                               // enabled.setValue(template.isEnabled() ? "true" : "false");
+                               // //$NON-NLS-1$ //$NON-NLS-2$
+                               // attributes.setNamedItem(enabled);
+
+                               Text pattern = document.createTextNode((String) iter.next());
+                               node.appendChild(pattern);
+                       }
+                       Transformer transformer = TransformerFactory.newInstance()
+                                       .newTransformer();
+                       transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+                       transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+                       DOMSource source = new DOMSource(document);
+                       StreamResult result = new StreamResult(stream);
+
+                       transformer.transform(source, result);
+
+               } catch (ParserConfigurationException e) {
+                       throwWriteException(e);
+               } catch (TransformerException e) {
+                       throwWriteException(e);
+               }
+               // OutputFormat format = new OutputFormat();
+               // format.setPreserveSpace(true);
+               // Serializer serializer =
+               // SerializerFactory.getSerializerFactory("xml").makeSerializer(stream,
+               // format); //$NON-NLS-1$
+               // serializer.asDOMSerializer().serialize(document);
+               //
+               // } catch (ParserConfigurationException e) {
+               // throwWriteException(e);
+               // } catch (IOException e) {
+               // throwWriteException(e);
+               // }
+       }
+
+       private static void throwReadException(Throwable t) throws CoreException {
+               PHPeclipsePlugin.log(t);
+               // IStatus status= new
+               // JavaUIStatus(JavaStatusConstants.TEMPLATE_IO_EXCEPTION,
+               // ObfuscatorMessages.getString("TemplateSet.error.read"), t);
+               // //$NON-NLS-1$
+               // throw new JavaUIException(status);
+       }
+
+       private static void throwWriteException(Throwable t) throws CoreException {
+               PHPeclipsePlugin.log(t);
+               // IStatus status= new
+               // JavaUIStatus(JavaStatusConstants.TEMPLATE_IO_EXCEPTION,
+               // ObfuscatorMessages.getString("TemplateSet.error.write"), t);
+               // //$NON-NLS-1$
+               // throw new JavaUIException(status);
+       }
+
+       /**
+        * Adds a template to the set.
+        */
+       // public void add(Template template) {
+       // if (exists(template))
+       // return; // ignore duplicate
+       //              
+       // fTemplates.add(template);
+       // sort();
+       // }
+       // private boolean exists(Template template) {
+       // for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) {
+       // Template anotherTemplate = (Template) iterator.next();
+       //
+       // if (template.equals(anotherTemplate))
+       // return true;
+       // }
+       //              
+       // return false;
+       // }
+       //      
+       // /**
+       // * Removes a template to the set.
+       // */
+       // public void remove(Template template) {
+       // fTemplates.remove(template);
+       // sort();
+       // }
+       //
+       /**
+        * Empties the set.
+        */
+       public void clear() {
+               fIdentifierMap.clear();
+               // fTemplates.clear();
+               // sort();
+       }
+
+       //      
+       // /**
+       // * Returns all templates.
+       // */
+       // public Template[] getTemplates() {
+       // return (Template[]) fTemplates.toArray(new Template[fTemplates.size()]);
+       // }
+
+       /**
+        * Returns all templates with a given name.
+        */
+       // public Template[] getTemplates(String name) {
+       // ArrayList res= new ArrayList();
+       // for (Iterator iterator= fTemplates.iterator(); iterator.hasNext();) {
+       // Template curr= (Template) iterator.next();
+       // if (curr.getName().equals(name)) {
+       // res.add(curr);
+       // }
+       // }
+       // return (Template[]) res.toArray(new Template[res.size()]);
+       // }
+       //      
+       // private void sort() {
+       // fSortedTemplates= (Template[]) fTemplates.toArray(new
+       // Template[fTemplates.size()]);
+       // Arrays.sort(fSortedTemplates, fTemplateComparator);
+       // }
+       /**
+        * @return
+        */
+       public HashMap getIdentifierMap() {
+               return fIdentifierMap;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorIgnores.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorIgnores.java
new file mode 100644 (file)
index 0000000..8cc826e
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpeclipse.obfuscator;
+
+import java.io.File;
+import java.io.InputStream;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.dialogs.ErrorDialog;
+
+/**
+ * <code>ObfuscatorIgnores</code> gives access to the available templates.
+ */
+public class ObfuscatorIgnores extends ObfuscatorIgnoreSet {
+
+       private static final String DEFAULT_FILE = "default-obfuscator.xml"; //$NON-NLS-1$
+
+       private static final String TEMPLATE_FILE = "obfuscator.xml"; //$NON-NLS-1$
+
+       /** Singleton. */
+       private static ObfuscatorIgnores fgIgnores;
+
+       private IProject fProject;
+
+       public ObfuscatorIgnores(IProject project) {
+               fProject = project;
+               try {
+                       File templateFile = getTemplateFile();
+                       if (templateFile.exists()) {
+                               addFromFile(templateFile);
+                       } else {
+                               addFromStream(getDefaultsAsStream());
+                               saveToFile(templateFile);
+                       }
+
+               } catch (CoreException e) {
+                       PHPeclipsePlugin.log(e);
+                       ErrorDialog.openError(null, ObfuscatorMessages
+                                       .getString("Obfuscator.error.title"), //$NON-NLS-1$
+                                       e.getMessage(), e.getStatus());
+
+                       clear();
+               }
+       }
+
+       /**
+        * Returns an instance of templates.
+        */
+       // public static ObfuscatorIgnores getInstance() {
+       // if (fgIgnores == null)
+       // fgIgnores = create();
+       //
+       // return fgIgnores;
+       // }
+       //
+       // private static ObfuscatorIgnores create() {
+       // ObfuscatorIgnores templates = new ObfuscatorIgnores();
+       //
+       // try {
+       // File templateFile = getTemplateFile();
+       // if (templateFile.exists()) {
+       // templates.addFromFile(templateFile);
+       // } else {
+       // templates.addFromStream(getDefaultsAsStream());
+       // templates.saveToFile(templateFile);
+       // }
+       //
+       // } catch (CoreException e) {
+       // PHPeclipsePlugin.log(e);
+       // ErrorDialog.openError(null,
+       // ObfuscatorMessages.getString("Templates.error.title"), //$NON-NLS-1$
+       // e.getMessage(), e.getStatus());
+       //
+       // templates.clear();
+       // }
+       //
+       // return templates;
+       // }
+       /**
+        * Resets the template set.
+        */
+       public void reset() throws CoreException {
+               clear();
+               addFromFile(getTemplateFile());
+       }
+
+       /**
+        * Resets the template set with the default templates.
+        */
+       public void restoreDefaults() throws CoreException {
+               clear();
+               addFromStream(getDefaultsAsStream());
+       }
+
+       /**
+        * Saves the template set.
+        */
+       public void save() throws CoreException {
+               saveToFile(getTemplateFile());
+       }
+
+       private InputStream getDefaultsAsStream() {
+               return ObfuscatorIgnores.class.getResourceAsStream(DEFAULT_FILE);
+       }
+
+       private File getTemplateFile() {
+               IPath path = fProject.getFullPath();
+               // PHPeclipsePlugin.getDefault().getStateLocation();
+               path = path.append(TEMPLATE_FILE);
+
+               return path.toFile();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorMessages.java
new file mode 100644 (file)
index 0000000..2f99776
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpeclipse.obfuscator;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class ObfuscatorMessages {
+
+       private static final String RESOURCE_BUNDLE = ObfuscatorMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private ObfuscatorMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorMessages.properties
new file mode 100644 (file)
index 0000000..7fd4c12
--- /dev/null
@@ -0,0 +1,9 @@
+#########################################
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+#########################################
+
+# obfuscator ignore list:
+Obfuscator.error.title=Error accessing obfuscator ignore list.
+Obfuscator.error.read=Error occurred while reading obfuscator ignore list.
+Obfuscator.error.write=Error occurred while writing obfuscator ignore list.
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass1Exporter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass1Exporter.java
new file mode 100644 (file)
index 0000000..7084482
--- /dev/null
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Analyzing php files in a first pass over all resources !
+ */
+public class ObfuscatorPass1Exporter implements ITerminalSymbols {
+
+       protected Scanner fScanner;
+
+       protected int fToken;
+
+       protected HashMap fIdentifierMap;
+
+       public ObfuscatorPass1Exporter(Scanner scanner, HashMap identifierMap) {
+               fScanner = scanner;
+               fIdentifierMap = identifierMap;
+       }
+
+       /**
+        * Get the next token from input
+        */
+       private void getNextToken() {
+
+               try {
+                       fToken = fScanner.getNextToken();
+                       if (Scanner.DEBUG) {
+                               int currentEndPosition = fScanner.getCurrentTokenEndPosition();
+                               int currentStartPosition = fScanner
+                                               .getCurrentTokenStartPosition();
+
+                               System.out.print(currentStartPosition + ","
+                                               + currentEndPosition + ": ");
+                               System.out.println(fScanner.toStringAction(fToken));
+                       }
+                       return;
+               } catch (InvalidInputException e) {
+
+               }
+               fToken = TokenNameERROR;
+       }
+
+       private void parseIdentifiers(boolean goBack) {
+               char[] ident;
+               String identifier;
+               PHPIdentifier value;
+               int counter = 0;
+
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               try {
+                       while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
+                               if (fToken == TokenNameVariable) {
+                                       identifier = new String(fScanner
+                                                       .getCurrentIdentifierSource());
+                                       value = (PHPIdentifier) fIdentifierMap.get(identifier);
+                                       if (value == null) {
+                                               fIdentifierMap.put(identifier, new PHPIdentifier(null,
+                                                               PHPIdentifier.VARIABLE));
+                                       }
+                                       getNextToken();
+                                       // } else if (fToken == TokenNamefunction) {
+                                       // getNextToken();
+                                       // if (fToken == TokenNameAND) {
+                                       // getNextToken();
+                                       // }
+                                       // if (fToken == TokenNameIdentifier) {
+                                       // ident = fScanner.getCurrentIdentifierSource();
+                                       // outlineInfo.addVariable(new String(ident));
+                                       // temp = new PHPFunctionDeclaration(current, new
+                                       // String(ident), fScanner.getCurrentTokenStartPosition());
+                                       // current.add(temp);
+                                       // getNextToken();
+                                       // parseDeclarations(outlineInfo, temp, true);
+                                       // }
+                                       // } else if (fToken == TokenNameclass) {
+                                       // getNextToken();
+                                       // if (fToken == TokenNameIdentifier) {
+                                       // ident = fScanner.getCurrentIdentifierSource();
+                                       // outlineInfo.addVariable(new String(ident));
+                                       // temp = new PHPClassDeclaration(current, new
+                                       // String(ident), fScanner.getCurrentTokenStartPosition());
+                                       // current.add(temp);
+                                       // getNextToken();
+                                       //
+                                       // //skip fTokens for classname, extends and others until we
+                                       // have the opening '{'
+                                       // while (fToken != TokenNameLBRACE && fToken !=
+                                       // TokenNameEOF && fToken != TokenNameERROR) {
+                                       // getNextToken();
+                                       // }
+                                       // parseDeclarations(outlineInfo, temp, true);
+                                       // // stack.pop();
+                                       // }
+                               } else if (fToken == TokenNameStringDoubleQuote) {
+                                       char currentCharacter;
+                                       int i = fScanner.startPosition;
+                                       ArrayList varList = new ArrayList();
+
+                                       while (i < fScanner.currentPosition) {
+                                               currentCharacter = fScanner.source[i++];
+                                               if (currentCharacter == '$'
+                                                               && fScanner.source[i - 2] != '\\') {
+                                                       StringBuffer varName = new StringBuffer();
+                                                       varName.append("$");
+                                                       while (i < fScanner.currentPosition) {
+                                                               currentCharacter = fScanner.source[i++];
+                                                               if (!Scanner
+                                                                               .isPHPIdentifierPart(currentCharacter)) {
+                                                                       break; // while loop
+                                                               }
+                                                               varName.append(currentCharacter);
+                                                       }
+                                                       varList.add(varName.toString());
+                                               }
+                                       }
+
+                                       for (i = 0; i < varList.size(); i++) {
+                                               identifier = (String) varList.get(i);
+                                               value = (PHPIdentifier) fIdentifierMap.get(identifier);
+                                               if (value == null) {
+                                                       fIdentifierMap.put(identifier, new PHPIdentifier(
+                                                                       null, PHPIdentifier.VARIABLE));
+                                               }
+                                       }
+
+                                       getNextToken();
+                               } else if (fToken == TokenNameLBRACE) {
+                                       getNextToken();
+                                       counter++;
+                               } else if (fToken == TokenNameRBRACE) {
+                                       getNextToken();
+                                       --counter;
+                                       if (counter == 0 && goBack) {
+                                               return;
+                                       }
+                               } else {
+                                       getNextToken();
+                               }
+                       }
+               } catch (SyntaxError sytaxErr) {
+                       // do nothing
+               }
+       }
+
+       /**
+        * Do nothing in first pass
+        */
+       public void createFolder(IPath destinationPath) {
+               // do nothing here
+               // new File(destinationPath.toOSString()).mkdir();
+       }
+
+       /**
+        * Writes the passed resource to the specified location recursively
+        */
+       public void write(IResource resource, IPath destinationPath)
+                       throws CoreException, IOException {
+               if (resource.getType() == IResource.FILE)
+                       writeFile((IFile) resource, destinationPath);
+               else
+                       writeChildren((IContainer) resource, destinationPath);
+       }
+
+       /**
+        * Exports the passed container's children
+        */
+       protected void writeChildren(IContainer folder, IPath destinationPath)
+                       throws CoreException, IOException {
+               if (folder.isAccessible()) {
+                       IResource[] children = folder.members();
+                       for (int i = 0; i < children.length; i++) {
+                               IResource child = children[i];
+                               writeResource(child, destinationPath.append(child.getName()));
+                       }
+               }
+       }
+
+       /**
+        * Analyzes the passed file resource for the PHP obfuscator
+        */
+       protected void writeFile(IFile file, IPath destinationPath)
+                       throws IOException, CoreException {
+               if (!PHPFileUtil.isPHPFile(file)) {
+                       return;
+               }
+               InputStream stream = null;
+               char[] charArray = null;
+               try {
+                       stream = new BufferedInputStream(file.getContents());
+                       charArray = Util.getInputStreamAsCharArray(stream, -1, null);
+               } catch (IOException e) {
+                       return;
+               } finally {
+                       try {
+                               if (stream != null) {
+                                       stream.close();
+                               }
+                       } catch (IOException e) {
+                       }
+               }
+
+               if (charArray == null) {
+                       // TODO show error message
+                       return;
+               }
+               /* fScanner initialization */
+               fScanner.setSource(charArray);
+               fScanner.setPHPMode(false);
+               fToken = TokenNameEOF;
+               getNextToken();
+               parseIdentifiers(false);
+       }
+
+       /**
+        * Writes the passed resource to the specified location recursively
+        */
+       protected void writeResource(IResource resource, IPath destinationPath)
+                       throws CoreException, IOException {
+               if (resource.getType() == IResource.FILE)
+                       writeFile((IFile) resource, destinationPath);
+               else {
+                       createFolder(destinationPath);
+                       writeChildren((IContainer) resource, destinationPath);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass2Exporter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass2Exporter.java
new file mode 100644 (file)
index 0000000..7898633
--- /dev/null
@@ -0,0 +1,382 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Helper class for exporting resources to the file system.
+ */
+public class ObfuscatorPass2Exporter implements ITerminalSymbols {
+       private Scanner fScanner;
+
+       private int fToken;
+
+       private int fCounter;
+
+       protected HashMap fIdentifierMap;
+
+       public ObfuscatorPass2Exporter(Scanner scanner, HashMap identifierMap) {
+               fScanner = scanner;
+               fIdentifierMap = identifierMap;
+               fCounter = 0;
+       }
+
+       /**
+        * gets the next token from input
+        */
+       private void getNextToken() {
+
+               try {
+                       fToken = fScanner.getNextToken();
+                       if (Scanner.DEBUG) {
+                               int currentEndPosition = fScanner.getCurrentTokenEndPosition();
+                               int currentStartPosition = fScanner
+                                               .getCurrentTokenStartPosition();
+
+                               System.out.print(currentStartPosition + ","
+                                               + currentEndPosition + ": ");
+                               System.out.println(fScanner.toStringAction(fToken));
+                       }
+                       return;
+               } catch (InvalidInputException e) {
+
+               }
+               fToken = TokenNameERROR;
+       }
+
+       private boolean obfuscate(StringBuffer buf) {
+               char[] ident;
+               String identifier;
+               PHPIdentifier value;
+
+               int startPosition = 0;
+               int lastPosition = 0;
+
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               try {
+                       while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
+                               if (fToken == TokenNameVariable) {
+                                       identifier = new String(fScanner
+                                                       .getCurrentIdentifierSource());
+                                       lastPosition = fScanner.startPosition;
+                                       int len = lastPosition - startPosition;
+                                       buf.append(fScanner.source, startPosition, len);
+                                       value = (PHPIdentifier) fIdentifierMap.get(identifier);
+                                       if (value != null) {
+                                               String obfuscatedIdentifier = value.getIdentifier();
+                                               if (obfuscatedIdentifier == null) {
+                                                       buf.append("$v" + Integer.toString(fCounter));
+                                                       value.setIdentifier("$v"
+                                                                       + Integer.toString(fCounter++));
+                                               } else {
+                                                       buf.append(obfuscatedIdentifier);
+                                               }
+                                               // System.out.println(hexString.toString());
+                                       } else {
+                                               buf.append(identifier);
+                                       }
+                                       startPosition = fScanner.currentPosition;
+                                       getNextToken();
+                               } else if (fToken == TokenNameIdentifier) {
+                                       identifier = new String(fScanner
+                                                       .getCurrentIdentifierSource());
+                                       lastPosition = fScanner.startPosition;
+                                       int len = lastPosition - startPosition;
+                                       buf.append(fScanner.source, startPosition, len);
+                                       value = (PHPIdentifier) fIdentifierMap.get(identifier);
+                                       if (value != null) {
+                                               String obfuscatedIdentifier = value.getIdentifier();
+                                               if (obfuscatedIdentifier == null) {
+                                                       buf.append("_" + Integer.toString(fCounter));
+                                                       value.setIdentifier("_"
+                                                                       + Integer.toString(fCounter++));
+                                               } else {
+                                                       buf.append(obfuscatedIdentifier);
+                                               }
+                                               // System.out.println(hexString.toString());
+                                       } else {
+                                               buf.append(identifier);
+                                       }
+                                       startPosition = fScanner.currentPosition;
+                                       getNextToken();
+
+                               } else if (fToken == TokenNameCOMMENT_LINE
+                                               || fToken == TokenNameCOMMENT_BLOCK
+                                               || fToken == TokenNameCOMMENT_PHPDOC) {
+                                       lastPosition = fScanner.startPosition;
+                                       buf.append(fScanner.source, startPosition, lastPosition
+                                                       - startPosition);
+                                       startPosition = fScanner.currentPosition;
+                                       getNextToken();
+                               } else if (fToken == TokenNameStringDoubleQuote) {
+                                       char currentCharacter;
+                                       int i = fScanner.startPosition;
+                                       ArrayList varList = new ArrayList();
+
+                                       lastPosition = fScanner.startPosition;
+                                       int len = lastPosition - startPosition;
+                                       buf.append(fScanner.source, startPosition, len);
+
+                                       while (i < fScanner.currentPosition) {
+                                               currentCharacter = fScanner.source[i++];
+                                               if (currentCharacter == '$'
+                                                               && fScanner.source[i - 2] != '\\') {
+                                                       StringBuffer varName = new StringBuffer();
+                                                       varName.append("$");
+                                                       while (i < fScanner.currentPosition) {
+                                                               currentCharacter = fScanner.source[i++];
+                                                               if (!Scanner
+                                                                               .isPHPIdentifierPart(currentCharacter)) {
+                                                                       break; // while loop
+                                                               }
+                                                               varName.append(currentCharacter);
+                                                       }
+                                                       varList.add(varName.toString());
+                                               }
+                                       }
+                                       StringBuffer stringLiteral = new StringBuffer();
+                                       stringLiteral.append(fScanner.source,
+                                                       fScanner.startPosition, fScanner.currentPosition
+                                                                       - fScanner.startPosition);
+                                       String stringIdent;
+                                       String replacement;
+                                       int index;
+
+                                       for (int j = 0; j < varList.size(); j++) {
+                                               stringIdent = (String) varList.get(j);
+                                               len = stringIdent.length();
+                                               value = (PHPIdentifier) fIdentifierMap.get(stringIdent);
+                                               if (value != null) {
+                                                       String obfuscatedIdentifier = value.getIdentifier();
+                                                       if (obfuscatedIdentifier == null) {
+                                                               replacement = "$v" + Integer.toString(fCounter);
+                                                               value.setIdentifier("$v"
+                                                                               + Integer.toString(fCounter++));
+                                                       } else {
+                                                               replacement = obfuscatedIdentifier;
+                                                       }
+                                                       // System.out.println(hexString.toString());
+                                               } else {
+                                                       replacement = stringIdent;
+                                               }
+                                               index = stringLiteral.indexOf(stringIdent);
+                                               if (index >= 0) {
+                                                       if (index > 0
+                                                                       && stringLiteral.charAt(index - 1) != '\\') {
+                                                               stringLiteral.replace(index, index
+                                                                               + stringIdent.length(), replacement);
+                                                       } else if (index == 0) {
+                                                               stringLiteral.replace(index, index
+                                                                               + stringIdent.length(), replacement);
+                                                       }
+                                               }
+                                       }
+                                       buf.append(stringLiteral);
+                                       startPosition = fScanner.currentPosition;
+                                       getNextToken();
+                               }
+                               if (fToken == TokenNameMINUS_GREATER) { // i.e. $this->var_name
+                                       getNextToken();
+                                       if (fToken == TokenNameIdentifier) {
+                                               // assuming this is a dereferenced variable
+                                               identifier = new String(fScanner
+                                                               .getCurrentIdentifierSource());
+                                               lastPosition = fScanner.startPosition;
+                                               int len = lastPosition - startPosition;
+                                               buf.append(fScanner.source, startPosition, len);
+                                               value = (PHPIdentifier) fIdentifierMap.get("$"
+                                                               + identifier);
+                                               if (value != null && value.isVariable()) {
+                                                       String obfuscatedIdentifier = value.getIdentifier();
+                                                       if (obfuscatedIdentifier == null) {
+                                                               // note: don't place a $ before the identifier
+                                                               buf.append("v" + Integer.toString(fCounter));
+                                                               value.setIdentifier("$v"
+                                                                               + Integer.toString(fCounter++));
+                                                       } else {
+                                                               if (obfuscatedIdentifier.charAt(0) == '$') {
+                                                                       buf.append(obfuscatedIdentifier
+                                                                                       .substring(1));
+                                                               } else {
+                                                                       buf.append(obfuscatedIdentifier);
+                                                               }
+                                                       }
+                                               } else {
+                                                       buf.append(identifier);
+                                               }
+                                               startPosition = fScanner.currentPosition;
+                                               getNextToken();
+                                       }
+
+                               } else {
+                                       getNextToken();
+                               }
+                       }
+                       if (startPosition < fScanner.source.length) {
+                               buf.append(fScanner.source, startPosition,
+                                               fScanner.source.length - startPosition);
+                       }
+                       return true;
+               } catch (SyntaxError sytaxErr) {
+                       // do nothing
+               }
+
+               return false;
+       }
+
+       /**
+        * Creates the specified file system directory at
+        * <code>destinationPath</code>. This creates a new file system
+        * directory.
+        */
+       public void createFolder(IPath destinationPath) {
+               new File(destinationPath.toOSString()).mkdir();
+       }
+
+       /**
+        * Writes the passed resource to the specified location recursively
+        */
+       public void write(IResource resource, IPath destinationPath)
+                       throws CoreException, IOException {
+               if (resource.getType() == IResource.FILE)
+                       writeFile((IFile) resource, destinationPath);
+               else
+                       writeChildren((IContainer) resource, destinationPath);
+       }
+
+       /**
+        * Exports the passed container's children
+        */
+       protected void writeChildren(IContainer folder, IPath destinationPath)
+                       throws CoreException, IOException {
+               if (folder.isAccessible()) {
+                       IResource[] children = folder.members();
+                       for (int i = 0; i < children.length; i++) {
+                               IResource child = children[i];
+                               writeResource(child, destinationPath.append(child.getName()));
+                       }
+               }
+       }
+
+       /**
+        * Writes the passed file resource to the specified destination on the local
+        * file system
+        */
+       protected void writeFile(IFile file, IPath destinationPath)
+                       throws IOException, CoreException {
+               if (PHPFileUtil.isPHPFile(file)) {
+                       InputStream stream = null;
+                       char[] charArray = null;
+                       try {
+                               stream = new BufferedInputStream(file.getContents());
+                               charArray = Util.getInputStreamAsCharArray(stream, -1, null);
+                       } catch (IOException e) {
+                               return;
+                       } finally {
+                               try {
+                                       if (stream != null) {
+                                               stream.close();
+                                       }
+                               } catch (IOException e) {
+                               }
+                       }
+
+                       if (charArray == null) {
+                               // TODO show error message
+                               return;
+                       }
+
+                       fScanner.setSource(charArray);
+                       fScanner.setPHPMode(false);
+                       fToken = TokenNameEOF;
+                       getNextToken();
+
+                       StringBuffer buf = new StringBuffer();
+                       if (!obfuscate(buf)) {
+                               copyFile(file, destinationPath);
+                       } else {
+                               // charArray = buf.toString().toCharArray();
+                               // File targetFile = new File(destinationPath.toOSString());
+                               BufferedWriter bw = new BufferedWriter(new FileWriter(
+                                               destinationPath.toOSString()));
+                               bw.write(buf.toString());
+                               bw.close();
+                       }
+
+               } else {
+                       copyFile(file, destinationPath);
+               }
+       }
+
+       private void copyFile(IFile file, IPath destinationPath)
+                       throws FileNotFoundException, CoreException, IOException {
+               FileOutputStream output = null;
+               InputStream contentStream = null;
+
+               try {
+                       output = new FileOutputStream(destinationPath.toOSString());
+                       contentStream = file.getContents(false);
+                       int chunkSize = contentStream.available();
+                       byte[] readBuffer = new byte[chunkSize];
+                       int n = contentStream.read(readBuffer);
+
+                       while (n > 0) {
+                               output.write(readBuffer);
+                               n = contentStream.read(readBuffer);
+                       }
+               } finally {
+                       if (output != null)
+                               output.close();
+                       if (contentStream != null)
+                               contentStream.close();
+               }
+       }
+
+       /**
+        * Writes the passed resource to the specified location recursively
+        */
+       protected void writeResource(IResource resource, IPath destinationPath)
+                       throws CoreException, IOException {
+               if (resource.getType() == IResource.FILE)
+                       writeFile((IFile) resource, destinationPath);
+               else {
+                       createFolder(destinationPath);
+                       writeChildren((IContainer) resource, destinationPath);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/PHPIdentifier.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/PHPIdentifier.java
new file mode 100644 (file)
index 0000000..53369ef
--- /dev/null
@@ -0,0 +1,119 @@
+package net.sourceforge.phpeclipse.obfuscator;
+
+/**
+ * Object which holds an PHP identifier name (i.e. class, function,
+ * variable,...)
+ * 
+ */
+public class PHPIdentifier {
+
+       public final static int CLASS = 1;
+
+       public final static int FUNCTION = 2;
+
+       public final static int VARIABLE = 3;
+
+       public final static int METHOD = 4;
+
+       public final static int DEFINE = 5;
+
+       public final static int CONSTRUCTOR = 6;
+
+       public final static int GLOBAL_VARIABLE = 7;
+
+       public final static int EXTENDS = 8;
+
+       public final static int IMPLEMENTS = 9;
+
+       private String fIdentifier;
+
+       private int fType;
+
+       public PHPIdentifier(String identifier, int type) {
+               fType = type;
+               fIdentifier = identifier;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object obj) {
+               if (!(obj instanceof PHPIdentifier)) {
+                       return false;
+               }
+               return ((PHPIdentifier) obj).fType == fType
+                               && ((PHPIdentifier) obj).fIdentifier.equals(fIdentifier);
+       }
+
+       public String getIdentifier() {
+               return fIdentifier;
+       }
+
+       public int getType() {
+               return fType;
+       }
+
+       public boolean isClass() {
+               return fType == CLASS;
+       }
+
+       public boolean isFunction() {
+               return fType == FUNCTION;
+       }
+
+       public boolean isVariable() {
+               return fType == VARIABLE;
+       }
+
+       public boolean isMethod() {
+               return fType == METHOD;
+       }
+
+       public boolean isDefine() {
+               return fType == DEFINE;
+       }
+
+       public boolean isGlobalVariable() {
+               return fType == GLOBAL_VARIABLE;
+       }
+
+       public boolean isConstructor() {
+               return fType == CONSTRUCTOR;
+       }
+
+       public void setIdentifier(String fIdentifier) {
+               this.fIdentifier = fIdentifier;
+       }
+
+       public void setType(int fType) {
+               this.fType = fType;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#toString()
+        */
+       public String toString() {
+               switch (fType) {
+               case CLASS:
+                       return "class - ";
+               case CONSTRUCTOR:
+                       return "constructor - ";
+               case DEFINE:
+                       return "define - ";
+               case FUNCTION:
+                       return "function - ";
+               case GLOBAL_VARIABLE:
+                       return "global variable - ";
+               case METHOD:
+                       return "method - ";
+               case VARIABLE:
+                       return "variable - ";
+               }
+               return "";
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/default-obfuscator.xml b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/default-obfuscator.xml
new file mode 100644 (file)
index 0000000..bd85d37
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<obfuscator>
+    <ignore>$this</ignore>
+    <ignore>$_COOKIE</ignore>
+    <ignore>$_ENV</ignore>
+    <ignore>$_FILES</ignore>
+    <ignore>$_GET</ignore>
+    <ignore>$_POST</ignore>
+    <ignore>$_REQUEST</ignore>
+    <ignore>$_SERVER</ignore>
+    <ignore>$_SESSION</ignore>
+    <ignore>$argc</ignore>
+    <ignore>$argv</ignore>
+    <ignore>$AUTH_TYPE</ignore>
+    <ignore>$CONTENT_LENGTH</ignore>
+    <ignore>$CONTENT_TYPE</ignore>
+    <ignore>$DOCUMENT_ROOT</ignore>
+    <ignore>$GATEWAY_INTERFACE</ignore>
+    <ignore>$GLOBALS</ignore>
+    <ignore>$HTTP_ACCEPT</ignore>   
+    <ignore>$HTTP_ACCEPT_ENCODING</ignore>
+    <ignore>$HTTP_ACCEPT_LANGUAGE</ignore>
+    <ignore>$HTTP_CACHE_CONTROL</ignore>
+    <ignore>$HTTP_CONNECTION</ignore>
+    <ignore>$HTTP_COOKIE</ignore>
+    <ignore>$HTTP_COOKIE_VARS</ignore>
+    <ignore>$HTTP_ENV_VARS</ignore>
+    <ignore>$HTTP_GET_VARS</ignore>
+    <ignore>$HTTP_HOST</ignore>
+    <ignore>$HTTP_HOST_FILES</ignore>
+    <ignore>$HTTP_POST_VARS</ignore>
+    <ignore>$HTTP_SERVER_VARS</ignore>
+    <ignore>$HTTP_SESSION_VARS</ignore>
+    <ignore>$HTTP_REFERER</ignore>
+    <ignore>$HTTP_USER_AGENT</ignore>
+    <ignore>$PATH</ignore>
+    <ignore>$PATH_INFO</ignore>
+    <ignore>$PATH_TRANSLATED</ignore>
+    <ignore>$PHP_AUTH_PW</ignore>
+    <ignore>$PHP_AUTH_USER</ignore>
+    <ignore>$PHP_ERRORMSG</ignore>
+    <ignore>$PHP_SELF</ignore>
+    <ignore>$QUERY_STRING</ignore>
+    <ignore>$REDIRECT_STATUS</ignore>
+    <ignore>$REDIRECT_URL</ignore>
+    <ignore>$REMOTE_ADDR</ignore>
+    <ignore>$REMOTE_HOST</ignore>
+    <ignore>$REMOTE_IDENT</ignore>
+    <ignore>$REMOTE_PORT</ignore>
+    <ignore>$REMOTE_USER</ignore>
+    <ignore>$REQUEST_METHOD</ignore>
+    <ignore>$REQUEST_URI</ignore>
+    <ignore>$SCRIPT_FILENAME</ignore>
+    <ignore>$SCRIPT_NAME</ignore>
+    <ignore>$SERVER_ADDR</ignore>
+    <ignore>$SERVER_ADMIN</ignore>
+    <ignore>$SERVER_NAME</ignore>
+    <ignore>$SERVER_PORT</ignore>
+    <ignore>$SERVER_PROTOCOL</ignore>
+    <ignore>$SERVER_SIGNATURE</ignore>
+    <ignore>$SERVER_SOFTWARE</ignore>
+</obfuscator>
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportMessages.java
new file mode 100644 (file)
index 0000000..3878513
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator.export;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class which helps managing messages
+ */
+class ObfuscatorExportMessages {
+       private static final String RESOURCE_BUNDLE = "net.sourceforge.phpeclipse.obfuscator.export.messages";//$NON-NLS-1$
+
+       private static ResourceBundle bundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private ObfuscatorExportMessages() {
+               // prevent instantiation of class
+       }
+
+       /**
+        * Returns the formatted message for the given key in the resource bundle.
+        * 
+        * @param key
+        *            the resource name
+        * @param args
+        *            the message arguments
+        * @return the string
+        */
+       public static String format(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+
+       /**
+        * Returns the resource object 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 name
+        * @return the string
+        */
+       public static String getString(String key) {
+               try {
+                       return bundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return key;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportOperation.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportOperation.java
new file mode 100644 (file)
index 0000000..2c9d808
--- /dev/null
@@ -0,0 +1,742 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator.export;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.obfuscator.ObfuscatorIgnores;
+import net.sourceforge.phpeclipse.obfuscator.ObfuscatorPass1Exporter;
+import net.sourceforge.phpeclipse.obfuscator.ObfuscatorPass2Exporter;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+
+/**
+ * Operation for exporting the contents of a resource to the local file system.
+ */
+/* package */
+class ObfuscatorExportOperation implements IRunnableWithProgress {
+       private IPath fPath;
+
+       private IProgressMonitor fMonitor;
+
+       private ObfuscatorPass1Exporter fExporter1 = null;
+
+       private ObfuscatorPass2Exporter fExporter2 = null;
+
+       private HashMap fCurrentIdentifierMap = null;
+
+       private HashMap fProjectMap = null;
+
+       private String fCurrentProjectName = "";
+
+       private List fResourcesToExport;
+
+       private IOverwriteQuery fOverwriteCallback;
+
+       private IResource fResource;
+
+       private List errorTable = new ArrayList(1);
+
+       // The constants for the overwrite 3 state
+       private static final int OVERWRITE_NOT_SET = 0;
+
+       private static final int OVERWRITE_NONE = 1;
+
+       private static final int OVERWRITE_ALL = 2;
+
+       private int overwriteState = OVERWRITE_NOT_SET;
+
+       // private boolean createLeadupStructure = true;
+       private boolean createContainerDirectories = true;
+
+       /**
+        * Create an instance of this class. Use this constructor if you wish to
+        * export specific resources without a common parent resource
+        */
+       // public ObfuscatorExportOperation(List resources, String destinationPath,
+       // IOverwriteQuery overwriteImplementor) {
+       // super();
+       //
+       // exporter1 = new ObfuscatorPass1Exporter(new Scanner(false, false),
+       // identifierMap);
+       // exporter2 = new ObfuscatorPass2Exporter(new Scanner(true, true),
+       // identifierMap);
+       // identifierMap = null;
+       //              
+       // // Eliminate redundancies in list of resources being exported
+       // Iterator elementsEnum = resources.iterator();
+       // while (elementsEnum.hasNext()) {
+       // IResource currentResource = (IResource) elementsEnum.next();
+       // if (isDescendent(resources, currentResource))
+       // elementsEnum.remove(); //Remove currentResource
+       // }
+       //
+       // resourcesToExport = resources;
+       // path = new Path(destinationPath);
+       // overwriteCallback = overwriteImplementor;
+       // }
+       /**
+        * Create an instance of this class. Use this constructor if you wish to
+        * recursively export a single resource
+        */
+       public ObfuscatorExportOperation(IResource res, String destinationPath,
+                       IOverwriteQuery overwriteImplementor) {
+               super();
+
+               fResource = res;
+               fPath = new Path(destinationPath);
+               fOverwriteCallback = overwriteImplementor;
+       }
+
+       /**
+        * Create an instance of this class. Use this constructor if you wish to
+        * export specific resources with a common parent resource (affects
+        * container directory creation)
+        */
+       public ObfuscatorExportOperation(IResource res, List resources,
+                       String destinationPath, IOverwriteQuery overwriteImplementor) {
+               this(res, destinationPath, overwriteImplementor);
+               fResourcesToExport = resources;
+       }
+
+       /**
+        * Add a new entry to the error table with the passed information
+        */
+       protected void addError(String message, Throwable e) {
+               errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
+                               message, e));
+       }
+
+       /**
+        * Answer the total number of file resources that exist at or below self in
+        * the resources hierarchy.
+        * 
+        * @return int
+        * @param resource
+        *            org.eclipse.core.resources.IResource
+        */
+       protected int countChildrenOf(IResource resource) throws CoreException {
+               if (resource.getType() == IResource.FILE)
+                       return 1;
+
+               int count = 0;
+               if (resource.isAccessible()) {
+                       IResource[] children = ((IContainer) resource).members();
+                       for (int i = 0; i < children.length; i++)
+                               count += countChildrenOf(children[i]);
+               }
+
+               return count;
+       }
+
+       /**
+        * Answer a boolean indicating the number of file resources that were
+        * specified for export
+        * 
+        * @return int
+        */
+       protected int countSelectedResources() throws CoreException {
+               int result = 0;
+               Iterator resources = fResourcesToExport.iterator();
+
+               while (resources.hasNext())
+                       result += countChildrenOf((IResource) resources.next());
+
+               return result;
+       }
+
+       /**
+        * Create the directories required for exporting the passed resource, based
+        * upon its container hierarchy
+        * 
+        * @param resource
+        *            org.eclipse.core.resources.IResource
+        */
+       protected void createLeadupDirectoriesFor(IResource resource) {
+               IPath resourcePath = resource.getFullPath().removeLastSegments(1);
+
+               for (int i = 0; i < resourcePath.segmentCount(); i++) {
+                       fPath = fPath.append(resourcePath.segment(i));
+                       fExporter2.createFolder(fPath);
+               }
+       }
+
+       /**
+        * Recursively export the previously-specified resource
+        */
+       protected void exportAllResources1() throws InterruptedException {
+               if (fResource.getType() == IResource.FILE) {
+                       exportFile1((IFile) fResource, fPath);
+               } else {
+                       try {
+                               setExporters(fResource);
+                               exportChildren1(((IContainer) fResource).members(), fPath);
+                       } catch (CoreException e) {
+                               // not safe to show a dialog
+                               // should never happen because the file system export wizard
+                               // ensures that the
+                               // single resource chosen for export is both existent and
+                               // accessible
+                               errorTable.add(e);
+                       }
+               }
+       }
+
+       /**
+        * Recursively export the previously-specified resource
+        */
+       protected void exportAllResources2() throws InterruptedException {
+               if (fResource.getType() == IResource.FILE) {
+                       exportFile2((IFile) fResource, fPath);
+               } else {
+                       try {
+                               setExporters(fResource);
+                               exportChildren2(((IContainer) fResource).members(), fPath);
+                       } catch (CoreException e) {
+                               // not safe to show a dialog
+                               // should never happen because the file system export wizard
+                               // ensures that the
+                               // single resource chosen for export is both existent and
+                               // accessible
+                               errorTable.add(e);
+                       }
+               }
+       }
+
+       /**
+        * Export all of the resources contained in the passed collection
+        * 
+        * @param children
+        *            java.util.Enumeration
+        * @param currentPath
+        *            IPath
+        */
+       protected void exportChildren1(IResource[] children, IPath currentPath)
+                       throws InterruptedException {
+               for (int i = 0; i < children.length; i++) {
+                       IResource child = children[i];
+                       if (!child.isAccessible())
+                               continue;
+
+                       if (child.getType() == IResource.FILE)
+                               exportFile1((IFile) child, currentPath);
+                       else {
+                               IPath destination = currentPath.append(child.getName());
+                               fExporter1.createFolder(destination);
+                               try {
+                                       exportChildren1(((IContainer) child).members(), destination);
+                               } catch (CoreException e) {
+                                       // not safe to show a dialog
+                                       // should never happen because:
+                                       // i. this method is called recursively iterating over the
+                                       // result of #members,
+                                       // which only answers existing children
+                                       // ii. there is an #isAccessible check done before #members
+                                       // is invoked
+                                       errorTable.add(e.getStatus());
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Export all of the resources contained in the passed collection
+        * 
+        * @param children
+        *            java.util.Enumeration
+        * @param currentPath
+        *            IPath
+        */
+       protected void exportChildren2(IResource[] children, IPath currentPath)
+                       throws InterruptedException {
+               for (int i = 0; i < children.length; i++) {
+                       IResource child = children[i];
+                       if (!child.isAccessible())
+                               continue;
+
+                       if (child.getType() == IResource.FILE)
+                               exportFile2((IFile) child, currentPath);
+                       else {
+                               IPath destination = currentPath.append(child.getName());
+                               fExporter2.createFolder(destination);
+                               try {
+                                       exportChildren2(((IContainer) child).members(), destination);
+                               } catch (CoreException e) {
+                                       // not safe to show a dialog
+                                       // should never happen because:
+                                       // i. this method is called recursively iterating over the
+                                       // result of #members,
+                                       // which only answers existing children
+                                       // ii. there is an #isAccessible check done before #members
+                                       // is invoked
+                                       errorTable.add(e.getStatus());
+                               }
+                       }
+               }
+       }
+
+       protected void exportFile1(IFile file, IPath location)
+                       throws InterruptedException {
+               IPath fullPath = location.append(file.getName());
+               fMonitor.subTask(file.getFullPath().toString());
+               String properPathString = fullPath.toOSString();
+               File targetFile = new File(properPathString);
+
+               // if (targetFile.exists()) {
+               // if (!targetFile.canWrite()) {
+               // errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
+               // ObfuscatorExportMessages.format("ObfuscatorTransfer.cannotOverwrite",
+               // //$NON-NLS-1$
+               // new Object[] { targetFile.getAbsolutePath()}), null));
+               // monitor.worked(1);
+               // return;
+               // }
+               //
+               // if (overwriteState == OVERWRITE_NONE)
+               // return;
+               //
+               // if (overwriteState != OVERWRITE_ALL) {
+               // String overwriteAnswer =
+               // overwriteCallback.queryOverwrite(properPathString);
+               //
+               // if (overwriteAnswer.equals(IOverwriteQuery.CANCEL))
+               // throw new InterruptedException();
+               //
+               // if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
+               // monitor.worked(1);
+               // return;
+               // }
+               //
+               // if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
+               // monitor.worked(1);
+               // overwriteState = OVERWRITE_NONE;
+               // return;
+               // }
+               //
+               // if (overwriteAnswer.equals(IOverwriteQuery.ALL))
+               // overwriteState = OVERWRITE_ALL;
+               // }
+               // }
+
+               try {
+                       setExporters(file);
+                       fExporter1.write(file, fullPath);
+               } catch (IOException e) {
+                       errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
+                                       ObfuscatorExportMessages.format(
+                                                       "ObfuscatorTransfer.errorExporting", //$NON-NLS-1$
+                                                       new Object[] { fullPath, e.getMessage() }), e));
+               } catch (CoreException e) {
+                       errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
+                                       ObfuscatorExportMessages.format(
+                                                       "ObfuscatorTransfer.errorExporting", //$NON-NLS-1$
+                                                       new Object[] { fullPath, e.getMessage() }), e));
+               }
+
+               fMonitor.worked(1);
+               ModalContext.checkCanceled(fMonitor);
+       }
+
+       /**
+        * Export the passed file to the specified location
+        * 
+        * @param file
+        *            org.eclipse.core.resources.IFile
+        * @param location
+        *            org.eclipse.core.runtime.IPath
+        */
+       protected void exportFile2(IFile file, IPath location)
+                       throws InterruptedException {
+               IPath fullPath = location.append(file.getName());
+               fMonitor.subTask(file.getFullPath().toString());
+               String properPathString = fullPath.toOSString();
+               File targetFile = new File(properPathString);
+
+               if (targetFile.exists()) {
+                       if (!targetFile.canWrite()) {
+                               errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID,
+                                               0, ObfuscatorExportMessages.format(
+                                                               "ObfuscatorTransfer.cannotOverwrite", //$NON-NLS-1$
+                                                               new Object[] { targetFile.getAbsolutePath() }),
+                                               null));
+                               fMonitor.worked(1);
+                               return;
+                       }
+
+                       if (overwriteState == OVERWRITE_NONE)
+                               return;
+
+                       if (overwriteState != OVERWRITE_ALL) {
+                               String overwriteAnswer = fOverwriteCallback
+                                               .queryOverwrite(properPathString);
+
+                               if (overwriteAnswer.equals(IOverwriteQuery.CANCEL))
+                                       throw new InterruptedException();
+
+                               if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
+                                       fMonitor.worked(1);
+                                       return;
+                               }
+
+                               if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
+                                       fMonitor.worked(1);
+                                       overwriteState = OVERWRITE_NONE;
+                                       return;
+                               }
+
+                               if (overwriteAnswer.equals(IOverwriteQuery.ALL))
+                                       overwriteState = OVERWRITE_ALL;
+                       }
+               }
+
+               try {
+                       setExporters(file);
+                       fExporter2.write(file, fullPath);
+               } catch (IOException e) {
+                       errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
+                                       ObfuscatorExportMessages.format(
+                                                       "ObfuscatorTransfer.errorExporting", //$NON-NLS-1$
+                                                       new Object[] { fullPath, e.getMessage() }), e));
+               } catch (CoreException e) {
+                       errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
+                                       ObfuscatorExportMessages.format(
+                                                       "ObfuscatorTransfer.errorExporting", //$NON-NLS-1$
+                                                       new Object[] { fullPath, e.getMessage() }), e));
+               }
+
+               fMonitor.worked(1);
+               ModalContext.checkCanceled(fMonitor);
+       }
+
+       protected void exportSpecifiedResources1() throws InterruptedException {
+               Iterator resources = fResourcesToExport.iterator();
+               IPath initPath = (IPath) fPath.clone();
+
+               while (resources.hasNext()) {
+                       IResource currentResource = (IResource) resources.next();
+                       if (!currentResource.isAccessible())
+                               continue;
+                       setExporters(currentResource);
+                       fPath = initPath;
+
+                       if (fResource == null) {
+                               // No root resource specified and creation of containment
+                               // directories
+                               // is required. Create containers from depth 2 onwards (ie.-
+                               // project's
+                               // child inclusive) for each resource being exported.
+                               // if (createLeadupStructure)
+                               // createLeadupDirectoriesFor(currentResource);
+
+                       } else {
+                               // Root resource specified. Must create containment directories
+                               // from this point onwards for each resource being exported
+                               IPath containersToCreate = currentResource.getFullPath()
+                                               .removeFirstSegments(
+                                                               fResource.getFullPath().segmentCount())
+                                               .removeLastSegments(1);
+
+                               for (int i = 0; i < containersToCreate.segmentCount(); i++) {
+                                       fPath = fPath.append(containersToCreate.segment(i));
+                                       fExporter1.createFolder(fPath);
+                               }
+                       }
+
+                       if (currentResource.getType() == IResource.FILE)
+                               exportFile1((IFile) currentResource, fPath);
+                       else {
+                               if (createContainerDirectories) {
+                                       fPath = fPath.append(currentResource.getName());
+                                       fExporter1.createFolder(fPath);
+                               }
+
+                               try {
+                                       exportChildren1(((IContainer) currentResource).members(),
+                                                       fPath);
+                               } catch (CoreException e) {
+                                       // should never happen because #isAccessible is called
+                                       // before #members is invoked,
+                                       // which implicitly does an existence check
+                                       errorTable.add(e.getStatus());
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Export the resources contained in the previously-defined
+        * resourcesToExport collection
+        */
+       protected void exportSpecifiedResources2() throws InterruptedException {
+               Iterator resources = fResourcesToExport.iterator();
+               IPath initPath = (IPath) fPath.clone();
+
+               while (resources.hasNext()) {
+                       IResource currentResource = (IResource) resources.next();
+                       if (!currentResource.isAccessible())
+                               continue;
+                       setExporters(currentResource);
+
+                       fPath = initPath;
+
+                       if (fResource == null) {
+                               // No root resource specified and creation of containment
+                               // directories
+                               // is required. Create containers from depth 2 onwards (ie.-
+                               // project's
+                               // child inclusive) for each resource being exported.
+                               // if (createLeadupStructure)
+                               // createLeadupDirectoriesFor(currentResource);
+
+                       } else {
+                               // Root resource specified. Must create containment directories
+                               // from this point onwards for each resource being exported
+                               IPath containersToCreate = currentResource.getFullPath()
+                                               .removeFirstSegments(
+                                                               fResource.getFullPath().segmentCount())
+                                               .removeLastSegments(1);
+
+                               for (int i = 0; i < containersToCreate.segmentCount(); i++) {
+                                       fPath = fPath.append(containersToCreate.segment(i));
+                                       fExporter2.createFolder(fPath);
+                               }
+                       }
+
+                       if (currentResource.getType() == IResource.FILE)
+                               exportFile2((IFile) currentResource, fPath);
+                       else {
+                               if (createContainerDirectories) {
+                                       fPath = fPath.append(currentResource.getName());
+                                       fExporter2.createFolder(fPath);
+                               }
+
+                               try {
+                                       exportChildren2(((IContainer) currentResource).members(),
+                                                       fPath);
+                               } catch (CoreException e) {
+                                       // should never happen because #isAccessible is called
+                                       // before #members is invoked,
+                                       // which implicitly does an existence check
+                                       errorTable.add(e.getStatus());
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Returns the status of the export operation. If there were any errors, the
+        * result is a status object containing individual status objects for each
+        * error. If there were no errors, the result is a status object with error
+        * code <code>OK</code>.
+        * 
+        * @return the status
+        */
+       public IStatus getStatus() {
+               IStatus[] errors = new IStatus[errorTable.size()];
+               errorTable.toArray(errors);
+               return new MultiStatus(
+                               PlatformUI.PLUGIN_ID,
+                               IStatus.OK,
+                               errors,
+                               ObfuscatorExportMessages
+                                               .getString("ObfuscatorExportOperation.problemsExporting"), //$NON-NLS-1$
+                               null);
+       }
+
+       /**
+        * Answer a boolean indicating whether the passed child is a descendent of
+        * one or more members of the passed resources collection
+        * 
+        * @return boolean
+        * @param resources
+        *            java.util.List
+        * @param child
+        *            org.eclipse.core.resources.IResource
+        */
+       protected boolean isDescendent(List resources, IResource child) {
+               if (child.getType() == IResource.PROJECT)
+                       return false;
+
+               IResource parent = child.getParent();
+               if (resources.contains(parent))
+                       return true;
+
+               return isDescendent(resources, parent);
+       }
+
+       private void setExporters(IResource resource) {
+               if (fCurrentIdentifierMap == null) {
+                       if (fProjectMap == null) {
+                               fProjectMap = new HashMap();
+                       }
+                       createExporters(resource);
+               } else {
+                       IProject project = resource.getProject();
+                       if (!fCurrentProjectName.equals(project.getName())) {
+                               HashMap temp = (HashMap) fProjectMap.get(project.getName());
+                               if (temp != null) {
+                                       fCurrentProjectName = project.getName();
+                                       fCurrentIdentifierMap = temp;
+                                       fExporter1 = new ObfuscatorPass1Exporter(new Scanner(false,
+                                                       false), fCurrentIdentifierMap);
+                                       fExporter2 = new ObfuscatorPass2Exporter(new Scanner(true,
+                                                       true), fCurrentIdentifierMap);
+                                       return;
+                               }
+                               createExporters(resource);
+                       }
+               }
+       }
+
+       private void createExporters(IResource resource) {
+               IProject project = resource.getProject();
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               ObfuscatorIgnores ignore = new ObfuscatorIgnores(project);
+               fCurrentIdentifierMap = ignore.getIdentifierMap();
+               fCurrentProjectName = project.getName();
+               fProjectMap.put(fCurrentProjectName, fCurrentIdentifierMap);
+               fExporter1 = new ObfuscatorPass1Exporter(new Scanner(false, false),
+                               fCurrentIdentifierMap);
+               fExporter2 = new ObfuscatorPass2Exporter(new Scanner(true, true),
+                               fCurrentIdentifierMap);
+       }
+
+       /**
+        * Export the resources that were previously specified for export (or if a
+        * single resource was specified then export it recursively)
+        */
+       public void run(IProgressMonitor monitor) throws InterruptedException {
+               this.fMonitor = monitor;
+               final IPath tempPath = (IPath) fPath.clone();
+               if (fResource != null) {
+                       setExporters(fResource);
+                       // if (createLeadupStructure)
+                       // createLeadupDirectoriesFor(resource);
+
+                       if (createContainerDirectories
+                                       && fResource.getType() != IResource.FILE) {
+                               // ensure it's a container
+                               fPath = fPath.append(fResource.getName());
+                               fExporter2.createFolder(fPath);
+                       }
+               }
+
+               try {
+                       // reset variables for this run:
+                       fCurrentIdentifierMap = null;
+                       fProjectMap = null;
+                       fCurrentProjectName = "";
+
+                       // count number of files
+                       int totalWork = IProgressMonitor.UNKNOWN;
+                       try {
+                               if (fResourcesToExport == null) {
+                                       totalWork = countChildrenOf(fResource);
+                               } else {
+                                       totalWork = countSelectedResources();
+                               }
+                       } catch (CoreException e) {
+                               // Should not happen
+                               errorTable.add(e.getStatus());
+                       }
+                       monitor
+                                       .beginTask(
+                                                       ObfuscatorExportMessages
+                                                                       .getString("ObfuscatorTransfer.exportingTitle1"), totalWork); //$NON-NLS-1$
+                       if (fResourcesToExport == null) {
+                               exportAllResources1();
+                       } else {
+                               exportSpecifiedResources1();
+                       }
+
+                       // try {
+                       // if (resourcesToExport == null)
+                       // totalWork = countChildrenOf(resource);
+                       // else
+                       // totalWork = countSelectedResources();
+                       // } catch (CoreException e) {
+                       // // Should not happen
+                       // errorTable.add(e.getStatus());
+                       // }
+
+                       // reset path:
+                       fPath = tempPath;
+                       monitor
+                                       .beginTask(
+                                                       ObfuscatorExportMessages
+                                                                       .getString("ObfuscatorTransfer.exportingTitle2"), totalWork); //$NON-NLS-1$
+                       if (fResourcesToExport == null) {
+                               exportAllResources2();
+                       } else {
+                               exportSpecifiedResources2();
+                       }
+               } finally {
+                       monitor.done();
+               }
+       }
+
+       /**
+        * Set this boolean indicating whether a directory should be created for
+        * Folder resources that are explicitly passed for export
+        * 
+        * @param value
+        *            boolean
+        */
+       // public void setCreateContainerDirectories(boolean value) {
+       // createContainerDirectories = value;
+       // }
+       /**
+        * Set this boolean indicating whether each exported resource's complete
+        * path should include containment hierarchies as dictated by its parents
+        * 
+        * @param value
+        *            boolean
+        */
+       // public void setCreateLeadupStructure(boolean value) {
+       // createLeadupStructure = value;
+       // }
+       /**
+        * Set this boolean indicating whether exported resources should
+        * automatically overwrite existing files when a conflict occurs. If not
+        * query the user.
+        * 
+        * @param value
+        *            boolean
+        */
+       public void setOverwriteFiles(boolean value) {
+               if (value)
+                       overwriteState = OVERWRITE_ALL;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportWizard.java
new file mode 100644 (file)
index 0000000..5111b04
--- /dev/null
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator.export;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IExportWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * Standard workbench wizard for exporting resources from the workspace to the
+ * local file system.
+ * <p>
+ * This class may be instantiated and used without further configuration; this
+ * class is not intended to be subclassed.
+ * </p>
+ * <p>
+ * Example:
+ * 
+ * <pre>
+ * IWizard wizard = new ObfuscatorExportWizard();
+ * wizard.init(workbench, selection);
+ * WizardDialog dialog = new WizardDialog(shell, wizard);
+ * dialog.open();
+ * </pre>
+ * 
+ * During the call to <code>open</code>, the wizard dialog is presented to
+ * the user. When the user hits Finish, the user-selected workspace resources
+ * are exported to the user-specified location in the local file system, the
+ * dialog closes, and the call to <code>open</code> returns.
+ * </p>
+ */
+public class ObfuscatorExportWizard extends Wizard implements IExportWizard {
+       private IWorkbench workbench;
+
+       private IStructuredSelection selection;
+
+       private WizardObfuscatorResourceExportPage1 mainPage;
+
+       /**
+        * Creates a wizard for exporting workspace resources to the local file
+        * system.
+        */
+       public ObfuscatorExportWizard() {
+               AbstractUIPlugin plugin = (AbstractUIPlugin) Platform
+                               .getPlugin(PlatformUI.PLUGIN_ID);
+               IDialogSettings workbenchSettings = plugin.getDialogSettings();
+               IDialogSettings section = workbenchSettings
+                               .getSection("ObfuscatorExportWizard");//$NON-NLS-1$
+               if (section == null)
+                       section = workbenchSettings.addNewSection("ObfuscatorExportWizard");//$NON-NLS-1$
+               setDialogSettings(section);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IWizard.
+        */
+       public void addPages() {
+               super.addPages();
+               mainPage = new WizardObfuscatorResourceExportPage1(selection);
+               addPage(mainPage);
+       }
+
+       /**
+        * Returns the image descriptor with the given relative path.
+        */
+       private ImageDescriptor getImageDescriptor(String relativePath) {
+               String iconPath = "icons/full/";//$NON-NLS-1$
+               try {
+                       AbstractUIPlugin plugin = (AbstractUIPlugin) Platform
+                                       .getPlugin(PlatformUI.PLUGIN_ID);
+                       URL installURL = plugin.getBundle().getEntry("/");
+                       URL url = new URL(installURL, iconPath + relativePath);
+                       return ImageDescriptor.createFromURL(url);
+               } catch (MalformedURLException e) {
+                       // Should not happen
+                       return null;
+               }
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IWorkbenchWizard.
+        */
+       public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
+               this.workbench = workbench;
+
+               // Make it the current selection by default but look it up otherwise
+
+               selection = currentSelection;
+
+               if (currentSelection.isEmpty()
+                               && workbench.getActiveWorkbenchWindow() != null) {
+                       IWorkbenchPage page = workbench.getActiveWorkbenchWindow()
+                                       .getActivePage();
+                       if (page != null) {
+                               IEditorPart currentEditor = page.getActiveEditor();
+                               if (currentEditor != null) {
+                                       Object selectedResource = currentEditor.getEditorInput()
+                                                       .getAdapter(IResource.class);
+                                       if (selectedResource != null)
+                                               selection = new StructuredSelection(selectedResource);
+                               }
+                       }
+               }
+
+               setWindowTitle(ObfuscatorExportMessages
+                               .getString("ObfuscatorTransfer.export")); //$NON-NLS-1$
+               setDefaultPageImageDescriptor(getImageDescriptor("wizban/exportdir_wiz.gif"));//$NON-NLS-1$
+               setNeedsProgressMonitor(true);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IWizard.
+        */
+       public boolean performFinish() {
+               return mainPage.finish();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/WizardObfuscatorResourceExportPage1.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/WizardObfuscatorResourceExportPage1.java
new file mode 100644 (file)
index 0000000..276c8e5
--- /dev/null
@@ -0,0 +1,505 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator.export;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+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.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.dialogs.WizardExportResourcesPage;
+
+/**
+ * Page 1 of the base resource export-to-file-system Wizard
+ */
+/* package */
+class WizardObfuscatorResourceExportPage1 extends WizardExportResourcesPage
+               implements Listener {
+
+       // widgets
+       private Combo destinationNameField;
+
+       private Button destinationBrowseButton;
+
+       protected Button overwriteExistingFilesCheckbox;
+
+       // protected Button createDirectoryStructureButton;
+       // protected Button createSelectionOnlyButton;
+
+       // constants
+       private static final int SIZING_TEXT_FIELD_WIDTH = 250;
+
+       // dialog store id constants
+       private static final String STORE_DESTINATION_NAMES_ID = "WizardObfuscatorResourceExportPage1.STORE_DESTINATION_NAMES_ID"; //$NON-NLS-1$
+
+       private static final String STORE_OVERWRITE_EXISTING_FILES_ID = "WizardObfuscatorResourceExportPage1.STORE_OVERWRITE_EXISTING_FILES_ID"; //$NON-NLS-1$
+       // private static final String STORE_CREATE_STRUCTURE_ID =
+       // "WizardObfuscatorResourceExportPage1.STORE_CREATE_STRUCTURE_ID";
+       // //$NON-NLS-1$
+
+       // messages
+       private static final String SELECT_DESTINATION_MESSAGE = ObfuscatorExportMessages
+                       .getString("FileExport.selectDestinationMessage"); //$NON-NLS-1$
+
+       private static final String SELECT_DESTINATION_TITLE = ObfuscatorExportMessages
+                       .getString("FileExport.selectDestinationTitle"); //$NON-NLS-1$
+
+       /**
+        * Create an instance of this class
+        */
+       protected WizardObfuscatorResourceExportPage1(String name,
+                       IStructuredSelection selection) {
+               super(name, selection);
+       }
+
+       /**
+        * Create an instance of this class
+        */
+       public WizardObfuscatorResourceExportPage1(IStructuredSelection selection) {
+               this("fileSystemExportPage1", selection); //$NON-NLS-1$
+               setTitle(ObfuscatorExportMessages
+                               .getString("ObfuscatorTransfer.fileSystemTitle")); //$NON-NLS-1$
+               setDescription(ObfuscatorExportMessages
+                               .getString("FileExport.exportLocalFileSystem")); //$NON-NLS-1$
+       }
+
+       /**
+        * Add the passed value to self's destination widget's history
+        * 
+        * @param value
+        *            java.lang.String
+        */
+       protected void addDestinationItem(String value) {
+               destinationNameField.add(value);
+       }
+
+       /**
+        * (non-Javadoc) Method declared on IDialogPage.
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               giveFocusToDestination();
+               // WorkbenchHelp.setHelp(
+               // getControl(),
+               // IDataTransferHelpContextIds.FILE_SYSTEM_EXPORT_WIZARD_PAGE);
+       }
+
+       /**
+        * Create the export destination specification widgets
+        * 
+        * @param parent
+        *            org.eclipse.swt.widgets.Composite
+        */
+       protected void createDestinationGroup(Composite parent) {
+
+               Font font = parent.getFont();
+               // destination specification group
+               Composite destinationSelectionGroup = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 3;
+               destinationSelectionGroup.setLayout(layout);
+               destinationSelectionGroup.setLayoutData(new GridData(
+                               GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+               destinationSelectionGroup.setFont(font);
+
+               Label destinationLabel = new Label(destinationSelectionGroup, SWT.NONE);
+               destinationLabel.setText(getDestinationLabel());
+               destinationLabel.setFont(font);
+
+               // destination name entry field
+               destinationNameField = new Combo(destinationSelectionGroup, SWT.SINGLE
+                               | SWT.BORDER);
+               destinationNameField.addListener(SWT.Modify, this);
+               destinationNameField.addListener(SWT.Selection, this);
+               GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.GRAB_HORIZONTAL);
+               data.widthHint = SIZING_TEXT_FIELD_WIDTH;
+               destinationNameField.setLayoutData(data);
+               destinationNameField.setFont(font);
+
+               // destination browse button
+               destinationBrowseButton = new Button(destinationSelectionGroup,
+                               SWT.PUSH);
+               destinationBrowseButton.setText(ObfuscatorExportMessages
+                               .getString("ObfuscatorTransfer.browse")); //$NON-NLS-1$
+               destinationBrowseButton.addListener(SWT.Selection, this);
+               destinationBrowseButton.setFont(font);
+               setButtonLayoutData(destinationBrowseButton);
+
+               new Label(parent, SWT.NONE); // vertical spacer
+       }
+
+       /**
+        * Create the buttons in the options group.
+        */
+
+       protected void createOptionsGroupButtons(Group optionsGroup) {
+
+               Font font = optionsGroup.getFont();
+               createOverwriteExisting(optionsGroup, font);
+
+               // createDirectoryStructureOptions(optionsGroup, font);
+       }
+
+       /**
+        * Create the buttons for the group that determine if the entire or selected
+        * directory structure should be created.
+        * 
+        * @param optionsGroup
+        * @param font
+        */
+       // protected void createDirectoryStructureOptions(
+       // Group optionsGroup,
+       // Font font) {
+       // // create directory structure radios
+       // createDirectoryStructureButton =
+       // new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
+       // createDirectoryStructureButton.setText(ObfuscatorExportMessages.getString("FileExport.createDirectoryStructure"));
+       // //$NON-NLS-1$
+       // createDirectoryStructureButton.setSelection(false);
+       // createDirectoryStructureButton.setFont(font);
+       //
+       // // create directory structure radios
+       // createSelectionOnlyButton =
+       // new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
+       // createSelectionOnlyButton.setText(
+       // ObfuscatorExportMessages.getString(
+       // "FileExport.createSelectedDirectories"));//$NON-NLS-1$
+       // createSelectionOnlyButton.setSelection(true);
+       // createSelectionOnlyButton.setFont(font);
+       // }
+       /**
+        * Create the button for checking if we should ask if we are going to
+        * overwrite existing files.
+        * 
+        * @param optionsGroup
+        * @param font
+        */
+       protected void createOverwriteExisting(Group optionsGroup, Font font) {
+               // overwrite... checkbox
+               overwriteExistingFilesCheckbox = new Button(optionsGroup, SWT.CHECK
+                               | SWT.LEFT);
+               overwriteExistingFilesCheckbox.setText(ObfuscatorExportMessages
+                               .getString("ExportFile.overwriteExisting")); //$NON-NLS-1$
+               overwriteExistingFilesCheckbox.setFont(font);
+       }
+
+       /**
+        * Attempts to ensure that the specified directory exists on the local file
+        * system. Answers a boolean indicating success.
+        * 
+        * @return boolean
+        * @param directory
+        *            java.io.File
+        */
+       protected boolean ensureDirectoryExists(File directory) {
+               if (!directory.exists()) {
+                       if (!queryYesNoQuestion(ObfuscatorExportMessages
+                                       .getString("ObfuscatorTransfer.createTargetDirectory"))) //$NON-NLS-1$
+                               return false;
+
+                       if (!directory.mkdirs()) {
+                               displayErrorDialog(ObfuscatorExportMessages
+                                               .getString("ObfuscatorTransfer.directoryCreationError")); //$NON-NLS-1$
+                               giveFocusToDestination();
+                               return false;
+                       }
+               }
+
+               return true;
+       }
+
+       /**
+        * If the target for export does not exist then attempt to create it. Answer
+        * a boolean indicating whether the target exists (ie.- if it either
+        * pre-existed or this method was able to create it)
+        * 
+        * @return boolean
+        */
+       protected boolean ensureTargetIsValid(File targetDirectory) {
+               if (targetDirectory.exists() && !targetDirectory.isDirectory()) {
+                       displayErrorDialog(ObfuscatorExportMessages
+                                       .getString("FileExport.directoryExists")); //$NON-NLS-1$
+                       giveFocusToDestination();
+                       return false;
+               }
+
+               return ensureDirectoryExists(targetDirectory);
+       }
+
+       /**
+        * Set up and execute the passed Operation. Answer a boolean indicating
+        * success.
+        * 
+        * @return boolean
+        */
+       protected boolean executeExportOperation(ObfuscatorExportOperation op) {
+               // op.setCreateLeadupStructure(
+               // createDirectoryStructureButton.getSelection());
+               op.setOverwriteFiles(overwriteExistingFilesCheckbox.getSelection());
+
+               try {
+                       getContainer().run(true, true, op);
+               } catch (InterruptedException e) {
+                       return false;
+               } catch (InvocationTargetException e) {
+                       displayErrorDialog(e.getTargetException());
+                       return false;
+               }
+
+               IStatus status = op.getStatus();
+               if (!status.isOK()) {
+                       ErrorDialog.openError(getContainer().getShell(),
+                                       ObfuscatorExportMessages
+                                                       .getString("ObfuscatorTransfer.exportProblems"), //$NON-NLS-1$
+                                       null, // no special message
+                                       status);
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * The Finish button was pressed. Try to do the required work now and answer
+        * a boolean indicating success. If false is returned then the wizard will
+        * not close.
+        * 
+        * @return boolean
+        */
+       public boolean finish() {
+               if (!ensureTargetIsValid(new File(getDestinationValue())))
+                       return false;
+
+               List resourcesToExport = getWhiteCheckedResources();
+
+               // Save dirty editors if possible but do not stop if not all are saved
+               saveDirtyEditors();
+               // about to invoke the operation so save our state
+               saveWidgetValues();
+
+               if (resourcesToExport.size() > 0)
+                       return executeExportOperation(new ObfuscatorExportOperation(null,
+                                       resourcesToExport, getDestinationValue(), this));
+
+               MessageDialog.openInformation(getContainer().getShell(),
+                               ObfuscatorExportMessages
+                                               .getString("ObfuscatorTransfer.information"), //$NON-NLS-1$
+                               ObfuscatorExportMessages.getString("FileExport.noneSelected")); //$NON-NLS-1$
+
+               return false;
+       }
+
+       /**
+        * Answer the string to display in self as the destination type
+        * 
+        * @return java.lang.String
+        */
+       protected String getDestinationLabel() {
+               return ObfuscatorExportMessages.getString("FileExport.toDirectory"); //$NON-NLS-1$
+       }
+
+       /**
+        * Answer the contents of self's destination specification widget
+        * 
+        * @return java.lang.String
+        */
+       protected String getDestinationValue() {
+               return destinationNameField.getText().trim();
+       }
+
+       /**
+        * Set the current input focus to self's destination entry field
+        */
+       protected void giveFocusToDestination() {
+               destinationNameField.setFocus();
+       }
+
+       /**
+        * Open an appropriate destination browser so that the user can specify a
+        * source to import from
+        */
+       protected void handleDestinationBrowseButtonPressed() {
+               DirectoryDialog dialog = new DirectoryDialog(getContainer().getShell(),
+                               SWT.SAVE);
+               dialog.setMessage(SELECT_DESTINATION_MESSAGE);
+               dialog.setText(SELECT_DESTINATION_TITLE);
+               dialog.setFilterPath(getDestinationValue());
+               String selectedDirectoryName = dialog.open();
+
+               if (selectedDirectoryName != null) {
+                       setErrorMessage(null);
+                       setDestinationValue(selectedDirectoryName);
+               }
+       }
+
+       /**
+        * Handle all events and enablements for widgets in this page
+        * 
+        * @param e
+        *            Event
+        */
+       public void handleEvent(Event e) {
+               Widget source = e.widget;
+
+               if (source == destinationBrowseButton)
+                       handleDestinationBrowseButtonPressed();
+
+               updatePageCompletion();
+       }
+
+       /**
+        * Hook method for saving widget values for restoration by the next instance
+        * of this class.
+        */
+       protected void internalSaveWidgetValues() {
+               // update directory names history
+               IDialogSettings settings = getDialogSettings();
+               if (settings != null) {
+                       String[] directoryNames = settings
+                                       .getArray(STORE_DESTINATION_NAMES_ID);
+                       if (directoryNames == null)
+                               directoryNames = new String[0];
+
+                       directoryNames = addToHistory(directoryNames, getDestinationValue());
+                       settings.put(STORE_DESTINATION_NAMES_ID, directoryNames);
+
+                       // options
+                       settings.put(STORE_OVERWRITE_EXISTING_FILES_ID,
+                                       overwriteExistingFilesCheckbox.getSelection());
+
+                       // settings.put(
+                       // STORE_CREATE_STRUCTURE_ID,
+                       // createDirectoryStructureButton.getSelection());
+
+               }
+       }
+
+       /**
+        * Hook method for restoring widget values to the values that they held last
+        * time this wizard was used to completion.
+        */
+       protected void restoreWidgetValues() {
+               IDialogSettings settings = getDialogSettings();
+               if (settings != null) {
+                       String[] directoryNames = settings
+                                       .getArray(STORE_DESTINATION_NAMES_ID);
+                       if (directoryNames == null)
+                               return; // ie.- no settings stored
+
+                       // destination
+                       setDestinationValue(directoryNames[0]);
+                       for (int i = 0; i < directoryNames.length; i++)
+                               addDestinationItem(directoryNames[i]);
+
+                       // options
+                       overwriteExistingFilesCheckbox.setSelection(settings
+                                       .getBoolean(STORE_OVERWRITE_EXISTING_FILES_ID));
+
+                       // boolean createDirectories =
+                       // settings.getBoolean(STORE_CREATE_STRUCTURE_ID);
+                       // createDirectoryStructureButton.setSelection(createDirectories);
+                       // createSelectionOnlyButton.setSelection(!createDirectories);
+               }
+       }
+
+       /**
+        * Set the contents of the receivers destination specification widget to the
+        * passed value
+        * 
+        */
+       protected void setDestinationValue(String value) {
+               destinationNameField.setText(value);
+       }
+
+       /**
+        * Answer a boolean indicating whether the receivers destination
+        * specification widgets currently all contain valid values.
+        */
+       protected boolean validateDestinationGroup() {
+               String destinationValue = getDestinationValue();
+               if (destinationValue.length() == 0) {
+                       setMessage(destinationEmptyMessage());
+                       return false;
+               }
+
+               String conflictingContainer = getConflictingContainerNameFor(destinationValue);
+               if (conflictingContainer == null)
+                       setErrorMessage(""); //$NON-NLS-1$
+               else {
+                       setErrorMessage(ObfuscatorExportMessages.format(
+                                       "FileExport.conflictingContainer", //$NON-NLS-1$
+                                       new Object[] { conflictingContainer }));
+                       giveFocusToDestination();
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * Get the message used to denote an empty destination.
+        */
+       protected String destinationEmptyMessage() {
+               return ObfuscatorExportMessages
+                               .getString("FileExport.destinationEmpty"); //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the name of a container with a location that encompasses
+        * targetDirectory. Returns null if there is no conflict.
+        * 
+        * @param targetDirectory
+        *            the path of the directory to check.
+        * @return the conflicting container name or <code>null</code>
+        */
+       protected String getConflictingContainerNameFor(String targetDirectory) {
+
+               IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+               IPath testPath = new Path(targetDirectory);
+
+               if (root.getFullPath().isPrefixOf(testPath))
+                       return ObfuscatorExportMessages.getString("FileExport.rootName"); //$NON-NLS-1$
+
+               IProject[] projects = root.getProjects();
+
+               for (int i = 0; i < projects.length; i++) {
+                       if (projects[i].getFullPath().isPrefixOf(testPath))
+                               return projects[i].getName();
+               }
+
+               return null;
+
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/messages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/obfuscator/export/messages.properties
new file mode 100644 (file)
index 0000000..baaf49d
--- /dev/null
@@ -0,0 +1,64 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+# package: org.eclipse.ui.wizards.ObfuscatorTransfer
+
+# ==============================================================================
+# Data Transfer Wizards
+# ==============================================================================
+ObfuscatorTransfer.fileSystemTitle = File system
+
+ObfuscatorTransfer.browse = B&rowse...
+ObfuscatorTransfer.selectTypes = Filter &Types...
+ObfuscatorTransfer.selectAll = &Select All
+ObfuscatorTransfer.deselectAll = &Deselect All
+
+ObfuscatorTransfer.typeDelimiter = ,
+ObfuscatorTransfer.allFiles = All files matching this criteria
+ObfuscatorTransfer.oneSelected = 1 file selected
+ObfuscatorTransfer.details = Details...
+ObfuscatorTransfer.allTypes = All types
+
+ObfuscatorTransfer.cannotOverwrite = Cannot overwrite file: {0}
+ObfuscatorTransfer.emptyString = 
+ObfuscatorTransfer.scanningChildren = Scanning for children...
+ObfuscatorTransfer.scanningMatching = Scanning for matching files...
+ObfuscatorTransfer.information = Information
+
+# --- Export Wizards ---
+ObfuscatorTransfer.export = Obfuscator Export
+
+ObfuscatorTransfer.exportingTitle1 = Obfuscating Pass 1:
+ObfuscatorTransfer.exportingTitle2 = Obfuscating Pass 2:
+ObfuscatorTransfer.selectDestination = Select the destination directory.
+ObfuscatorTransfer.directory = Director&y:
+ObfuscatorTransfer.createTargetDirectory = Target directory does not exist.  Would you like to create it?
+ObfuscatorTransfer.directoryCreationError = Target directory could not be created.
+ObfuscatorTransfer.errorExporting = Error exporting {0}: {1}
+ObfuscatorTransfer.exportProblems = Export Problems
+
+ExportFile.overwriteExisting = &Overwrite existing files without warning
+ExportFile.createDirectoriesForSelected = Create directories for selected folders
+ExportFile.createDirectoryStructure = &Create directory structure
+
+FileExport.selectDestinationTitle= Export To Directory
+FileExport.selectDestinationMessage=Select a directory to export to.
+FileExport.exportLocalFileSystem = Export obfuscated PHP resources to the local file system.
+FileExport.destinationEmpty = Please enter a destination directory.
+FileExport.createDirectoryStructure = &Create directory structure for files
+FileExport.createSelectedDirectories = Create on&ly selected directories
+FileExport.noneSelected = There are no resources currently selected for export.
+FileExport.directoryExists = Target directory already exists as a file.
+FileExport.conflictingContainer = Destination directory conflicts with location of {0}.
+FileExport.rootName = workspace root
+ObfuscatorExportOperation.problemsExporting = Problems were encountered during export:
+FileExport.toDirectory = To director&y:
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/AnnotationType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/AnnotationType.java
new file mode 100644 (file)
index 0000000..6fadf0c
--- /dev/null
@@ -0,0 +1,59 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import org.eclipse.jface.text.Assert;
+
+public final class AnnotationType {
+
+       public static final AnnotationType ALL = new AnnotationType();
+
+       public static final AnnotationType UNKNOWN = new AnnotationType();
+
+       public static final AnnotationType BOOKMARK = new AnnotationType();
+
+       public static final AnnotationType TASK = new AnnotationType();
+
+       public static final AnnotationType ERROR = new AnnotationType();
+
+       public static final AnnotationType WARNING = new AnnotationType();
+
+       public static final AnnotationType SEARCH = new AnnotationType();
+
+       private AnnotationType() {
+       }
+
+       public String toString() {
+               if (this == ALL)
+                       return "AnnotationType.ALL"; //$NON-NLS-1$
+
+               if (this == UNKNOWN)
+                       return "AnnotationType.UNKNOWN"; //$NON-NLS-1$
+
+               if (this == BOOKMARK)
+                       return "AnnotationType.BOOKMARK"; //$NON-NLS-1$
+
+               if (this == TASK)
+                       return "AnnotationType.TASK"; //$NON-NLS-1$
+
+               if (this == ERROR)
+                       return "AnnotationType.ERROR"; //$NON-NLS-1$
+
+               if (this == WARNING)
+                       return "AnnotationType.WARNING"; //$NON-NLS-1$
+
+               if (this == SEARCH)
+                       return "AnnotationType.SEARCH"; //$NON-NLS-1$
+
+               Assert.isLegal(false);
+               return ""; //$NON-NLS-1$
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BasicEditorActionContributor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BasicEditorActionContributor.java
new file mode 100644 (file)
index 0000000..1f542a7
--- /dev/null
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import net.sourceforge.phpdt.ui.actions.PHPdtActionConstants;
+
+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.RetargetAction;
+import org.eclipse.ui.editors.text.EncodingActionGroup;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.RetargetTextEditorAction;
+
+public class BasicEditorActionContributor extends
+               BasicJavaEditorActionContributor {
+
+       protected RetargetAction fRetargetContentAssist;
+
+       protected RetargetTextEditorAction fContentAssist;
+
+       // protected RetargetTextEditorAction fContextInformation;
+       // protected RetargetTextEditorAction fCorrectionAssist;
+       private EncodingActionGroup fEncodingActionGroup;
+
+       public BasicEditorActionContributor() {
+
+               fRetargetContentAssist = new RetargetAction(
+                               PHPdtActionConstants.CONTENT_ASSIST, PHPEditorMessages
+                                               .getString("ContentAssistProposal.label")); //$NON-NLS-1$
+               fRetargetContentAssist
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+               markAsPartListener(fRetargetContentAssist);
+
+               fContentAssist = new RetargetTextEditorAction(PHPEditorMessages
+                               .getResourceBundle(), "ContentAssistProposal."); //$NON-NLS-1$
+               fContentAssist
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+               fContentAssist.setImageDescriptor(PHPUiImages.DESC_CLCL_CODE_ASSIST);
+               fContentAssist
+                               .setDisabledImageDescriptor(PHPUiImages.DESC_DLCL_CODE_ASSIST);
+
+               // fContextInformation= new
+               // RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(),
+               // "ContentAssistContextInformation."); //$NON-NLS-1$
+               // fContextInformation.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
+
+               // fCorrectionAssist= new
+               // RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(),
+               // "CorrectionAssistProposal."); //$NON-NLS-1$
+               // fCorrectionAssist.setActionDefinitionId(PHPEditorActionDefinitionIds.CORRECTION_ASSIST_PROPOSALS);
+
+               // character encoding
+               fEncodingActionGroup = new EncodingActionGroup();
+       }
+
+       /*
+        * @see EditorActionBarContributor#contributeToMenu(IMenuManager)
+        */
+       public void contributeToMenu(IMenuManager menu) {
+
+               super.contributeToMenu(menu);
+
+               IMenuManager editMenu = menu
+                               .findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+               if (editMenu != null) {
+                       editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE,
+                                       fRetargetContentAssist);
+                       // editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE,
+                       // fCorrectionAssist);
+                       // editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE,
+                       // fContextInformation);
+               }
+       }
+
+       /*
+        * @see IEditorActionBarContributor#setActiveEditor(IEditorPart)
+        */
+       public void setActiveEditor(IEditorPart part) {
+               super.setActiveEditor(part);
+
+               ITextEditor textEditor = null;
+               if (part instanceof ITextEditor)
+                       textEditor = (ITextEditor) part;
+
+               fContentAssist
+                               .setAction(getAction(textEditor, "ContentAssistProposal")); //$NON-NLS-1$
+               // fContextInformation.setAction(getAction(textEditor,
+               // "ContentAssistContextInformation")); //$NON-NLS-1$
+               // fCorrectionAssist.setAction(getAction(textEditor,
+               // "CorrectionAssistProposal")); //$NON-NLS-1$
+
+               IActionBars actionBars = getActionBars();
+               actionBars.setGlobalActionHandler(PHPdtActionConstants.SHIFT_RIGHT,
+                               getAction(textEditor, "ShiftRight")); //$NON-NLS-1$
+               actionBars.setGlobalActionHandler(PHPdtActionConstants.SHIFT_LEFT,
+                               getAction(textEditor, "ShiftLeft")); //$NON-NLS-1$
+
+               actionBars.setGlobalActionHandler(IDEActionFactory.ADD_TASK.getId(),
+                               getAction(textEditor, IDEActionFactory.ADD_TASK.getId())); //$NON-NLS-1$
+               actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(),
+                               getAction(textEditor, IDEActionFactory.BOOKMARK.getId())); //$NON-NLS-1$
+
+               // character encoding
+               fEncodingActionGroup.retarget(textEditor);
+       }
+
+       /*
+        * @see IEditorActionBarContributor#init(IActionBars, IWorkbenchPage)
+        */
+       public void init(IActionBars bars, IWorkbenchPage page) {
+               super.init(bars, page);
+
+               // register actions that have a dynamic editor.
+               bars.setGlobalActionHandler(PHPdtActionConstants.CONTENT_ASSIST,
+                               fContentAssist);
+               // character encoding
+               fEncodingActionGroup.fillActionBars(bars);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BasicJavaEditorActionContributor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BasicJavaEditorActionContributor.java
new file mode 100644 (file)
index 0000000..ebbc553
--- /dev/null
@@ -0,0 +1,287 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpdt.internal.ui.actions.FoldingActionGroup;
+import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.actions.RetargetAction;
+import org.eclipse.ui.texteditor.BasicTextEditorActionContributor;
+import org.eclipse.ui.texteditor.GotoAnnotationAction;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.RetargetTextEditorAction;
+
+/**
+ * Common base class for action contributors for Java editors.
+ */
+public class BasicJavaEditorActionContributor extends
+               BasicTextEditorActionContributor {
+
+       private List fPartListeners = new ArrayList();
+
+       private TogglePresentationAction fTogglePresentation;
+
+       private GotoAnnotationAction fPreviousAnnotation;
+       private GotoAnnotationAction fNextAnnotation;
+
+       private RetargetTextEditorAction fGotoMatchingBracket;
+
+       // private RetargetTextEditorAction fShowOutline;
+       // private RetargetTextEditorAction fOpenStructure;
+       // private RetargetTextEditorAction fOpenHierarchy;
+
+       // private RetargetAction fRetargetShowJavaDoc;
+       // private RetargetTextEditorAction fShowJavaDoc;
+
+       // private RetargetTextEditorAction fStructureSelectEnclosingAction;
+       // private RetargetTextEditorAction fStructureSelectNextAction;
+       // private RetargetTextEditorAction fStructureSelectPreviousAction;
+       // private RetargetTextEditorAction fStructureSelectHistoryAction;
+
+       private RetargetTextEditorAction fGotoNextMemberAction;
+
+       private RetargetTextEditorAction fGotoPreviousMemberAction;
+
+       //
+       // private RetargetTextEditorAction fRemoveOccurrenceAnnotationsAction;
+
+       public BasicJavaEditorActionContributor() {
+               super();
+
+               ResourceBundle b = PHPEditorMessages.getResourceBundle();
+
+               // fRetargetShowJavaDoc= new
+               // RetargetAction(PHPdtActionConstants.SHOW_JAVA_DOC,
+               // PHPEditorMessages.getString("ShowJavaDoc.label")); //$NON-NLS-1$
+               // fRetargetShowJavaDoc.setActionDefinitionId(net.sourceforge.phpdt.ui.actions.PHPEditorActionDefinitionIds.SHOW_JAVADOC);
+               // markAsPartListener(fRetargetShowJavaDoc);
+
+               // actions that are "contributed" to editors, they are considered
+               // belonging to the active editor
+               fTogglePresentation = new TogglePresentationAction();
+
+               fPreviousAnnotation = new GotoAnnotationAction(b,
+                               "PreviousAnnotation.", null, false); //$NON-NLS-1$
+               fNextAnnotation = new GotoAnnotationAction(b,
+                               "NextAnnotation.", null, true); //$NON-NLS-1$
+
+               fGotoMatchingBracket = new RetargetTextEditorAction(b,
+                               "GotoMatchingBracket."); //$NON-NLS-1$
+               fGotoMatchingBracket
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
+
+               // fShowJavaDoc= new RetargetTextEditorAction(b, "ShowJavaDoc.");
+               // //$NON-NLS-1$
+               // fShowJavaDoc.setActionDefinitionId(net.sourceforge.phpdt.ui.actions.PHPEditorActionDefinitionIds.SHOW_JAVADOC);
+
+               // fShowOutline= new
+               // RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(),
+               // "ShowOutline."); //$NON-NLS-1$
+               // fShowOutline.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE);
+               //
+               // fOpenHierarchy= new
+               // RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(),
+               // "OpenHierarchy."); //$NON-NLS-1$
+               // fOpenHierarchy.setActionDefinitionId(PHPEditorActionDefinitionIds.OPEN_HIERARCHY);
+               //      
+               // fOpenStructure= new
+               // RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(),
+               // "OpenStructure."); //$NON-NLS-1$
+               // fOpenStructure.setActionDefinitionId(PHPEditorActionDefinitionIds.OPEN_STRUCTURE);
+
+               // fStructureSelectEnclosingAction= new RetargetTextEditorAction(b,
+               // "StructureSelectEnclosing."); //$NON-NLS-1$
+               // fStructureSelectEnclosingAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_ENCLOSING);
+               // fStructureSelectNextAction= new RetargetTextEditorAction(b,
+               // "StructureSelectNext."); //$NON-NLS-1$
+               // fStructureSelectNextAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_NEXT);
+               // fStructureSelectPreviousAction= new RetargetTextEditorAction(b,
+               // "StructureSelectPrevious."); //$NON-NLS-1$
+               // fStructureSelectPreviousAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_PREVIOUS);
+               // fStructureSelectHistoryAction= new RetargetTextEditorAction(b,
+               // "StructureSelectHistory."); //$NON-NLS-1$
+               // fStructureSelectHistoryAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_LAST);
+               //              
+               fGotoNextMemberAction = new RetargetTextEditorAction(b,
+                               "GotoNextMember."); //$NON-NLS-1$
+               fGotoNextMemberAction
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_NEXT_MEMBER);
+               fGotoPreviousMemberAction = new RetargetTextEditorAction(b,
+                               "GotoPreviousMember."); //$NON-NLS-1$
+               fGotoPreviousMemberAction
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER);
+               //
+               // fRemoveOccurrenceAnnotationsAction= new RetargetTextEditorAction(b,
+               // "RemoveOccurrenceAnnotations."); //$NON-NLS-1$
+               // fRemoveOccurrenceAnnotationsAction.setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_OCCURRENCE_ANNOTATIONS);
+       }
+
+       protected final void markAsPartListener(RetargetAction action) {
+               fPartListeners.add(action);
+       }
+
+       /*
+        * @see IEditorActionBarContributor#init(IActionBars, IWorkbenchPage)
+        */
+       public void init(IActionBars bars, IWorkbenchPage page) {
+               Iterator e = fPartListeners.iterator();
+               while (e.hasNext())
+                       page.addPartListener((RetargetAction) e.next());
+
+               super.init(bars, page);
+
+               // register actions that have a dynamic editor.
+               bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_NEXT_ANNOTATION, fNextAnnotation);
+               bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_PREVIOUS_ANNOTATION, fPreviousAnnotation);
+               bars.setGlobalActionHandler(ITextEditorActionConstants.NEXT, fNextAnnotation);
+               bars.setGlobalActionHandler(ITextEditorActionConstants.PREVIOUS, fPreviousAnnotation);
+               bars
+                               .setGlobalActionHandler(
+                                               ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY,
+                                               fTogglePresentation);
+
+               // bars.setGlobalActionHandler(PHPdtActionConstants.SHOW_JAVA_DOC,
+               // fShowJavaDoc);
+       }
+
+       /*
+        * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToMenu(org.eclipse.jface.action.IMenuManager)
+        */
+       public void contributeToMenu(IMenuManager menu) {
+
+               super.contributeToMenu(menu);
+
+               IMenuManager editMenu = menu
+                               .findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+               if (editMenu != null) {
+
+                       editMenu.add(new Separator(IContextMenuConstants.GROUP_OPEN));
+                       editMenu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
+                       editMenu.add(new Separator(IContextMenuConstants.GROUP_ADDITIONS));
+
+                       // MenuManager structureSelection= new
+                       // MenuManager(PHPEditorMessages.getString("ExpandSelectionMenu.label"),
+                       // "expandSelection"); //$NON-NLS-1$ //$NON-NLS-2$
+                       // structureSelection.add(fStructureSelectEnclosingAction);
+                       // structureSelection.add(fStructureSelectNextAction);
+                       // structureSelection.add(fStructureSelectPreviousAction);
+                       // structureSelection.add(fStructureSelectHistoryAction);
+                       // editMenu.appendToGroup(IContextMenuConstants.GROUP_OPEN,
+                       // structureSelection);
+
+                       // editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE,
+                       // fRetargetShowJavaDoc);
+               }
+
+               // IMenuManager navigateMenu=
+               // menu.findMenuUsingPath(IWorkbenchActionConstants.M_NAVIGATE);
+               // if (navigateMenu != null) {
+               // navigateMenu.appendToGroup(IWorkbenchActionConstants.SHOW_EXT,
+               // fShowOutline);
+               // navigateMenu.appendToGroup(IWorkbenchActionConstants.SHOW_EXT,
+               // fOpenHierarchy);
+               // }
+
+               IMenuManager gotoMenu = menu.findMenuUsingPath("navigate/goTo"); //$NON-NLS-1$
+               if (gotoMenu != null) {
+                       gotoMenu.add(new Separator("additions2")); //$NON-NLS-1$
+                       gotoMenu.appendToGroup("additions2", fGotoPreviousMemberAction); //$NON-NLS-1$
+                       gotoMenu.appendToGroup("additions2", fGotoNextMemberAction); //$NON-NLS-1$
+                       gotoMenu.appendToGroup("additions2", fGotoMatchingBracket); //$NON-NLS-1$
+               }
+       }
+
+       /*
+        * @see EditorActionBarContributor#setActiveEditor(IEditorPart)
+        */
+       public void setActiveEditor(IEditorPart part) {
+
+               super.setActiveEditor(part);
+
+               IActionBars actionBars = getActionBars();
+               IStatusLineManager manager = actionBars.getStatusLineManager();
+               manager.setMessage(null);
+               manager.setErrorMessage(null);
+
+               ITextEditor textEditor = null;
+               if (part instanceof ITextEditor)
+                       textEditor = (ITextEditor) part;
+
+               fTogglePresentation.setEditor(textEditor);
+               fPreviousAnnotation.setEditor(textEditor);
+               fNextAnnotation.setEditor(textEditor);
+
+               fGotoMatchingBracket.setAction(getAction(textEditor,
+                               GotoMatchingBracketAction.GOTO_MATCHING_BRACKET));
+               // fShowJavaDoc.setAction(getAction(textEditor, "ShowJavaDoc"));
+               // //$NON-NLS-1$
+               // fShowOutline.setAction(getAction(textEditor,
+               // IJavaEditorActionDefinitionIds.SHOW_OUTLINE));
+               // fOpenHierarchy.setAction(getAction(textEditor,
+               // IJavaEditorActionDefinitionIds.OPEN_HIERARCHY));
+               // fOpenStructure.setAction(getAction(textEditor,
+               // IJavaEditorActionDefinitionIds.OPEN_STRUCTURE));
+
+               // fStructureSelectEnclosingAction.setAction(getAction(textEditor,
+               // StructureSelectionAction.ENCLOSING));
+               // fStructureSelectNextAction.setAction(getAction(textEditor,
+               // StructureSelectionAction.NEXT));
+               // fStructureSelectPreviousAction.setAction(getAction(textEditor,
+               // StructureSelectionAction.PREVIOUS));
+               // fStructureSelectHistoryAction.setAction(getAction(textEditor,
+               // StructureSelectionAction.HISTORY));
+
+               // fGotoNextMemberAction.setAction(getAction(textEditor,
+               // GoToNextPreviousMemberAction.NEXT_MEMBER));
+               // fGotoPreviousMemberAction.setAction(getAction(textEditor,
+               // GoToNextPreviousMemberAction.PREVIOUS_MEMBER));
+
+               // fRemoveOccurrenceAnnotationsAction.setAction(getAction(textEditor,
+               // "RemoveOccurrenceAnnotations")); //$NON-NLS-1$
+               if (part instanceof PHPEditor) {
+                       PHPEditor javaEditor = (PHPEditor) part;
+                       javaEditor.getActionGroup().fillActionBars(getActionBars());
+                       FoldingActionGroup foldingActions = javaEditor
+                                       .getFoldingActionGroup();
+                       if (foldingActions != null)
+                               foldingActions.updateActionBars();
+               }
+       }
+
+       /*
+        * @see IEditorActionBarContributor#dispose()
+        */
+       public void dispose() {
+
+               Iterator e = fPartListeners.iterator();
+               while (e.hasNext())
+                       getPage().removePartListener((RetargetAction) e.next());
+               fPartListeners.clear();
+
+               setActiveEditor(null);
+               super.dispose();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BracketPainter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BracketPainter.java
new file mode 100644 (file)
index 0000000..e73790b
--- /dev/null
@@ -0,0 +1,179 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+
+public final class BracketPainter implements IPainter, PaintListener {
+
+       private PHPPairMatcher fMatcher = new PHPPairMatcher(new char[] { '{', '}',
+                       '(', ')', '[', ']' });
+
+       private Position fBracketPosition = new Position(0, 0);
+
+       private int fAnchor;
+
+       private boolean fIsActive = false;
+
+       private ISourceViewer fSourceViewer;
+
+       private StyledText fTextWidget;
+
+       private Color fColor;
+
+       private IPositionManager fPositionManager;
+
+       public BracketPainter(ISourceViewer sourceViewer) {
+               fSourceViewer = sourceViewer;
+               fTextWidget = sourceViewer.getTextWidget();
+       }
+
+       public void setHighlightColor(Color color) {
+               fColor = color;
+       }
+
+       public void dispose() {
+               if (fMatcher != null) {
+                       fMatcher.dispose();
+                       fMatcher = null;
+               }
+
+               fColor = null;
+               fTextWidget = null;
+       }
+
+       public void deactivate(boolean redraw) {
+               if (fIsActive) {
+                       fIsActive = false;
+                       fTextWidget.removePaintListener(this);
+                       if (fPositionManager != null)
+                               fPositionManager.removeManagedPosition(fBracketPosition);
+                       if (redraw)
+                               handleDrawRequest(null);
+               }
+       }
+
+       public void paintControl(PaintEvent event) {
+               if (fTextWidget != null)
+                       handleDrawRequest(event.gc);
+       }
+
+       private void handleDrawRequest(GC gc) {
+
+               if (fBracketPosition.isDeleted)
+                       return;
+
+               int offset = fBracketPosition.getOffset();
+               int length = fBracketPosition.getLength();
+               if (length < 1)
+                       return;
+
+               if (fSourceViewer instanceof ITextViewerExtension5) {
+                       ITextViewerExtension5 extension = (ITextViewerExtension5) fSourceViewer;
+                       IRegion widgetRange = extension.modelRange2WidgetRange(new Region(
+                                       offset, length));
+                       if (widgetRange == null)
+                               return;
+
+                       offset = widgetRange.getOffset();
+                       length = widgetRange.getLength();
+
+               } else {
+                       IRegion region = fSourceViewer.getVisibleRegion();
+                       if (region.getOffset() > offset
+                                       || region.getOffset() + region.getLength() < offset
+                                                       + length)
+                               return;
+                       offset -= region.getOffset();
+               }
+
+               if (PHPPairMatcher.RIGHT == fAnchor)
+                       draw(gc, offset, 1);
+               else
+                       draw(gc, offset + length - 1, 1);
+       }
+
+       private void draw(GC gc, int offset, int length) {
+               if (gc != null) {
+                       Point left = fTextWidget.getLocationAtOffset(offset);
+                       Point right = fTextWidget.getLocationAtOffset(offset + length);
+
+                       gc.setForeground(fColor);
+                       gc.drawRectangle(left.x, left.y, right.x - left.x - 1, gc
+                                       .getFontMetrics().getHeight() - 1);
+
+               } else {
+                       fTextWidget.redrawRange(offset, length, true);
+               }
+       }
+
+       /*
+        * @see IPainter#paint(int)
+        */
+       public void paint(int reason) {
+               Point selection = fSourceViewer.getSelectedRange();
+               if (selection.y > 0) {
+                       deactivate(true);
+                       return;
+               }
+
+               IRegion pair = fMatcher.match(fSourceViewer.getDocument(), selection.x);
+               if (pair == null) {
+                       deactivate(true);
+                       return;
+               }
+
+               if (fIsActive) {
+                       // only if different
+                       if (pair.getOffset() != fBracketPosition.getOffset()
+                                       || pair.getLength() != fBracketPosition.getLength()
+                                       || fMatcher.getAnchor() != fAnchor) {
+
+                               // remove old highlighting
+                               handleDrawRequest(null);
+                               // update position
+                               fBracketPosition.isDeleted = false;
+                               fBracketPosition.offset = pair.getOffset();
+                               fBracketPosition.length = pair.getLength();
+                               fAnchor = fMatcher.getAnchor();
+                               // apply new highlighting
+                               handleDrawRequest(null);
+
+                       }
+               } else {
+
+                       fIsActive = true;
+
+                       fBracketPosition.isDeleted = false;
+                       fBracketPosition.offset = pair.getOffset();
+                       fBracketPosition.length = pair.getLength();
+                       fAnchor = fMatcher.getAnchor();
+
+                       fTextWidget.addPaintListener(this);
+                       fPositionManager.addManagedPosition(fBracketPosition);
+                       handleDrawRequest(null);
+               }
+       }
+
+       /*
+        * @see IPainter#setPositionManager(IPositionManager)
+        */
+       public void setPositionManager(IPositionManager manager) {
+               fPositionManager = manager;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BreakpointImageProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/BreakpointImageProvider.java
new file mode 100644 (file)
index 0000000..b57d14d
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.texteditor.IAnnotationImageProvider;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+/**
+ * BreakpointImageProvider
+ * 
+ * @since 3.0
+ */
+public class BreakpointImageProvider implements IAnnotationImageProvider {
+
+       private IDebugModelPresentation fPresentation;
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationImageProvider#getManagedImage(org.eclipse.jface.text.source.Annotation)
+        */
+       public Image getManagedImage(Annotation annotation) {
+               if (annotation instanceof MarkerAnnotation) {
+                       MarkerAnnotation markerAnnotation = (MarkerAnnotation) annotation;
+                       IMarker marker = markerAnnotation.getMarker();
+                       if (marker != null && marker.exists())
+                               return getPresentation().getImage(marker);
+               }
+
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationImageProvider#getImageDescriptorId(org.eclipse.jface.text.source.Annotation)
+        */
+       public String getImageDescriptorId(Annotation annotation) {
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationImageProvider#getImageDescriptor(java.lang.String)
+        */
+       public ImageDescriptor getImageDescriptor(String imageDescritporId) {
+               return null;
+       }
+
+       private IDebugModelPresentation getPresentation() {
+               if (fPresentation == null)
+                       fPresentation = DebugUITools.newDebugModelPresentation();
+               return fPresentation;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitAnnotationModelEvent.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitAnnotationModelEvent.java
new file mode 100644 (file)
index 0000000..fa55f33
--- /dev/null
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+/**
+ * Event sent out by changes of the compilation unit annotation model.
+ */
+public class CompilationUnitAnnotationModelEvent extends AnnotationModelEvent {
+
+       private boolean fIncludesProblemMarkerAnnotations;
+
+       private IResource fUnderlyingResource;
+
+       /**
+        * Constructor for CompilationUnitAnnotationModelEvent.
+        * 
+        * @param model
+        * @param underlyingResource
+        *            The annotation model's underlying resource
+        */
+       public CompilationUnitAnnotationModelEvent(IAnnotationModel model,
+                       IResource underlyingResource) {
+               super(model);
+               fUnderlyingResource = underlyingResource;
+               fIncludesProblemMarkerAnnotations = false;
+       }
+
+       private void testIfProblemMarker(Annotation annotation) {
+               if (fIncludesProblemMarkerAnnotations) {
+                       return;
+               }
+               if (annotation instanceof JavaMarkerAnnotation) {
+                       fIncludesProblemMarkerAnnotations = ((JavaMarkerAnnotation) annotation)
+                                       .isProblem();
+               } else if (annotation instanceof MarkerAnnotation) {
+                       try {
+                               IMarker marker = ((MarkerAnnotation) annotation).getMarker();
+                               if (!marker.exists() || marker.isSubtypeOf(IMarker.PROBLEM)) {
+                                       fIncludesProblemMarkerAnnotations = true;
+                               }
+                       } catch (CoreException e) {
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationAdded(org.eclipse.jface.text.source.Annotation)
+        */
+       public void annotationAdded(Annotation annotation) {
+               super.annotationAdded(annotation);
+               testIfProblemMarker(annotation);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationRemoved(org.eclipse.jface.text.source.Annotation)
+        */
+       public void annotationRemoved(Annotation annotation) {
+               super.annotationRemoved(annotation);
+               testIfProblemMarker(annotation);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationRemoved(org.eclipse.jface.text.source.Annotation,
+        *      org.eclipse.jface.text.Position)
+        */
+       public void annotationRemoved(Annotation annotation, Position position) {
+               super.annotationRemoved(annotation, position);
+               testIfProblemMarker(annotation);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationChanged(org.eclipse.jface.text.source.Annotation)
+        */
+       public void annotationChanged(Annotation annotation) {
+               testIfProblemMarker(annotation);
+               super.annotationChanged(annotation);
+       }
+
+       /**
+        * Returns whether the change included problem marker annotations.
+        * 
+        * @return <code>true</code> if the change included marker annotations
+        */
+       public boolean includesProblemMarkerAnnotationChanges() {
+               return fIncludesProblemMarkerAnnotations;
+       }
+
+       /**
+        * Returns the annotation model's underlying resource
+        */
+       public IResource getUnderlyingResource() {
+               return fUnderlyingResource;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitEditorActionContributor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitEditorActionContributor.java
new file mode 100644 (file)
index 0000000..b77af3e
--- /dev/null
@@ -0,0 +1,76 @@
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ **********************************************************************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.ui.actions.PHPdtActionConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.editor.ShowExternalPreviewAction;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class CompilationUnitEditorActionContributor extends
+               BasicEditorActionContributor {
+       public CompilationUnitEditorActionContributor() {
+               super();
+       }
+
+       /*
+        * @see IEditorActionBarContributor#setActiveEditor(IEditorPart)
+        */
+       public void setActiveEditor(IEditorPart part) {
+               super.setActiveEditor(part);
+
+               ITextEditor textEditor = null;
+               if (part instanceof ITextEditor)
+                       textEditor = (ITextEditor) part;
+
+               // Source menu.
+               IActionBars bars = getActionBars();
+               bars.setGlobalActionHandler(PHPdtActionConstants.COMMENT, getAction(
+                               textEditor, "Comment")); //$NON-NLS-1$
+               bars.setGlobalActionHandler(PHPdtActionConstants.UNCOMMENT, getAction(
+                               textEditor, "Uncomment")); //$NON-NLS-1$
+               bars.setGlobalActionHandler(PHPdtActionConstants.TOGGLE_COMMENT,
+                               getAction(textEditor, "ToggleComment")); //$NON-NLS-1$
+               bars.setGlobalActionHandler(PHPdtActionConstants.FORMAT, getAction(
+                               textEditor, "Format")); //$NON-NLS-1$
+               bars.setGlobalActionHandler(PHPdtActionConstants.ADD_BLOCK_COMMENT,
+                               getAction(textEditor, "AddBlockComment")); //$NON-NLS-1$
+               bars.setGlobalActionHandler(PHPdtActionConstants.REMOVE_BLOCK_COMMENT,
+                               getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$
+               // bars.setGlobalActionHandler(PHPdtActionConstants.INDENT, getAction(
+               // textEditor, "Indent")); //$NON-NLS-1$ //$NON-NLS-2$
+
+               if (textEditor != null) {
+                       IFile file = null;
+                       IEditorInput editorInput = textEditor.getEditorInput();
+
+                       if (editorInput instanceof IFileEditorInput) {
+                               file = ((IFileEditorInput) editorInput).getFile();
+                       }
+
+                       PHPeclipsePlugin.getDefault().setLastEditorFile(file);
+
+                       ShowExternalPreviewAction fShowExternalPreviewAction = ShowExternalPreviewAction
+                                       .getInstance();
+                       fShowExternalPreviewAction.setEditor(textEditor);
+                       fShowExternalPreviewAction.update();
+                       // if (fShowExternalPreviewAction != null) {
+                       // fShowExternalPreviewAction
+                       // .doRun(ShowExternalPreviewAction.PHP_TYPE);
+                       // }
+                       fShowExternalPreviewAction
+                                       .refresh(ShowExternalPreviewAction.PHP_TYPE);
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java
new file mode 100644 (file)
index 0000000..6c0bdff
--- /dev/null
@@ -0,0 +1,513 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import net.sourceforge.phpdt.core.BufferChangedEvent;
+import net.sourceforge.phpdt.core.IBuffer;
+import net.sourceforge.phpdt.core.IBufferChangedListener;
+import net.sourceforge.phpdt.core.IOpenable;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Adapts <code>IDocument</code> to <code>IBuffer</code>. Uses the same
+ * algorithm as the text widget to determine the buffer's line delimiter. All
+ * text inserted into the buffer is converted to this line delimiter. This class
+ * is <code>public</code> for test purposes only.
+ */
+public class DocumentAdapter implements IBuffer, IDocumentListener {
+
+       /**
+        * Internal implementation of a NULL instanceof IBuffer.
+        */
+       static private class NullBuffer implements IBuffer {
+               public void addBufferChangedListener(IBufferChangedListener listener) {
+               }
+
+               public void append(char[] text) {
+               }
+
+               public void append(String text) {
+               }
+
+               public void close() {
+               }
+
+               public char getChar(int position) {
+                       return 0;
+               }
+
+               public char[] getCharacters() {
+                       return null;
+               }
+
+               public String getContents() {
+                       return null;
+               }
+
+               public int getLength() {
+                       return 0;
+               }
+
+               public IOpenable getOwner() {
+                       return null;
+               }
+
+               public String getText(int offset, int length) {
+                       return null;
+               }
+
+               public IResource getUnderlyingResource() {
+                       return null;
+               }
+
+               public boolean hasUnsavedChanges() {
+                       return false;
+               }
+
+               public boolean isClosed() {
+                       return false;
+               }
+
+               public boolean isReadOnly() {
+                       return true;
+               }
+
+               public void removeBufferChangedListener(IBufferChangedListener listener) {
+               }
+
+               public void replace(int position, int length, char[] text) {
+               }
+
+               public void replace(int position, int length, String text) {
+               }
+
+               public void save(IProgressMonitor progress, boolean force)
+                               throws JavaModelException {
+               }
+
+               public void setContents(char[] contents) {
+               }
+
+               public void setContents(String contents) {
+               }
+       }
+
+       /** NULL implementing <code>IBuffer</code> */
+       public final static IBuffer NULL = new NullBuffer();
+
+       /**
+        * Executes a document set content call in the ui thread.
+        */
+       protected class DocumentSetCommand implements Runnable {
+
+               private String fContents;
+
+               public void run() {
+                       fDocument.set(fContents);
+               }
+
+               public void set(String contents) {
+                       fContents = contents;
+                       Display.getDefault().syncExec(this);
+               }
+       }
+
+       /**
+        * Executes a document replace call in the ui thread.
+        */
+       protected class DocumentReplaceCommand implements Runnable {
+
+               private int fOffset;
+
+               private int fLength;
+
+               private String fText;
+
+               public void run() {
+                       try {
+                               fDocument.replace(fOffset, fLength, fText);
+                       } catch (BadLocationException x) {
+                               // ignore
+                       }
+               }
+
+               public void replace(int offset, int length, String text) {
+                       fOffset = offset;
+                       fLength = length;
+                       fText = text;
+                       Display.getDefault().syncExec(this);
+               }
+       }
+
+       private static final boolean DEBUG_LINE_DELIMITERS = true;
+
+       private IOpenable fOwner;
+
+       private IFile fFile;
+
+       private ITextFileBuffer fTextFileBuffer;
+
+       private IDocument fDocument;
+
+       private DocumentSetCommand fSetCmd = new DocumentSetCommand();
+
+       private DocumentReplaceCommand fReplaceCmd = new DocumentReplaceCommand();
+
+       private Set fLegalLineDelimiters;
+
+       private List fBufferListeners = new ArrayList(3);
+
+       private IStatus fStatus;
+
+       /**
+        * This method is <code>public</code> for test purposes only.
+        */
+       public DocumentAdapter(IOpenable owner, IFile file) {
+
+               fOwner = owner;
+               fFile = file;
+
+               initialize();
+       }
+
+       private void initialize() {
+               ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
+               IPath location = fFile.getFullPath();
+               try {
+                       manager.connect(location, new NullProgressMonitor());
+                       fTextFileBuffer = manager.getTextFileBuffer(location);
+                       fDocument = fTextFileBuffer.getDocument();
+               } catch (CoreException x) {
+                       fStatus = x.getStatus();
+                       fDocument = manager.createEmptyDocument(location);
+               }
+               fDocument.addPrenotifiedDocumentListener(this);
+       }
+
+       /**
+        * Returns the status of this document adapter.
+        */
+       public IStatus getStatus() {
+               if (fStatus != null)
+                       return fStatus;
+               if (fTextFileBuffer != null)
+                       return fTextFileBuffer.getStatus();
+               return null;
+       }
+
+       /**
+        * Returns the adapted document.
+        * 
+        * @return the adapted document
+        */
+       public IDocument getDocument() {
+               return fDocument;
+       }
+
+       /*
+        * @see IBuffer#addBufferChangedListener(IBufferChangedListener)
+        */
+       public void addBufferChangedListener(IBufferChangedListener listener) {
+               Assert.isNotNull(listener);
+               if (!fBufferListeners.contains(listener))
+                       fBufferListeners.add(listener);
+       }
+
+       /*
+        * @see IBuffer#removeBufferChangedListener(IBufferChangedListener)
+        */
+       public void removeBufferChangedListener(IBufferChangedListener listener) {
+               Assert.isNotNull(listener);
+               fBufferListeners.remove(listener);
+       }
+
+       /*
+        * @see IBuffer#append(char[])
+        */
+       public void append(char[] text) {
+               append(new String(text));
+       }
+
+       /*
+        * @see IBuffer#append(String)
+        */
+       public void append(String text) {
+               if (DEBUG_LINE_DELIMITERS) {
+                       validateLineDelimiters(text);
+               }
+               fReplaceCmd.replace(fDocument.getLength(), 0, text);
+       }
+
+       /*
+        * @see IBuffer#close()
+        */
+       public void close() {
+
+               if (isClosed())
+                       return;
+
+               IDocument d = fDocument;
+               fDocument = null;
+               d.removePrenotifiedDocumentListener(this);
+
+               if (fTextFileBuffer != null) {
+                       ITextFileBufferManager manager = FileBuffers
+                                       .getTextFileBufferManager();
+                       try {
+                               manager.disconnect(fTextFileBuffer.getLocation(),
+                                               new NullProgressMonitor());
+                       } catch (CoreException x) {
+                               // ignore
+                       }
+                       fTextFileBuffer = null;
+               }
+
+               fireBufferChanged(new BufferChangedEvent(this, 0, 0, null));
+               fBufferListeners.clear();
+       }
+
+       /*
+        * @see IBuffer#getChar(int)
+        */
+       public char getChar(int position) {
+               try {
+                       return fDocument.getChar(position);
+               } catch (BadLocationException x) {
+                       throw new ArrayIndexOutOfBoundsException();
+               }
+       }
+
+       /*
+        * @see IBuffer#getCharacters()
+        */
+       public char[] getCharacters() {
+               String content = getContents();
+               return content == null ? null : content.toCharArray();
+       }
+
+       /*
+        * @see IBuffer#getContents()
+        */
+       public String getContents() {
+               return fDocument.get();
+       }
+
+       /*
+        * @see IBuffer#getLength()
+        */
+       public int getLength() {
+               return fDocument.getLength();
+       }
+
+       /*
+        * @see IBuffer#getOwner()
+        */
+       public IOpenable getOwner() {
+               return fOwner;
+       }
+
+       /*
+        * @see IBuffer#getText(int, int)
+        */
+       public String getText(int offset, int length) {
+               try {
+                       return fDocument.get(offset, length);
+               } catch (BadLocationException x) {
+                       throw new ArrayIndexOutOfBoundsException();
+               }
+       }
+
+       /*
+        * @see IBuffer#getUnderlyingResource()
+        */
+       public IResource getUnderlyingResource() {
+               return fFile;
+       }
+
+       /*
+        * @see IBuffer#hasUnsavedChanges()
+        */
+       public boolean hasUnsavedChanges() {
+               return fTextFileBuffer != null ? fTextFileBuffer.isDirty() : false;
+       }
+
+       /*
+        * @see IBuffer#isClosed()
+        */
+       public boolean isClosed() {
+               return fDocument == null;
+       }
+
+       /*
+        * @see IBuffer#isReadOnly()
+        */
+       public boolean isReadOnly() {
+               IResource resource = getUnderlyingResource();
+               return resource == null ? true : resource.getResourceAttributes()
+                               .isReadOnly();
+       }
+
+       /*
+        * @see IBuffer#replace(int, int, char[])
+        */
+       public void replace(int position, int length, char[] text) {
+               replace(position, length, new String(text));
+       }
+
+       /*
+        * @see IBuffer#replace(int, int, String)
+        */
+       public void replace(int position, int length, String text) {
+               if (DEBUG_LINE_DELIMITERS) {
+                       validateLineDelimiters(text);
+               }
+               fReplaceCmd.replace(position, length, text);
+       }
+
+       /*
+        * @see IBuffer#save(IProgressMonitor, boolean)
+        */
+       public void save(IProgressMonitor progress, boolean force)
+                       throws JavaModelException {
+               try {
+                       if (fTextFileBuffer != null)
+                               fTextFileBuffer.commit(progress, force);
+               } catch (CoreException e) {
+                       throw new JavaModelException(e);
+               }
+       }
+
+       /*
+        * @see IBuffer#setContents(char[])
+        */
+       public void setContents(char[] contents) {
+               setContents(new String(contents));
+       }
+
+       /*
+        * @see IBuffer#setContents(String)
+        */
+       public void setContents(String contents) {
+               int oldLength = fDocument.getLength();
+
+               if (contents == null) {
+
+                       if (oldLength != 0)
+                               fSetCmd.set(""); //$NON-NLS-1$
+
+               } else {
+
+                       // set only if different
+                       if (DEBUG_LINE_DELIMITERS) {
+                               validateLineDelimiters(contents);
+                       }
+
+                       if (!contents.equals(fDocument.get()))
+                               fSetCmd.set(contents);
+               }
+       }
+
+       private void validateLineDelimiters(String contents) {
+
+               if (fLegalLineDelimiters == null) {
+                       // collect all line delimiters in the document
+                       HashSet existingDelimiters = new HashSet();
+
+                       for (int i = fDocument.getNumberOfLines() - 1; i >= 0; i--) {
+                               try {
+                                       String curr = fDocument.getLineDelimiter(i);
+                                       if (curr != null) {
+                                               existingDelimiters.add(curr);
+                                       }
+                               } catch (BadLocationException e) {
+                                       PHPeclipsePlugin.log(e);
+                               }
+                       }
+                       if (existingDelimiters.isEmpty()) {
+                               return; // first insertion of a line delimiter: no test
+                       }
+                       fLegalLineDelimiters = existingDelimiters;
+
+               }
+
+               DefaultLineTracker tracker = new DefaultLineTracker();
+               tracker.set(contents);
+
+               int lines = tracker.getNumberOfLines();
+               if (lines <= 1)
+                       return;
+
+               for (int i = 0; i < lines; i++) {
+                       try {
+                               String curr = tracker.getLineDelimiter(i);
+                               if (curr != null && !fLegalLineDelimiters.contains(curr)) {
+                                       StringBuffer buf = new StringBuffer(
+                                                       "New line delimiter added to new code: "); //$NON-NLS-1$
+                                       for (int k = 0; k < curr.length(); k++) {
+                                               buf.append(String.valueOf((int) curr.charAt(k)));
+                                       }
+                                       PHPeclipsePlugin.log(new Exception(buf.toString()));
+                               }
+                       } catch (BadLocationException e) {
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+       }
+
+       /*
+        * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+        */
+       public void documentAboutToBeChanged(DocumentEvent event) {
+               // there is nothing to do here
+       }
+
+       /*
+        * @see IDocumentListener#documentChanged(DocumentEvent)
+        */
+       public void documentChanged(DocumentEvent event) {
+               fireBufferChanged(new BufferChangedEvent(this, event.getOffset(), event
+                               .getLength(), event.getText()));
+       }
+
+       private void fireBufferChanged(BufferChangedEvent event) {
+               if (fBufferListeners != null && fBufferListeners.size() > 0) {
+                       Iterator e = new ArrayList(fBufferListeners).iterator();
+                       while (e.hasNext())
+                               ((IBufferChangedListener) e.next()).bufferChanged(event);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/EditorHighlightingSynchronizer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/EditorHighlightingSynchronizer.java
new file mode 100644 (file)
index 0000000..4125a28
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.link.ILinkedModeListener;
+import org.eclipse.jface.text.link.LinkedModeModel;
+
+/**
+ * Turns off occurrences highlighting on a java editor until linked mode is
+ * left.
+ * 
+ * @since 3.0
+ */
+public class EditorHighlightingSynchronizer implements ILinkedModeListener {
+
+       private final PHPEditor fEditor;
+
+       // private final boolean fWasOccurrencesOn;
+
+       /**
+        * Creates a new synchronizer.
+        * 
+        * @param editor
+        *            the java editor the occurrences markers of which will be
+        *            synchonized with the linked mode
+        * 
+        */
+       public EditorHighlightingSynchronizer(PHPEditor editor) {
+               Assert.isLegal(editor != null);
+               fEditor = editor;
+               // fWasOccurrencesOn= fEditor.isMarkingOccurrences();
+               //              
+               // if (fWasOccurrencesOn)
+               // fEditor.uninstallOccurrencesFinder();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.link.ILinkedModeListener#left(org.eclipse.jface.text.link.LinkedModeModel,
+        *      int)
+        */
+       public void left(LinkedModeModel environment, int flags) {
+               // if (fWasOccurrencesOn)
+               // fEditor.installOccurrencesFinder();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.link.ILinkedModeListener#suspend(org.eclipse.jface.text.link.LinkedModeModel)
+        */
+       public void suspend(LinkedModeModel environment) {
+       }
+
+       /*
+        * @see org.eclipse.jface.text.link.ILinkedModeListener#resume(org.eclipse.jface.text.link.LinkedModeModel,
+        *      int)
+        */
+       public void resume(LinkedModeModel environment, int flags) {
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java
new file mode 100644 (file)
index 0000000..5952b81
--- /dev/null
@@ -0,0 +1,437 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.IWorkingCopy;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+import net.sourceforge.phpdt.ui.JavaUI;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * A number of routines for working with JavaElements in editors
+ * 
+ * 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) {
+                       try {
+                               return editor.getEditorInput().equals(getEditorInput(element));
+                       } catch (JavaModelException x) {
+                               PHPeclipsePlugin.log(x.getStatus());
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Tests if a cu 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;
+
+               try {
+                       input = getEditorInput(inputElement);
+               } catch (JavaModelException x) {
+                       PHPeclipsePlugin.log(x.getStatus());
+               }
+
+               if (input != null) {
+                       IWorkbenchPage p = WebUI.getActivePage();
+                       if (p != null) {
+                               return p.findEditor(input);
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Opens a Java editor for an element such as <code>IJavaElement</code>,
+        * <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 JavaModelException, PartInitException {
+               return openInEditor(inputElement, true);
+       }
+
+       /**
+        * Opens a Java editor for an element (IJavaElement, IFile, IStorage...)
+        * 
+        * @return the IEditorPart or null if wrong element type or opening failed
+        */
+       public static IEditorPart openInEditor(Object inputElement, boolean activate)
+                       throws JavaModelException, PartInitException {
+
+               if (inputElement instanceof IFile)
+                       return openInEditor((IFile) inputElement, activate);
+
+               IEditorInput input = getEditorInput(inputElement);
+               if (input instanceof IFileEditorInput) {
+                       IFileEditorInput fileInput = (IFileEditorInput) input;
+                       return openInEditor(fileInput.getFile(), activate);
+               }
+
+               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, IJavaElement element) {
+               if (element != null && part instanceof PHPEditor) {
+                       ((PHPEditor) part).setSelection(element);
+               }
+       }
+
+       private static IEditorPart openInEditor(IFile file, boolean activate)
+                       throws PartInitException {
+               if (file != null) {
+                       IWorkbenchPage p = WebUI.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 = WebUI.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) {
+                       TogglePresentationAction toggleAction = new TogglePresentationAction();
+                       // Initialize editor
+                       toggleAction.setEditor((ITextEditor) editorPart);
+                       // Reset action
+                       toggleAction.setEditor(null);
+               }
+       }
+
+       /**
+        * @deprecated Made it public again for java debugger UI.
+        */
+       public static String getEditorID(IEditorInput input, Object inputObject) {
+               IEditorRegistry registry = PlatformUI.getWorkbench()
+                               .getEditorRegistry();
+               IEditorDescriptor descriptor = registry.getDefaultEditor(input
+                               .getName());
+               if (descriptor != null)
+                       return descriptor.getId();
+               return null;
+       }
+
+       private static IEditorInput getEditorInput(IJavaElement element)
+                       throws JavaModelException {
+               while (element != null) {
+                       if (element instanceof IWorkingCopy
+                                       && ((IWorkingCopy) element).isWorkingCopy())
+                               element = ((IWorkingCopy) element).getOriginalElement();
+
+                       if (element instanceof ICompilationUnit) {
+                               ICompilationUnit unit = (ICompilationUnit) element;
+                               IResource resource = unit.getResource();
+                               if (resource instanceof IFile)
+                                       return new FileEditorInput((IFile) resource);
+                       }
+
+                       // if (element instanceof IClassFile)
+                       // return new InternalClassFileEditorInput((IClassFile) element);
+                       //                      
+                       element = element.getParent();
+               }
+
+               return null;
+       }
+
+       public static IEditorInput getEditorInput(Object input)
+                       throws JavaModelException {
+
+               if (input instanceof IJavaElement)
+                       return getEditorInput((IJavaElement) input);
+
+               if (input instanceof IFile)
+                       return new FileEditorInput((IFile) input);
+
+               // if (input instanceof IStorage)
+               // return new JarEntryEditorInput((IStorage)input);
+
+               return null;
+       }
+
+       /**
+        * If the current active editor edits a java element return it, else return
+        * null
+        */
+       public static IJavaElement getActiveEditorJavaInput() {
+               IWorkbenchPage page = WebUI.getActivePage();
+               if (page != null) {
+                       IEditorPart part = page.getActiveEditor();
+                       if (part != null) {
+                               IEditorInput editorInput = part.getEditorInput();
+                               if (editorInput != null) {
+                                       return (IJavaElement) editorInput
+                                                       .getAdapter(IJavaElement.class);
+                               }
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Gets the working copy of an compilation unit opened in an editor
+        * 
+        * @param part
+        *            the editor part
+        * @param cu
+        *            the original compilation unit (or another working copy)
+        * @return the working copy of the compilation unit, or null if not found
+        */
+       public static ICompilationUnit getWorkingCopy(ICompilationUnit cu) {
+               if (cu == null)
+                       return null;
+               if (cu.isWorkingCopy())
+                       return cu;
+
+               return (ICompilationUnit) cu.findSharedWorkingCopy(JavaUI
+                               .getBufferFactory());
+       }
+
+       /**
+        * Gets the working copy of an member opened in an editor
+        * 
+        * @param member
+        *            the original member or a member in a working copy
+        * @return the corresponding member in the shared working copy or
+        *         <code>null</code> if not found
+        */
+       public static IMember getWorkingCopy(IMember member)
+                       throws JavaModelException {
+               ICompilationUnit cu = member.getCompilationUnit();
+               if (cu != null) {
+                       ICompilationUnit workingCopy = getWorkingCopy(cu);
+                       if (workingCopy != null) {
+                               return JavaModelUtil.findMemberInCompilationUnit(workingCopy,
+                                               member);
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Returns the compilation unit for the given java element.
+        * 
+        * @param element
+        *            the java element whose compilation unit is searched for
+        * @return the compilation unit of the given java element
+        */
+       private static ICompilationUnit getCompilationUnit(IJavaElement element) {
+
+               if (element == null)
+                       return null;
+
+               if (element instanceof IMember)
+                       return ((IMember) element).getCompilationUnit();
+
+               int type = element.getElementType();
+               if (IJavaElement.COMPILATION_UNIT == type)
+                       return (ICompilationUnit) element;
+               if (IJavaElement.CLASS_FILE == type)
+                       return null;
+
+               return getCompilationUnit(element.getParent());
+       }
+
+       /**
+        * Returns the working copy of the given java element.
+        * 
+        * @param javaElement
+        *            the javaElement for which the working copyshould be found
+        * @param reconcile
+        *            indicates whether the working copy must be reconcile prior to
+        *            searching it
+        * @return the working copy of the given element or <code>null</code> if
+        *         none
+        */
+       public static IJavaElement getWorkingCopy(IJavaElement element,
+                       boolean reconcile) throws JavaModelException {
+               ICompilationUnit unit = getCompilationUnit(element);
+               if (unit == null)
+                       return null;
+
+               if (unit.isWorkingCopy())
+                       return element;
+
+               ICompilationUnit workingCopy = getWorkingCopy(unit);
+               if (workingCopy != null) {
+                       if (reconcile) {
+                               synchronized (workingCopy) {
+                                       workingCopy.reconcile();
+                                       return JavaModelUtil.findInCompilationUnit(workingCopy,
+                                                       element);
+                               }
+                       } else {
+                               return JavaModelUtil
+                                               .findInCompilationUnit(workingCopy, element);
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Maps the localized modifier name to a code in the same manner as
+        * #findModifier.
+        * 
+        * @return the SWT modifier bit, or <code>0</code> if no match was found
+        * @see findModifier
+        * @since 2.1.1
+        */
+       public static int findLocalizedModifier(String token) {
+               if (token == null)
+                       return 0;
+
+               if (token.equalsIgnoreCase(Action.findModifierString(SWT.CTRL)))
+                       return SWT.CTRL;
+               if (token.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT)))
+                       return SWT.SHIFT;
+               if (token.equalsIgnoreCase(Action.findModifierString(SWT.ALT)))
+                       return SWT.ALT;
+               if (token.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 PHPEditorMessages
+                               .getFormattedString(
+                                               "EditorUtility.concatModifierStrings", new String[] { modifierString, newModifierString }); //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the Java project for a given editor input or <code>null</code>
+        * if no corresponding Java project exists.
+        * 
+        * @param input
+        *            the editor input
+        * @return the corresponding Java project
+        * 
+        * @since 3.0
+        */
+       public static IJavaProject getJavaProject(IEditorInput input) {
+               IJavaProject jProject = null;
+               if (input instanceof IFileEditorInput) {
+                       IProject project = ((IFileEditorInput) input).getFile()
+                                       .getProject();
+                       if (project != null) {
+                               jProject = JavaCore.create(project);
+                               if (!jProject.exists())
+                                       jProject = null;
+                       }
+               }
+               // else if (input instanceof IClassFileEditorInput) {
+               // jProject=
+               // ((IClassFileEditorInput)input).getClassFile().getJavaProject();
+               // }
+               return jProject;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/GotoAnnotationAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/GotoAnnotationAction.java
new file mode 100644 (file)
index 0000000..781cff9
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+public class GotoAnnotationAction extends TextEditorAction {
+
+       private boolean fForward;
+
+       public GotoAnnotationAction(String prefix, boolean forward) {
+               super(PHPEditorMessages.getResourceBundle(), prefix, null);
+               fForward = forward;
+               if (forward)
+                       PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                                       IJavaHelpContextIds.GOTO_NEXT_ERROR_ACTION);
+               else
+                       PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                                       IJavaHelpContextIds.GOTO_PREVIOUS_ERROR_ACTION);
+       }
+
+       public void run() {
+               PHPEditor e = (PHPEditor) getTextEditor();
+               e.gotoAnnotation(fForward);
+       }
+
+       public void setEditor(ITextEditor editor) {
+               if (editor instanceof PHPEditor)
+                       super.setEditor(editor);
+               update();
+       }
+
+       public void update() {
+               setEnabled(getTextEditor() instanceof PHPEditor);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/GotoErrorAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/GotoErrorAction.java
new file mode 100644 (file)
index 0000000..8a835e2
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+public class GotoErrorAction extends TextEditorAction {
+
+       private boolean fForward;
+
+       public GotoErrorAction(String prefix, boolean forward) {
+               super(PHPEditorMessages.getResourceBundle(), prefix, null);
+               fForward = forward;
+               if (forward)
+                       PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                                       IJavaHelpContextIds.GOTO_NEXT_ERROR_ACTION);
+               else
+                       PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                                       IJavaHelpContextIds.GOTO_PREVIOUS_ERROR_ACTION);
+       }
+
+       public void run() {
+               PHPEditor e = (PHPEditor) getTextEditor();
+               e.gotoError(fForward);
+       }
+
+       public void setEditor(ITextEditor editor) {
+               if (editor instanceof PHPEditor)
+                       super.setEditor(editor);
+               update();
+       }
+
+       public void update() {
+               setEnabled(getTextEditor() instanceof PHPEditor);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/HTMLDocumentSetupParticipant.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/HTMLDocumentSetupParticipant.java
new file mode 100644 (file)
index 0000000..9946258
--- /dev/null
@@ -0,0 +1,38 @@
+/**********************************************************************
+ Copyright (c) 2000, 2003 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * The document setup participant for PHPDT.
+ */
+public class HTMLDocumentSetupParticipant implements IDocumentSetupParticipant {
+
+       public HTMLDocumentSetupParticipant() {
+       }
+
+       /*
+        * @see org.eclipse.core.filebuffers.IDocumentSetupParticipant#setup(org.eclipse.jface.text.IDocument)
+        */
+       public void setup(IDocument document) {
+               JavaTextTools tools = WebUI.getDefault().getJavaTextTools();
+               tools.setupHTMLDocumentPartitioner(document,
+                               IPHPPartitions.PHP_PARTITIONING, null); // IPHPPartitions.PHP_PARTITIONING,
+                                                                                                               // null);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ICompilationUnitDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ICompilationUnitDocumentProvider.java
new file mode 100644 (file)
index 0000000..115130c
--- /dev/null
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.source.IAnnotationModelListener;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.IDocumentProviderExtension2;
+import org.eclipse.ui.texteditor.IDocumentProviderExtension3;
+
+/**
+ * @since 3.0
+ */
+public interface ICompilationUnitDocumentProvider extends IDocumentProvider,
+               IDocumentProviderExtension2, IDocumentProviderExtension3 {
+
+       /**
+        * Shuts down this provider.
+        */
+       void shutdown();
+
+       /**
+        * Returns the working copy for the given element.
+        * 
+        * @param element
+        *            the element
+        * @return the working copy for the given element
+        */
+       ICompilationUnit getWorkingCopy(Object element);
+
+       /**
+        * Saves the content of the given document to the given element. This method
+        * has only an effect if it is called when directly or indirectly inside
+        * <code>saveDocument</code>.
+        * 
+        * @param monitor
+        *            the progress monitor
+        * @param element
+        *            the element to which to save
+        * @param document
+        *            the document to save
+        * @param overwrite
+        *            <code>true</code> if the save should be enforced
+        */
+       void saveDocumentContent(IProgressMonitor monitor, Object element,
+                       IDocument document, boolean overwrite) throws CoreException;
+
+       /**
+        * Creates a line tracker for the given element. It is of the same kind as
+        * the one that would be used for a newly created document for the given
+        * element.
+        * 
+        * @param element
+        *            the element
+        * @return a line tracker for the given element
+        */
+       ILineTracker createLineTracker(Object element);
+
+       /**
+        * Sets the document provider's save policy.
+        * 
+        * @param savePolicy
+        *            the save policy
+        */
+       void setSavePolicy(ISavePolicy savePolicy);
+
+       /**
+        * Adds a listener that reports changes from all compilation unit annotation
+        * models.
+        * 
+        * @param listener
+        *            the listener
+        */
+       void addGlobalAnnotationModelListener(IAnnotationModelListener listener);
+
+       /**
+        * Removes the listener.
+        * 
+        * @param listener
+        *            the listener
+        */
+       void removeGlobalAnnotationModelListener(IAnnotationModelListener listener);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IJavaAnnotation.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IJavaAnnotation.java
new file mode 100644 (file)
index 0000000..2e109ad
--- /dev/null
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Interface of annotations representing markers and problems.
+ * 
+ * @see org.eclipse.core.resources.IMarker
+ * @see net.sourceforge.phpdt.core.compiler.IProblem
+ */
+public interface IJavaAnnotation {
+
+       /**
+        * @see org.eclipse.jface.text.source.Annotation#getType()
+        */
+       String getType();
+
+       /**
+        * @see org.eclipse.jface.text.source.Annotation#isPersistent()
+        */
+       boolean isPersistent();
+
+       /**
+        * @see org.eclipse.jface.text.source.Annotation#isMarkedDeleted()
+        */
+       boolean isMarkedDeleted();
+
+       /**
+        * @see org.eclipse.jface.text.source.Annotation#getText()
+        */
+       String getText();
+
+       /**
+        * Returns whether this annotation is overlaid.
+        * 
+        * @return <code>true</code> if overlaid
+        */
+       boolean hasOverlay();
+
+       /**
+        * Returns the overlay of this annotation.
+        * 
+        * @return the annotation's overlay
+        * @since 3.0
+        */
+       IJavaAnnotation getOverlay();
+
+       /**
+        * Returns an iterator for iterating over the annotation which are overlaid
+        * by this annotation.
+        * 
+        * @return an iterator over the overlaid annotaions
+        */
+       Iterator getOverlaidIterator();
+
+       /**
+        * Adds the given annotation to the list of annotations which are overlaid
+        * by this annotations.
+        * 
+        * @param annotation
+        *            the problem annoation
+        */
+       void addOverlaid(IJavaAnnotation annotation);
+
+       /**
+        * Removes the given annotation from the list of annotations which are
+        * overlaid by this annotation.
+        * 
+        * @param annotation
+        *            the problem annoation
+        */
+       void removeOverlaid(IJavaAnnotation annotation);
+
+       /**
+        * Tells whether this annotation is a problem annotation.
+        * 
+        * @return <code>true</code> if it is a problem annotation
+        */
+       boolean isProblem();
+
+       /**
+        * Returns the compilation unit corresponding to the document on which the
+        * annotation is set or <code>null</code> if no corresponding
+        * co0mpilationunit exists.
+        */
+       ICompilationUnit getCompilationUnit();
+
+       String[] getArguments();
+
+       int getId();
+
+       Image getImage(Display display);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IJavaEditorActionConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IJavaEditorActionConstants.java
new file mode 100644 (file)
index 0000000..fd91df3
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+/**
+ * Defines action IDs for private JavaEditor actions.
+ */
+public interface IJavaEditorActionConstants {
+
+       /**
+        * ID of the action to toggle the style of the presentation.
+        */
+       public static final String TOGGLE_PRESENTATION = "togglePresentation"; //$NON-NLS-1$
+
+       /**
+        * ID of the toolbar action to go to the previous error.
+        */
+       public static final String PREVIOUS_ERROR = "gotoPreviousError"; //$NON-NLS-1$
+
+       /**
+        * ID of the toolbar action to go to the next error.
+        */
+       public static final String NEXT_ERROR = "gotoNextError"; //$NON-NLS-1$
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IPainter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IPainter.java
new file mode 100644 (file)
index 0000000..80d2594
--- /dev/null
@@ -0,0 +1,42 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public interface IPainter {
+
+       /** Paint reasons */
+       int SELECTION = 0;
+
+       int TEXT_CHANGE = 1;
+
+       int KEY_STROKE = 2;
+
+       int MOUSE_BUTTON = 4;
+
+       int INTERNAL = 8;
+
+       int CONFIGURATION = 16;
+
+       /**
+        * Disposes this painter.
+        * <p>
+        * XXX: The relationship with deactivate is not yet defined.
+        * </p>
+        */
+       void dispose();
+
+       void paint(int reason);
+
+       /**
+        * Deactivates the painter.
+        * <p>
+        * XXX: The relationship with dispose is not yet defined.
+        * </p>
+        */
+       void deactivate(boolean redraw);
+
+       void setPositionManager(IPositionManager manager);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IPositionManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IPositionManager.java
new file mode 100644 (file)
index 0000000..8b4965c
--- /dev/null
@@ -0,0 +1,15 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import org.eclipse.jface.text.Position;
+
+public interface IPositionManager {
+
+       void addManagedPosition(Position position);
+
+       void removeManagedPosition(Position position);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IProblemAnnotation.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/IProblemAnnotation.java
new file mode 100644 (file)
index 0000000..bd6a3ee
--- /dev/null
@@ -0,0 +1,59 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.Iterator;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Interface of annotations representing problems.
+ */
+public interface IProblemAnnotation {
+
+       AnnotationType getAnnotationType();
+
+       boolean isTemporary();
+
+       String getMessage();
+
+       String[] getArguments();
+
+       int getId();
+
+       Image getImage(Display display);
+
+       boolean isRelevant();
+
+       boolean hasOverlay();
+
+       Iterator getOverlaidIterator();
+
+       void addOverlaid(IProblemAnnotation annotation);
+
+       void removeOverlaid(IProblemAnnotation annotation);
+
+       /**
+        * @deprecated
+        */
+       boolean isProblem();
+
+       /**
+        * @deprecated
+        */
+       boolean isTask();
+
+       /**
+        * @deprecated
+        */
+       boolean isWarning();
+
+       /**
+        * @deprecated
+        */
+       boolean isError();
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ISavePolicy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ISavePolicy.java
new file mode 100644 (file)
index 0000000..4b26a0c
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+
+public interface ISavePolicy {
+
+       /**
+        * 
+        */
+       void preSave(ICompilationUnit unit);
+
+       /**
+        * Returns the compilation unit in which the argument has been changed. If
+        * the argument is not changed, the returned result is <code>null</code>.
+        */
+       ICompilationUnit postSave(ICompilationUnit unit);
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationImageProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationImageProvider.java
new file mode 100644 (file)
index 0000000..ae92cf6
--- /dev/null
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IAnnotationImageProvider;
+
+/**
+ * Image provider for annotations based on Java problem markers.
+ * 
+ * @since 3.0
+ */
+public class JavaAnnotationImageProvider implements IAnnotationImageProvider {
+
+       private final static int NO_IMAGE = 0;
+
+       private final static int GRAY_IMAGE = 1;
+
+       private final static int OVERLAY_IMAGE = 2;
+
+       private final static int QUICKFIX_IMAGE = 3;
+
+       private final static int QUICKFIX_ERROR_IMAGE = 4;
+
+       private static Image fgQuickFixImage;
+
+       private static Image fgQuickFixErrorImage;
+
+       private static ImageRegistry fgImageRegistry;
+
+       private boolean fShowQuickFixIcon;
+
+       private int fCachedImageType;
+
+       private Image fCachedImage;
+
+       public JavaAnnotationImageProvider() {
+               fShowQuickFixIcon = PreferenceConstants.getPreferenceStore()
+                               .getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationImageProvider#getManagedImage(org.eclipse.jface.text.source.Annotation)
+        */
+       public Image getManagedImage(Annotation annotation) {
+               if (annotation instanceof IJavaAnnotation) {
+                       IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
+                       int imageType = getImageType(javaAnnotation);
+                       return getImage(javaAnnotation, imageType, Display.getCurrent());
+               }
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationImageProvider#getImageDescriptorId(org.eclipse.jface.text.source.Annotation)
+        */
+       public String getImageDescriptorId(Annotation annotation) {
+               // unmanaged images are not supported
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationImageProvider#getImageDescriptor(java.lang.String)
+        */
+       public ImageDescriptor getImageDescriptor(String symbolicName) {
+               // unmanaged images are not supported
+               return null;
+       }
+
+       private boolean showQuickFix(IJavaAnnotation annotation) {
+               // return fShowQuickFixIcon && annotation.isProblem() &&
+               // JavaCorrectionProcessor.hasCorrections(annotation);
+               return false;
+       }
+
+       private Image getQuickFixImage() {
+               if (fgQuickFixImage == null)
+                       fgQuickFixImage = PHPUiImages
+                                       .get(PHPUiImages.IMG_OBJS_FIXABLE_PROBLEM);
+               return fgQuickFixImage;
+       }
+
+       private Image getQuickFixErrorImage() {
+               if (fgQuickFixErrorImage == null)
+                       fgQuickFixErrorImage = PHPUiImages
+                                       .get(PHPUiImages.IMG_OBJS_FIXABLE_ERROR);
+               return fgQuickFixErrorImage;
+       }
+
+       private ImageRegistry getImageRegistry(Display display) {
+               if (fgImageRegistry == null)
+                       fgImageRegistry = new ImageRegistry(display);
+               return fgImageRegistry;
+       }
+
+       private int getImageType(IJavaAnnotation annotation) {
+               int imageType = NO_IMAGE;
+               if (annotation.hasOverlay())
+                       imageType = OVERLAY_IMAGE;
+               else if (!annotation.isMarkedDeleted()) {
+                       if (showQuickFix(annotation))
+                               imageType = JavaMarkerAnnotation.ERROR_ANNOTATION_TYPE
+                                               .equals(annotation.getType()) ? QUICKFIX_ERROR_IMAGE
+                                               : QUICKFIX_IMAGE;
+               } else {
+                       imageType = GRAY_IMAGE;
+               }
+               return imageType;
+       }
+
+       private Image getImage(IJavaAnnotation annotation, int imageType,
+                       Display display) {
+               if (fCachedImageType == imageType)
+                       return fCachedImage;
+
+               Image image = null;
+               switch (imageType) {
+               case OVERLAY_IMAGE:
+                       IJavaAnnotation overlay = annotation.getOverlay();
+                       image = overlay.getImage(display);
+                       break;
+               case QUICKFIX_IMAGE:
+                       image = getQuickFixImage();
+                       break;
+               case QUICKFIX_ERROR_IMAGE:
+                       image = getQuickFixErrorImage();
+                       break;
+               case GRAY_IMAGE: {
+                       ISharedImages sharedImages = PlatformUI.getWorkbench()
+                                       .getSharedImages();
+                       String annotationType = annotation.getType();
+                       if (JavaMarkerAnnotation.ERROR_ANNOTATION_TYPE
+                                       .equals(annotationType)) {
+                               image = sharedImages.getImage(ISharedImages.IMG_OBJS_ERROR_TSK);
+                       } else if (JavaMarkerAnnotation.WARNING_ANNOTATION_TYPE
+                                       .equals(annotationType)) {
+                               image = sharedImages.getImage(ISharedImages.IMG_OBJS_WARN_TSK);
+                       } else if (JavaMarkerAnnotation.INFO_ANNOTATION_TYPE
+                                       .equals(annotationType)) {
+                               image = sharedImages.getImage(ISharedImages.IMG_OBJS_INFO_TSK);
+                       }
+                       if (image != null) {
+                               ImageRegistry registry = getImageRegistry(display);
+                               String key = Integer.toString(image.hashCode());
+                               Image grayImage = registry.get(key);
+                               if (grayImage == null) {
+                                       grayImage = new Image(display, image, SWT.IMAGE_GRAY);
+                                       registry.put(key, grayImage);
+                               }
+                               image = grayImage;
+                       }
+                       break;
+               }
+               }
+
+               fCachedImageType = imageType;
+               fCachedImage = image;
+               return fCachedImage;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationIterator.java
new file mode 100644 (file)
index 0000000..40ef7c2
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.Collections;
+import java.util.Iterator;
+
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+/**
+ * Filters problems based on their types.
+ */
+public class JavaAnnotationIterator implements Iterator {
+
+       private Iterator fIterator;
+
+       private Annotation fNext;
+
+       private boolean fSkipIrrelevants;
+
+       private boolean fReturnAllAnnotations;
+
+       /**
+        * Equivalent to
+        * <code>JavaAnnotationIterator(model, skipIrrelevants, false)</code>.
+        */
+       public JavaAnnotationIterator(IAnnotationModel model,
+                       boolean skipIrrelevants) {
+               this(model, skipIrrelevants, false);
+       }
+
+       /**
+        * Returns a new JavaAnnotationIterator.
+        * 
+        * @param model
+        *            the annotation model
+        * @param skipIrrelevants
+        *            whether to skip irrelevant annotations
+        * @param returnAllAnnotations
+        *            Whether to return non IJavaAnnotations as well
+        */
+       public JavaAnnotationIterator(IAnnotationModel model,
+                       boolean skipIrrelevants, boolean returnAllAnnotations) {
+               fReturnAllAnnotations = returnAllAnnotations;
+               if (model != null)
+                       fIterator = model.getAnnotationIterator();
+               else
+                       fIterator = Collections.EMPTY_LIST.iterator();
+               fSkipIrrelevants = skipIrrelevants;
+               skip();
+       }
+
+       private void skip() {
+               while (fIterator.hasNext()) {
+                       Annotation next = (Annotation) fIterator.next();
+                       if (next instanceof IJavaAnnotation) {
+                               if (fSkipIrrelevants) {
+                                       if (!next.isMarkedDeleted()) {
+                                               fNext = next;
+                                               return;
+                                       }
+                               } else {
+                                       fNext = next;
+                                       return;
+                               }
+                       } else if (fReturnAllAnnotations) {
+                               fNext = next;
+                               return;
+                       }
+               }
+               fNext = null;
+       }
+
+       /*
+        * @see Iterator#hasNext()
+        */
+       public boolean hasNext() {
+               return fNext != null;
+       }
+
+       /*
+        * @see Iterator#next()
+        */
+       public Object next() {
+               try {
+                       return fNext;
+               } finally {
+                       skip();
+               }
+       }
+
+       /*
+        * @see Iterator#remove()
+        */
+       public void remove() {
+               throw new UnsupportedOperationException();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentFactory.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentFactory.java
new file mode 100644 (file)
index 0000000..1166d26
--- /dev/null
@@ -0,0 +1,30 @@
+/**********************************************************************
+ Copyright (c) 2000, 2003 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import org.eclipse.core.filebuffers.IDocumentFactory;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * The document factory for JDT UI,
+ */
+public class JavaDocumentFactory implements IDocumentFactory {
+
+       public JavaDocumentFactory() {
+       }
+
+       /*
+        * @see org.eclipse.core.filebuffers.IDocumentFactory#createDocument()
+        */
+       public IDocument createDocument() {
+               return new PartiallySynchronizedDocument();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentSetupParticipant.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentSetupParticipant.java
new file mode 100644 (file)
index 0000000..c4cd4a9
--- /dev/null
@@ -0,0 +1,41 @@
+/**********************************************************************
+ Copyright (c) 2000, 2003 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * The document setup participant for PHPDT.
+ */
+public class JavaDocumentSetupParticipant implements IDocumentSetupParticipant {
+
+       public JavaDocumentSetupParticipant() {
+       }
+
+       /*
+        * @see org.eclipse.core.filebuffers.IDocumentSetupParticipant#setup(org.eclipse.jface.text.IDocument)
+        */
+       public void setup(IDocument document) {
+               JavaTextTools tools = WebUI.getDefault().getJavaTextTools();
+               tools.setupJavaDocumentPartitioner(document,
+                               IPHPPartitions.PHP_PARTITIONING);
+
+               // tools.setupJavaDocumentPartitioner(document,
+               // IPHPPartitions.PHP_PARTITIONING, null);
+               // //IPHPPartitions.PHP_PARTITIONING, null);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaEditorErrorTickUpdater.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaEditorErrorTickUpdater.java
new file mode 100644 (file)
index 0000000..e1ecf5f
--- /dev/null
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.internal.ui.viewsupport.IProblemChangedListener;
+import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementImageProvider;
+import net.sourceforge.phpdt.internal.ui.viewsupport.JavaUILabelProvider;
+import net.sourceforge.phpdt.ui.ProblemsLabelDecorator;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * The <code>JavaEditorErrorTickUpdater</code> will register as a
+ * IProblemChangedListener to listen on problem changes of the editor's input.
+ * It updates the title images when the annotation model changed.
+ */
+public class JavaEditorErrorTickUpdater implements IProblemChangedListener {
+
+       private PHPEditor fJavaEditor;
+
+       private JavaUILabelProvider fLabelProvider;
+
+       public JavaEditorErrorTickUpdater(PHPEditor editor) {
+               Assert.isNotNull(editor);
+               fJavaEditor = editor;
+               fLabelProvider = new JavaUILabelProvider(0,
+                               JavaElementImageProvider.SMALL_ICONS);
+               fLabelProvider.addLabelDecorator(new ProblemsLabelDecorator(null));
+               WebUI.getDefault().getProblemMarkerManager().addListener(
+                               this);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see IProblemChangedListener#problemsChanged(IResource[], boolean)
+        */
+       public void problemsChanged(IResource[] changedResources,
+                       boolean isMarkerChange) {
+               if (isMarkerChange) {
+                       return;
+               }
+               IEditorInput input = fJavaEditor.getEditorInput();
+               if (input != null) { // might run async, tests needed
+                       IJavaElement jelement = (IJavaElement) input
+                                       .getAdapter(IJavaElement.class);
+                       if (jelement != null) {
+                               IResource resource = jelement.getResource();
+                               for (int i = 0; i < changedResources.length; i++) {
+                                       if (changedResources[i].equals(resource)) {
+                                               updateEditorImage(jelement);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public void updateEditorImage(IJavaElement jelement) {
+               Image titleImage = fJavaEditor.getTitleImage();
+               if (titleImage == null) {
+                       return;
+               }
+               Image newImage = fLabelProvider.getImage(jelement);
+               if (titleImage != newImage) {
+                       postImageChange(newImage);
+               }
+       }
+
+       private void postImageChange(final Image newImage) {
+               Shell shell = fJavaEditor.getEditorSite().getShell();
+               if (shell != null && !shell.isDisposed()) {
+                       shell.getDisplay().syncExec(new Runnable() {
+                               public void run() {
+                                       fJavaEditor.updatedTitleImage(newImage);
+                               }
+                       });
+               }
+       }
+
+       public void dispose() {
+               fLabelProvider.dispose();
+               WebUI.getDefault().getProblemMarkerManager().removeListener(
+                               this);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaMarkerAnnotation.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaMarkerAnnotation.java
new file mode 100644 (file)
index 0000000..e72f265
--- /dev/null
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaModelMarker;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+public class JavaMarkerAnnotation extends MarkerAnnotation implements
+               IJavaAnnotation {
+
+       public static final String JAVA_MARKER_TYPE_PREFIX = "net.sourceforge.phpdt"; //$NON-NLS-1$
+
+       public static final String ERROR_ANNOTATION_TYPE = "net.sourceforge.phpdt.ui.error"; //$NON-NLS-1$
+
+       public static final String WARNING_ANNOTATION_TYPE = "net.sourceforge.phpdt.ui.warning"; //$NON-NLS-1$
+
+       public static final String INFO_ANNOTATION_TYPE = "net.sourceforge.phpdt.ui.info"; //$NON-NLS-1$
+
+       public static final String TASK_ANNOTATION_TYPE = "org.eclipse.ui.workbench.texteditor.task"; //$NON-NLS-1$
+
+       private IJavaAnnotation fOverlay;
+
+       public JavaMarkerAnnotation(IMarker marker) {
+               super(marker);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.IJavaAnnotation#getImage(org.eclipse.swt.widgets.Display)
+        */
+       public Image getImage(Display display) {
+               return super.getImage(display);
+       }
+
+       /*
+        * @see IJavaAnnotation#getArguments()
+        */
+       public String[] getArguments() {
+               IMarker marker = getMarker();
+               if (marker != null && marker.exists() && isProblem())
+                       return JavaModelUtil.getProblemArgumentsFromMarker(marker
+                                       .getAttribute(IJavaModelMarker.ARGUMENTS, "")); //$NON-NLS-1$
+               return null;
+       }
+
+       /*
+        * @see IJavaAnnotation#getId()
+        */
+       public int getId() {
+               IMarker marker = getMarker();
+               if (marker == null || !marker.exists())
+                       return -1;
+
+               if (isProblem())
+                       return marker.getAttribute(IJavaModelMarker.ID, -1);
+
+               // if (TASK_ANNOTATION_TYPE.equals(getAnnotationType())) {
+               // try {
+               // if (marker.isSubtypeOf(IJavaModelMarker.TASK_MARKER)) {
+               // return IProblem.Task;
+               // }
+               // } catch (CoreException e) {
+               // JavaPlugin.log(e); // should no happen, we test for marker.exists
+               // }
+               // }
+
+               return -1;
+       }
+
+       /*
+        * @see IJavaAnnotation#isProblem()
+        */
+       public boolean isProblem() {
+               String type = getType();
+               return WARNING_ANNOTATION_TYPE.equals(type)
+                               || ERROR_ANNOTATION_TYPE.equals(type);
+       }
+
+       /**
+        * Overlays this annotation with the given javaAnnotation.
+        * 
+        * @param javaAnnotation
+        *            annotation that is overlaid by this annotation
+        */
+       public void setOverlay(IJavaAnnotation javaAnnotation) {
+               if (fOverlay != null)
+                       fOverlay.removeOverlaid(this);
+
+               fOverlay = javaAnnotation;
+               if (!isMarkedDeleted())
+                       markDeleted(fOverlay != null);
+
+               if (fOverlay != null)
+                       fOverlay.addOverlaid(this);
+       }
+
+       /*
+        * @see IJavaAnnotation#hasOverlay()
+        */
+       public boolean hasOverlay() {
+               return fOverlay != null;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.IJavaAnnotation#getOverlay()
+        */
+       public IJavaAnnotation getOverlay() {
+               return fOverlay;
+       }
+
+       /*
+        * @see IJavaAnnotation#addOverlaid(IJavaAnnotation)
+        */
+       public void addOverlaid(IJavaAnnotation annotation) {
+               // not supported
+       }
+
+       /*
+        * @see IJavaAnnotation#removeOverlaid(IJavaAnnotation)
+        */
+       public void removeOverlaid(IJavaAnnotation annotation) {
+               // not supported
+       }
+
+       /*
+        * @see IJavaAnnotation#getOverlaidIterator()
+        */
+       public Iterator getOverlaidIterator() {
+               // not supported
+               return null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.IJavaAnnotation#getCompilationUnit()
+        */
+       public ICompilationUnit getCompilationUnit() {
+               IJavaElement element = JavaCore.create(getMarker().getResource());
+               if (element instanceof ICompilationUnit) {
+                       ICompilationUnit cu = (ICompilationUnit) element;
+                       ICompilationUnit workingCopy = EditorUtility.getWorkingCopy(cu);
+                       if (workingCopy != null) {
+                               return workingCopy;
+                       }
+                       return cu;
+               }
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java
new file mode 100644 (file)
index 0000000..9dac4f3
--- /dev/null
@@ -0,0 +1,1428 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+import net.sourceforge.phpdt.core.ElementChangedEvent;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IElementChangedListener;
+import net.sourceforge.phpdt.core.IField;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IParent;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.actions.AbstractToggleLinkingAction;
+import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
+import net.sourceforge.phpdt.internal.ui.preferences.MembersOrderPreferenceCache;
+import net.sourceforge.phpdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
+import net.sourceforge.phpdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
+import net.sourceforge.phpdt.internal.ui.viewsupport.JavaElementLabels;
+import net.sourceforge.phpdt.internal.ui.viewsupport.StatusBarUpdater;
+import net.sourceforge.phpdt.ui.JavaElementSorter;
+import net.sourceforge.phpdt.ui.JavaUI;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
+import net.sourceforge.phpdt.ui.actions.CustomFiltersActionGroup;
+import net.sourceforge.phpdt.ui.actions.GenerateActionGroup;
+import net.sourceforge.phpdt.ui.actions.MemberFilterActionGroup;
+import net.sourceforge.phpdt.ui.actions.PHPdtActionConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+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.preference.IPreferenceStore;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+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.custom.BusyIndicator;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.model.WorkbenchAdapter;
+import org.eclipse.ui.part.IPageSite;
+import org.eclipse.ui.part.IShowInSource;
+import org.eclipse.ui.part.IShowInTarget;
+import org.eclipse.ui.part.IShowInTargetList;
+import org.eclipse.ui.part.Page;
+import org.eclipse.ui.part.ShowInContext;
+import org.eclipse.ui.texteditor.GotoAnnotationAction;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.texteditor.TextEditorAction;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
+
+/**
+ * The content outline page of the Java editor. The viewer implements a
+ * proprietary update mechanism based on Java model deltas. It does not react on
+ * domain changes. It is specified to show the content of ICompilationUnits and
+ * IClassFiles. Publishes its context menu under
+ * <code>PHPeclipsePlugin.getDefault().getPluginId() + ".outline"</code>.
+ */
+public class JavaOutlinePage extends Page implements IContentOutlinePage,
+               IAdaptable, IPostSelectionProvider {
+
+       static Object[] NO_CHILDREN = new Object[0];
+
+       /**
+        * The element change listener of the java outline viewer.
+        * 
+        * @see IElementChangedListener
+        */
+       class ElementChangedListener implements IElementChangedListener {
+
+               public void elementChanged(final ElementChangedEvent e) {
+
+                       if (getControl() == null)
+                               return;
+
+                       Display d = getControl().getDisplay();
+                       if (d != null) {
+                               d.asyncExec(new Runnable() {
+                                       public void run() {
+                                               ICompilationUnit cu = (ICompilationUnit) fInput;
+                                               IJavaElement base = cu;
+                                               // if (fTopLevelTypeOnly) {
+                                               // base= getMainType(cu);
+                                               // if (base == null) {
+                                               if (fOutlineViewer != null)
+                                                       fOutlineViewer.refresh(true);
+                                               return;
+                                               // }
+                                               // }
+                                               // IJavaElementDelta delta= findElement(base,
+                                               // e.getDelta());
+                                               // if (delta != null && fOutlineViewer != null) {
+                                               // fOutlineViewer.reconcile(delta);
+                                               // }
+                                       }
+                               });
+                       }
+               }
+
+               private boolean isPossibleStructuralChange(IJavaElementDelta cuDelta) {
+                       if (cuDelta.getKind() != IJavaElementDelta.CHANGED) {
+                               return true; // add or remove
+                       }
+                       int flags = cuDelta.getFlags();
+                       if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
+                               return true;
+                       }
+                       return (flags & (IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_FINE_GRAINED)) == IJavaElementDelta.F_CONTENT;
+               }
+
+               protected IJavaElementDelta findElement(IJavaElement unit,
+                               IJavaElementDelta delta) {
+
+                       if (delta == null || unit == null)
+                               return null;
+
+                       IJavaElement element = delta.getElement();
+
+                       if (unit.equals(element)) {
+                               if (isPossibleStructuralChange(delta)) {
+                                       return delta;
+                               }
+                               return null;
+                       }
+
+                       if (element.getElementType() > IJavaElement.CLASS_FILE)
+                               return null;
+
+                       IJavaElementDelta[] children = delta.getAffectedChildren();
+                       if (children == null || children.length == 0)
+                               return null;
+
+                       for (int i = 0; i < children.length; i++) {
+                               IJavaElementDelta d = findElement(unit, children[i]);
+                               if (d != null)
+                                       return d;
+                       }
+
+                       return null;
+               }
+       }
+
+       static class NoClassElement extends WorkbenchAdapter implements IAdaptable {
+               /*
+                * @see java.lang.Object#toString()
+                */
+               public String toString() {
+                       return PHPEditorMessages
+                                       .getString("JavaOutlinePage.error.NoTopLevelType"); //$NON-NLS-1$
+               }
+
+               /*
+                * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
+                */
+               public Object getAdapter(Class clas) {
+                       if (clas == IWorkbenchAdapter.class)
+                               return this;
+                       return null;
+               }
+       }
+
+       /**
+        * Content provider for the children of an ICompilationUnit or an IClassFile
+        * 
+        * @see ITreeContentProvider
+        */
+       class ChildrenProvider implements ITreeContentProvider {
+
+               private Object[] NO_CLASS = new Object[] { new NoClassElement() };
+
+               private ElementChangedListener fListener;
+
+               protected boolean matches(IJavaElement element) {
+                       if (element.getElementType() == IJavaElement.METHOD) {
+                               String name = element.getElementName();
+                               return (name != null && name.indexOf('<') >= 0);
+                       }
+                       return false;
+               }
+
+               protected IJavaElement[] filter(IJavaElement[] children) {
+                       boolean initializers = false;
+                       for (int i = 0; i < children.length; i++) {
+                               if (matches(children[i])) {
+                                       initializers = true;
+                                       break;
+                               }
+                       }
+
+                       if (!initializers)
+                               return children;
+
+                       Vector v = new Vector();
+                       for (int i = 0; i < children.length; i++) {
+                               if (matches(children[i]))
+                                       continue;
+                               v.addElement(children[i]);
+                       }
+
+                       IJavaElement[] result = new IJavaElement[v.size()];
+                       v.copyInto(result);
+                       return result;
+               }
+
+               public Object[] getChildren(Object parent) {
+                       if (parent instanceof IParent) {
+                               IParent c = (IParent) parent;
+                               try {
+                                       return filter(c.getChildren());
+                               } catch (JavaModelException x) {
+                                       // https://bugs.eclipse.org/bugs/show_bug.cgi?id=38341
+                                       // don't log NotExist exceptions as this is a valid case
+                                       // since we might have been posted and the element
+                                       // removed in the meantime.
+                                       if (PHPeclipsePlugin.isDebug() || !x.isDoesNotExist())
+                                               PHPeclipsePlugin.log(x);
+                               }
+                       }
+                       return NO_CHILDREN;
+               }
+
+               public Object[] getElements(Object parent) {
+                       if (fTopLevelTypeOnly) {
+                               if (parent instanceof ICompilationUnit) {
+                                       try {
+                                               IType type = getMainType((ICompilationUnit) parent);
+                                               return type != null ? type.getChildren() : NO_CLASS;
+                                       } catch (JavaModelException e) {
+                                               PHPeclipsePlugin.log(e);
+                                       }
+                               }
+                               // else if (parent instanceof IClassFile) {
+                               // try {
+                               // IType type= getMainType((IClassFile) parent);
+                               // return type != null ? type.getChildren() : NO_CLASS;
+                               // } catch (JavaModelException e) {
+                               // PHPeclipsePlugin.log(e);
+                               // }
+                               // }
+                       }
+                       return getChildren(parent);
+               }
+
+               public Object getParent(Object child) {
+                       if (child instanceof IJavaElement) {
+                               IJavaElement e = (IJavaElement) child;
+                               return e.getParent();
+                       }
+                       return null;
+               }
+
+               public boolean hasChildren(Object parent) {
+                       if (parent instanceof IParent) {
+                               IParent c = (IParent) parent;
+                               try {
+                                       IJavaElement[] children = filter(c.getChildren());
+                                       return (children != null && children.length > 0);
+                               } catch (JavaModelException x) {
+                                       // https://bugs.eclipse.org/bugs/show_bug.cgi?id=38341
+                                       // don't log NotExist exceptions as this is a valid case
+                                       // since we might have been posted and the element
+                                       // removed in the meantime.
+                                       if (PHPeclipsePlugin.isDebug() || !x.isDoesNotExist())
+                                               PHPeclipsePlugin.log(x);
+                               }
+                       }
+                       return false;
+               }
+
+               public boolean isDeleted(Object o) {
+                       return false;
+               }
+
+               public void dispose() {
+                       if (fListener != null) {
+                               JavaCore.removeElementChangedListener(fListener);
+                               fListener = null;
+                       }
+               }
+
+               /*
+                * @see IContentProvider#inputChanged(Viewer, Object, Object)
+                */
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+                       boolean isCU = (newInput instanceof ICompilationUnit);
+
+                       if (isCU && fListener == null) {
+                               fListener = new ElementChangedListener();
+                               JavaCore.addElementChangedListener(fListener);
+                       } else if (!isCU && fListener != null) {
+                               JavaCore.removeElementChangedListener(fListener);
+                               fListener = null;
+                       }
+               }
+       }
+
+       class JavaOutlineViewer extends TreeViewer {
+
+               /**
+                * Indicates an item which has been reused. At the point of its reuse it
+                * has been expanded. This field is used to communicate between
+                * <code>internalExpandToLevel</code> and <code>reuseTreeItem</code>.
+                */
+               private Item fReusedExpandedItem;
+
+               private boolean fReorderedMembers;
+
+               private boolean fForceFireSelectionChanged;
+
+               public JavaOutlineViewer(Tree tree) {
+                       super(tree);
+                       setAutoExpandLevel(ALL_LEVELS);
+                       setUseHashlookup(true);
+               }
+
+               /**
+                * Investigates the given element change event and if affected
+                * incrementally updates the Java outline.
+                * 
+                * @param delta
+                *            the Java element delta used to reconcile the Java outline
+                */
+               public void reconcile(IJavaElementDelta delta) {
+                       fReorderedMembers = false;
+                       fForceFireSelectionChanged = false;
+                       if (getSorter() == null) {
+                               if (fTopLevelTypeOnly && delta.getElement() instanceof IType
+                                               && (delta.getKind() & IJavaElementDelta.ADDED) != 0) {
+                                       refresh(true);
+
+                               } else {
+                                       Widget w = findItem(fInput);
+                                       if (w != null && !w.isDisposed())
+                                               update(w, delta);
+                                       if (fForceFireSelectionChanged)
+                                               fireSelectionChanged(new SelectionChangedEvent(
+                                                               getSite().getSelectionProvider(), this
+                                                                               .getSelection()));
+                                       if (fReorderedMembers) {
+                                               refresh(false);
+                                               fReorderedMembers = false;
+                                       }
+                               }
+                       } else {
+                               // just for now
+                               refresh(true);
+                       }
+               }
+
+               /*
+                * @see TreeViewer#internalExpandToLevel
+                */
+               protected void internalExpandToLevel(Widget node, int level) {
+                       if (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)) {
+                                               if (i != fReusedExpandedItem) {
+                                                       setExpanded(i, false);
+                                                       return;
+                                               }
+                                       }
+                               }
+                       }
+                       super.internalExpandToLevel(node, level);
+               }
+
+               protected void reuseTreeItem(Item item, Object element) {
+
+                       // remove children
+                       Item[] c = getChildren(item);
+                       if (c != null && c.length > 0) {
+
+                               if (getExpanded(item))
+                                       fReusedExpandedItem = item;
+
+                               for (int k = 0; k < c.length; k++) {
+                                       if (c[k].getData() != null)
+                                               disassociate(c[k]);
+                                       c[k].dispose();
+                               }
+                       }
+
+                       updateItem(item, element);
+                       updatePlus(item, element);
+                       internalExpandToLevel(item, ALL_LEVELS);
+
+                       fReusedExpandedItem = null;
+                       fForceFireSelectionChanged = true;
+               }
+
+               protected boolean mustUpdateParent(IJavaElementDelta delta,
+                               IJavaElement element) {
+                       if (element instanceof IMethod) {
+                               if ((delta.getKind() & IJavaElementDelta.ADDED) != 0) {
+                                       try {
+                                               return ((IMethod) element).isMainMethod();
+                                       } catch (JavaModelException e) {
+                                               PHPeclipsePlugin.log(e.getStatus());
+                                       }
+                               }
+                               return "main".equals(element.getElementName()); //$NON-NLS-1$
+                       }
+                       return false;
+               }
+
+               /*
+                * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object)
+                */
+               public boolean isExpandable(Object element) {
+                       if (hasFilters()) {
+                               return getFilteredChildren(element).length > 0;
+                       }
+                       return super.isExpandable(element);
+               }
+
+               protected ISourceRange getSourceRange(IJavaElement element)
+                               throws JavaModelException {
+                       if (element instanceof ISourceReference)
+                               return ((ISourceReference) element).getSourceRange();
+                       if (element instanceof IMember)// && !(element instanceof
+                                                                                       // IInitializer))
+                               return ((IMember) element).getNameRange();
+                       return null;
+               }
+
+               protected boolean overlaps(ISourceRange range, int start, int end) {
+                       return start <= (range.getOffset() + range.getLength() - 1)
+                                       && range.getOffset() <= end;
+               }
+
+               protected boolean filtered(IJavaElement parent, IJavaElement child) {
+
+                       Object[] result = new Object[] { child };
+                       ViewerFilter[] filters = getFilters();
+                       for (int i = 0; i < filters.length; i++) {
+                               result = filters[i].filter(this, parent, result);
+                               if (result.length == 0)
+                                       return true;
+                       }
+
+                       return false;
+               }
+
+               protected void update(Widget w, IJavaElementDelta delta) {
+
+                       Item item;
+
+                       IJavaElement parent = delta.getElement();
+                       IJavaElementDelta[] affected = delta.getAffectedChildren();
+                       Item[] children = getChildren(w);
+
+                       boolean doUpdateParent = false;
+                       boolean doUpdateParentsPlus = false;
+
+                       Vector deletions = new Vector();
+                       Vector additions = new Vector();
+
+                       for (int i = 0; i < affected.length; i++) {
+                               IJavaElementDelta affectedDelta = affected[i];
+                               IJavaElement affectedElement = affectedDelta.getElement();
+                               int status = affected[i].getKind();
+
+                               // find tree item with affected element
+                               int j;
+                               for (j = 0; j < children.length; j++)
+                                       if (affectedElement.equals(children[j].getData()))
+                                               break;
+
+                               if (j == children.length) {
+                                       // remove from collapsed parent
+                                       if ((status & IJavaElementDelta.REMOVED) != 0) {
+                                               doUpdateParentsPlus = true;
+                                               continue;
+                                       }
+                                       // addition
+                                       if ((status & IJavaElementDelta.CHANGED) != 0
+                                                       && (affectedDelta.getFlags() & IJavaElementDelta.F_MODIFIERS) != 0
+                                                       && !filtered(parent, affectedElement)) {
+                                               additions.addElement(affectedDelta);
+                                       }
+                                       continue;
+                               }
+
+                               item = children[j];
+
+                               // removed
+                               if ((status & IJavaElementDelta.REMOVED) != 0) {
+                                       deletions.addElement(item);
+                                       doUpdateParent = doUpdateParent
+                                                       || mustUpdateParent(affectedDelta, affectedElement);
+
+                                       // changed
+                               } else if ((status & IJavaElementDelta.CHANGED) != 0) {
+                                       int change = affectedDelta.getFlags();
+                                       doUpdateParent = doUpdateParent
+                                                       || mustUpdateParent(affectedDelta, affectedElement);
+
+                                       if ((change & IJavaElementDelta.F_MODIFIERS) != 0) {
+                                               if (filtered(parent, affectedElement))
+                                                       deletions.addElement(item);
+                                               else
+                                                       updateItem(item, affectedElement);
+                                       }
+
+                                       if ((change & IJavaElementDelta.F_CONTENT) != 0)
+                                               updateItem(item, affectedElement);
+
+                                       if ((change & IJavaElementDelta.F_CHILDREN) != 0)
+                                               update(item, affectedDelta);
+
+                                       if ((change & IJavaElementDelta.F_REORDER) != 0)
+                                               fReorderedMembers = true;
+                               }
+                       }
+
+                       // find all elements to add
+                       IJavaElementDelta[] add = delta.getAddedChildren();
+                       if (additions.size() > 0) {
+                               IJavaElementDelta[] tmp = new IJavaElementDelta[add.length
+                                               + additions.size()];
+                               System.arraycopy(add, 0, tmp, 0, add.length);
+                               for (int i = 0; i < additions.size(); i++)
+                                       tmp[i + add.length] = (IJavaElementDelta) additions
+                                                       .elementAt(i);
+                               add = tmp;
+                       }
+
+                       // add at the right position
+                       go2: for (int i = 0; i < add.length; i++) {
+
+                               try {
+
+                                       IJavaElement e = add[i].getElement();
+                                       if (filtered(parent, e))
+                                               continue go2;
+
+                                       doUpdateParent = doUpdateParent
+                                                       || mustUpdateParent(add[i], e);
+                                       ISourceRange rng = getSourceRange(e);
+                                       int start = rng.getOffset();
+                                       int end = start + rng.getLength() - 1;
+                                       int nameOffset = Integer.MAX_VALUE;
+                                       if (e instanceof IField) {
+                                               ISourceRange nameRange = ((IField) e).getNameRange();
+                                               if (nameRange != null)
+                                                       nameOffset = nameRange.getOffset();
+                                       }
+
+                                       Item last = null;
+                                       item = null;
+                                       children = getChildren(w);
+
+                                       for (int j = 0; j < children.length; j++) {
+                                               item = children[j];
+                                               IJavaElement r = (IJavaElement) item.getData();
+
+                                               if (r == null) {
+                                                       // parent node collapsed and not be opened before ->
+                                                       // do nothing
+                                                       continue go2;
+                                               }
+
+                                               try {
+                                                       rng = getSourceRange(r);
+
+                                                       // multi-field declarations always start at
+                                                       // the same offset. They also have the same
+                                                       // end offset if the field sequence is terminated
+                                                       // with a semicolon. If not, the source range
+                                                       // ends behind the identifier / initializer
+                                                       // see
+                                                       // https://bugs.eclipse.org/bugs/show_bug.cgi?id=51851
+                                                       boolean multiFieldDeclaration = r.getElementType() == IJavaElement.FIELD
+                                                                       && e.getElementType() == IJavaElement.FIELD
+                                                                       && rng.getOffset() == start;
+
+                                                       // elements are inserted by occurrence
+                                                       // however, multi-field declarations have
+                                                       // equal source ranges offsets, therefore we
+                                                       // compare name-range offsets.
+                                                       boolean multiFieldOrderBefore = false;
+                                                       if (multiFieldDeclaration) {
+                                                               if (r instanceof IField) {
+                                                                       ISourceRange nameRange = ((IField) r)
+                                                                                       .getNameRange();
+                                                                       if (nameRange != null) {
+                                                                               if (nameRange.getOffset() > nameOffset)
+                                                                                       multiFieldOrderBefore = true;
+                                                                       }
+                                                               }
+                                                       }
+
+                                                       if (!multiFieldDeclaration
+                                                                       && overlaps(rng, start, end)) {
+
+                                                               // be tolerant if the delta is not correct, or
+                                                               // if
+                                                               // the tree has been updated other than by a
+                                                               // delta
+                                                               reuseTreeItem(item, e);
+                                                               continue go2;
+
+                                                       } else if (multiFieldOrderBefore
+                                                                       || rng.getOffset() > start) {
+
+                                                               if (last != null && deletions.contains(last)) {
+                                                                       // reuse item
+                                                                       deletions.removeElement(last);
+                                                                       reuseTreeItem(last, e);
+                                                               } else {
+                                                                       // nothing to reuse
+                                                                       createTreeItem(w, e, j);
+                                                               }
+                                                               continue go2;
+                                                       }
+
+                                               } catch (JavaModelException x) {
+                                                       // stumbled over deleted element
+                                               }
+
+                                               last = item;
+                                       }
+
+                                       // add at the end of the list
+                                       if (last != null && deletions.contains(last)) {
+                                               // reuse item
+                                               deletions.removeElement(last);
+                                               reuseTreeItem(last, e);
+                                       } else {
+                                               // nothing to reuse
+                                               createTreeItem(w, e, -1);
+                                       }
+
+                               } catch (JavaModelException x) {
+                                       // the element to be added is not present -> don't add it
+                               }
+                       }
+
+                       // remove items which haven't been reused
+                       Enumeration e = deletions.elements();
+                       while (e.hasMoreElements()) {
+                               item = (Item) e.nextElement();
+                               disassociate(item);
+                               item.dispose();
+                       }
+
+                       if (doUpdateParent)
+                               updateItem(w, delta.getElement());
+                       if (!doUpdateParent && doUpdateParentsPlus && w instanceof Item)
+                               updatePlus((Item) w, delta.getElement());
+               }
+
+               /*
+                * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent)
+                */
+               protected void handleLabelProviderChanged(
+                               LabelProviderChangedEvent event) {
+                       Object input = getInput();
+                       if (event instanceof ProblemsLabelChangedEvent) {
+                               ProblemsLabelChangedEvent e = (ProblemsLabelChangedEvent) event;
+                               if (e.isMarkerChange() && input instanceof ICompilationUnit) {
+                                       return; // marker changes can be ignored
+                               }
+                       }
+                       // look if the underlying resource changed
+                       Object[] changed = event.getElements();
+                       if (changed != null) {
+                               IResource resource = getUnderlyingResource();
+                               if (resource != null) {
+                                       for (int i = 0; i < changed.length; i++) {
+                                               if (changed[i] != null && changed[i].equals(resource)) {
+                                                       // change event to a full refresh
+                                                       event = new LabelProviderChangedEvent(
+                                                                       (IBaseLabelProvider) event.getSource());
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       super.handleLabelProviderChanged(event);
+               }
+
+               private IResource getUnderlyingResource() {
+                       Object input = getInput();
+                       if (input instanceof ICompilationUnit) {
+                               ICompilationUnit cu = (ICompilationUnit) input;
+                               cu = JavaModelUtil.toOriginal(cu);
+                               return cu.getResource();
+                       }
+                       // else if (input instanceof IClassFile) {
+                       // return ((IClassFile) input).getResource();
+                       // }
+                       return null;
+               }
+
+       }
+
+       class LexicalSortingAction extends Action {
+
+               private JavaElementSorter fSorter = new JavaElementSorter();
+
+               public LexicalSortingAction() {
+                       super();
+                       PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                                       IJavaHelpContextIds.LEXICAL_SORTING_OUTLINE_ACTION);
+                       setText(PHPEditorMessages.getString("JavaOutlinePage.Sort.label")); //$NON-NLS-1$
+                       PHPUiImages.setLocalImageDescriptors(this, "alphab_sort_co.gif"); //$NON-NLS-1$
+                       setToolTipText(PHPEditorMessages
+                                       .getString("JavaOutlinePage.Sort.tooltip")); //$NON-NLS-1$
+                       setDescription(PHPEditorMessages
+                                       .getString("JavaOutlinePage.Sort.description")); //$NON-NLS-1$
+
+                       boolean checked = WebUI.getDefault()
+                                       .getPreferenceStore().getBoolean(
+                                                       "LexicalSortingAction.isChecked"); //$NON-NLS-1$
+                       valueChanged(checked, false);
+               }
+
+               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.setSorter(on ? fSorter : null);
+                                               }
+                                       });
+
+                       if (store)
+                               WebUI.getDefault().getPreferenceStore().setValue(
+                                               "LexicalSortingAction.isChecked", on); //$NON-NLS-1$
+               }
+       }
+
+       class ClassOnlyAction extends Action {
+
+               public ClassOnlyAction() {
+                       super();
+                       PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                                       IJavaHelpContextIds.GO_INTO_TOP_LEVEL_TYPE_ACTION);
+                       setText(PHPEditorMessages
+                                       .getString("JavaOutlinePage.GoIntoTopLevelType.label")); //$NON-NLS-1$
+                       setToolTipText(PHPEditorMessages
+                                       .getString("JavaOutlinePage.GoIntoTopLevelType.tooltip")); //$NON-NLS-1$
+                       setDescription(PHPEditorMessages
+                                       .getString("JavaOutlinePage.GoIntoTopLevelType.description")); //$NON-NLS-1$
+                       PHPUiImages.setLocalImageDescriptors(this,
+                                       "gointo_toplevel_type.gif"); //$NON-NLS-1$
+
+                       IPreferenceStore preferenceStore = WebUI.getDefault()
+                                       .getPreferenceStore();
+                       boolean showclass = preferenceStore
+                                       .getBoolean("GoIntoTopLevelTypeAction.isChecked"); //$NON-NLS-1$
+                       setTopLevelTypeOnly(showclass);
+               }
+
+               /*
+                * @see org.eclipse.jface.action.Action#run()
+                */
+               public void run() {
+                       setTopLevelTypeOnly(!fTopLevelTypeOnly);
+               }
+
+               private void setTopLevelTypeOnly(boolean show) {
+                       fTopLevelTypeOnly = show;
+                       setChecked(show);
+                       fOutlineViewer.refresh(false);
+
+                       IPreferenceStore preferenceStore = WebUI.getDefault()
+                                       .getPreferenceStore();
+                       preferenceStore
+                                       .setValue("GoIntoTopLevelTypeAction.isChecked", show); //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * This action toggles whether this Java Outline page links its selection to
+        * the active editor.
+        * 
+        * @since 3.0
+        */
+       public class ToggleLinkingAction extends AbstractToggleLinkingAction {
+
+               JavaOutlinePage fJavaOutlinePage;
+
+               /**
+                * Constructs a new action.
+                * 
+                * @param outlinePage
+                *            the Java outline page
+                */
+               public ToggleLinkingAction(JavaOutlinePage outlinePage) {
+                       boolean isLinkingEnabled = PreferenceConstants
+                                       .getPreferenceStore()
+                                       .getBoolean(
+                                                       PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE);
+                       setChecked(isLinkingEnabled);
+                       fJavaOutlinePage = outlinePage;
+               }
+
+               /**
+                * Runs the action.
+                */
+               public void run() {
+                       PreferenceConstants.getPreferenceStore().setValue(
+                                       PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE,
+                                       isChecked());
+                       if (isChecked() && fEditor != null)
+                               fEditor.synchronizeOutlinePage(fEditor
+                                               .computeHighlightRangeSourceReference(), false);
+               }
+
+       }
+
+       /** A flag to show contents of top level type only */
+       private boolean fTopLevelTypeOnly;
+
+       private IJavaElement fInput;
+
+       private String fContextMenuID;
+
+       private Menu fMenu;
+
+       private JavaOutlineViewer fOutlineViewer;
+
+       private PHPEditor fEditor;
+
+       private MemberFilterActionGroup fMemberFilterActionGroup;
+
+       private ListenerList fSelectionChangedListeners = new ListenerList();
+
+       private ListenerList fPostSelectionChangedListeners = new ListenerList();
+
+       private Hashtable fActions = new Hashtable();
+
+       private TogglePresentationAction fTogglePresentation;
+
+       private GotoAnnotationAction fPreviousAnnotation;
+
+       private GotoAnnotationAction fNextAnnotation;
+
+       private TextEditorAction fShowJavadoc;
+
+       private IAction fUndo;
+
+       private IAction fRedo;
+
+       private ToggleLinkingAction fToggleLinkingAction;
+
+       private CompositeActionGroup fActionGroups;
+
+       private IPropertyChangeListener fPropertyChangeListener;
+
+       /**
+        * Custom filter action group.
+        * 
+        * @since 3.0
+        */
+       private CustomFiltersActionGroup fCustomFiltersActionGroup;
+
+       public JavaOutlinePage(String contextMenuID, PHPEditor editor) {
+               super();
+
+               Assert.isNotNull(editor);
+
+               fContextMenuID = contextMenuID;
+               fEditor = editor;
+               fTogglePresentation = new TogglePresentationAction();
+               ResourceBundle bundle = PHPEditorMessages.getResourceBundle();
+               fPreviousAnnotation = new GotoAnnotationAction(bundle,
+                               "PreviousAnnotation.", null, false); //$NON-NLS-1$
+               fNextAnnotation = new GotoAnnotationAction(bundle,
+                               "NextAnnotation.", null, true); //$NON-NLS-1$
+               fShowJavadoc = (TextEditorAction) fEditor.getAction("ShowJavaDoc"); //$NON-NLS-1$
+               fUndo = fEditor.getAction(ITextEditorActionConstants.UNDO);
+               fRedo = fEditor.getAction(ITextEditorActionConstants.REDO);
+
+               fTogglePresentation.setEditor(editor);
+               fPreviousAnnotation.setEditor(editor);
+               fNextAnnotation.setEditor(editor);
+
+               fPropertyChangeListener = new IPropertyChangeListener() {
+                       public void propertyChange(PropertyChangeEvent event) {
+                               doPropertyChange(event);
+                       }
+               };
+               WebUI.getDefault().getPreferenceStore()
+                               .addPropertyChangeListener(fPropertyChangeListener);
+       }
+
+       /**
+        * Returns the primary type of a compilation unit (has the same name as the
+        * compilation unit).
+        * 
+        * @param compilationUnit
+        *            the compilation unit
+        * @return returns the primary type of the compilation unit, or
+        *         <code>null</code> if is does not have one
+        */
+       protected IType getMainType(ICompilationUnit compilationUnit) {
+
+               if (compilationUnit == null)
+                       return null;
+
+               String name = compilationUnit.getElementName();
+               int index = name.indexOf('.');
+               if (index != -1)
+                       name = name.substring(0, index);
+               IType type = compilationUnit.getType(name);
+               return type.exists() ? type : null;
+       }
+
+       /**
+        * Returns the primary type of a class file.
+        * 
+        * @param classFile
+        *            the class file
+        * @return returns the primary type of the class file, or <code>null</code>
+        *         if is does not have one
+        */
+       // protected IType getMainType(IClassFile classFile) {
+       // try {
+       // IType type= classFile.getType();
+       // return type != null && type.exists() ? type : null;
+       // } catch (JavaModelException e) {
+       // return null;
+       // }
+       // }
+       /*
+        * (non-Javadoc) Method declared on Page
+        */
+       public void init(IPageSite pageSite) {
+               super.init(pageSite);
+       }
+
+       private void doPropertyChange(PropertyChangeEvent event) {
+               if (fOutlineViewer != null) {
+                       if (MembersOrderPreferenceCache.isMemberOrderProperty(event
+                                       .getProperty())) {
+                               fOutlineViewer.refresh(false);
+                       }
+               }
+       }
+
+       /*
+        * @see ISelectionProvider#addSelectionChangedListener(ISelectionChangedListener)
+        */
+       public void addSelectionChangedListener(ISelectionChangedListener listener) {
+               if (fOutlineViewer != null)
+                       fOutlineViewer.addSelectionChangedListener(listener);
+               else
+                       fSelectionChangedListeners.add(listener);
+       }
+
+       /*
+        * @see ISelectionProvider#removeSelectionChangedListener(ISelectionChangedListener)
+        */
+       public void removeSelectionChangedListener(
+                       ISelectionChangedListener listener) {
+               if (fOutlineViewer != null)
+                       fOutlineViewer.removeSelectionChangedListener(listener);
+               else
+                       fSelectionChangedListeners.remove(listener);
+       }
+
+       /*
+        * @see ISelectionProvider#setSelection(ISelection)
+        */
+       public void setSelection(ISelection selection) {
+               if (fOutlineViewer != null)
+                       fOutlineViewer.setSelection(selection);
+       }
+
+       /*
+        * @see ISelectionProvider#getSelection()
+        */
+       public ISelection getSelection() {
+               if (fOutlineViewer == null)
+                       return StructuredSelection.EMPTY;
+               return fOutlineViewer.getSelection();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IPostSelectionProvider#addPostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
+        */
+       public void addPostSelectionChangedListener(
+                       ISelectionChangedListener listener) {
+               if (fOutlineViewer != null)
+                       fOutlineViewer.addPostSelectionChangedListener(listener);
+               else
+                       fPostSelectionChangedListeners.add(listener);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IPostSelectionProvider#removePostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
+        */
+       public void removePostSelectionChangedListener(
+                       ISelectionChangedListener listener) {
+               if (fOutlineViewer != null)
+                       fOutlineViewer.removePostSelectionChangedListener(listener);
+               else
+                       fPostSelectionChangedListeners.remove(listener);
+       }
+
+       private void registerToolbarActions(IActionBars actionBars) {
+
+               IToolBarManager toolBarManager = actionBars.getToolBarManager();
+               if (toolBarManager != null) {
+                       toolBarManager.add(new LexicalSortingAction());
+
+                       fMemberFilterActionGroup = new MemberFilterActionGroup(
+                                       fOutlineViewer,
+                                       "net.sourceforge.phpeclipse.JavaOutlinePage"); //$NON-NLS-1$
+                       fMemberFilterActionGroup.contributeToToolBar(toolBarManager);
+
+                       fCustomFiltersActionGroup.fillActionBars(actionBars);
+
+                       IMenuManager menu = actionBars.getMenuManager();
+                       menu.add(new Separator("EndFilterGroup")); //$NON-NLS-1$
+
+                       fToggleLinkingAction = new ToggleLinkingAction(this);
+                       menu.add(new ClassOnlyAction());
+                       menu.add(fToggleLinkingAction);
+               }
+       }
+
+       /*
+        * @see IPage#createControl
+        */
+       public void createControl(Composite parent) {
+
+               Tree tree = new Tree(parent, SWT.MULTI);
+
+               AppearanceAwareLabelProvider lprovider = new AppearanceAwareLabelProvider(
+                               AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS
+                                               | JavaElementLabels.F_APP_TYPE_SIGNATURE,
+                               AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS);
+
+               fOutlineViewer = new JavaOutlineViewer(tree);
+               initDragAndDrop();
+               fOutlineViewer.setContentProvider(new ChildrenProvider());
+               fOutlineViewer.setLabelProvider(new DecoratingJavaLabelProvider(
+                               lprovider));
+
+               Object[] listeners = fSelectionChangedListeners.getListeners();
+               for (int i = 0; i < listeners.length; i++) {
+                       fSelectionChangedListeners.remove(listeners[i]);
+                       fOutlineViewer
+                                       .addSelectionChangedListener((ISelectionChangedListener) listeners[i]);
+               }
+
+               listeners = fPostSelectionChangedListeners.getListeners();
+               for (int i = 0; i < listeners.length; i++) {
+                       fPostSelectionChangedListeners.remove(listeners[i]);
+                       fOutlineViewer
+                                       .addPostSelectionChangedListener((ISelectionChangedListener) listeners[i]);
+               }
+
+               MenuManager manager = new MenuManager(fContextMenuID, fContextMenuID);
+               manager.setRemoveAllWhenShown(true);
+               manager.addMenuListener(new IMenuListener() {
+                       public void menuAboutToShow(IMenuManager m) {
+                               contextMenuAboutToShow(m);
+                       }
+               });
+               fMenu = manager.createContextMenu(tree);
+               tree.setMenu(fMenu);
+
+               IPageSite site = getSite();
+               site
+                               .registerContextMenu(PHPeclipsePlugin.getPluginId()
+                                               + ".outline", manager, fOutlineViewer); //$NON-NLS-1$
+               site.setSelectionProvider(fOutlineViewer);
+
+               // we must create the groups after we have set the selection provider to
+               // the site
+               fActionGroups = new CompositeActionGroup(new ActionGroup[] {
+               // new OpenViewActionGroup(this),
+                               // new CCPActionGroup(this),
+                               new GenerateActionGroup(this) });
+               // new RefactorActionGroup(this),
+               // new JavaSearchActionGroup(this)});
+
+               // register global actions
+               IActionBars bars = site.getActionBars();
+
+               bars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, fUndo);
+               bars.setGlobalActionHandler(ITextEditorActionConstants.REDO, fRedo);
+               bars.setGlobalActionHandler(ActionFactory.PREVIOUS.getId(),
+                               fPreviousAnnotation);
+               bars
+                               .setGlobalActionHandler(ActionFactory.NEXT.getId(),
+                                               fNextAnnotation);
+               bars.setGlobalActionHandler(PHPdtActionConstants.SHOW_JAVA_DOC,
+                               fShowJavadoc);
+               bars
+                               .setGlobalActionHandler(
+                                               ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY,
+                                               fTogglePresentation);
+               bars.setGlobalActionHandler(
+                               ITextEditorActionDefinitionIds.GOTO_NEXT_ANNOTATION,
+                               fNextAnnotation);
+               bars.setGlobalActionHandler(
+                               ITextEditorActionDefinitionIds.GOTO_PREVIOUS_ANNOTATION,
+                               fPreviousAnnotation);
+
+               fActionGroups.fillActionBars(bars);
+
+               IStatusLineManager statusLineManager = bars.getStatusLineManager();
+               if (statusLineManager != null) {
+                       StatusBarUpdater updater = new StatusBarUpdater(statusLineManager);
+                       fOutlineViewer.addPostSelectionChangedListener(updater);
+               }
+               // Custom filter group
+               fCustomFiltersActionGroup = new CustomFiltersActionGroup(
+                               "net.sourceforge.phpdt.ui.JavaOutlinePage", fOutlineViewer); //$NON-NLS-1$
+
+               registerToolbarActions(bars);
+
+               fOutlineViewer.setInput(fInput);
+       }
+
+       public void dispose() {
+
+               if (fEditor == null)
+                       return;
+
+               if (fMemberFilterActionGroup != null) {
+                       fMemberFilterActionGroup.dispose();
+                       fMemberFilterActionGroup = null;
+               }
+
+               if (fCustomFiltersActionGroup != null) {
+                       fCustomFiltersActionGroup.dispose();
+                       fCustomFiltersActionGroup = null;
+               }
+
+               fEditor.outlinePageClosed();
+               fEditor = null;
+
+               fSelectionChangedListeners.clear();
+               fSelectionChangedListeners = null;
+
+               fPostSelectionChangedListeners.clear();
+               fPostSelectionChangedListeners = null;
+
+               if (fPropertyChangeListener != null) {
+                       WebUI.getDefault().getPreferenceStore()
+                                       .removePropertyChangeListener(fPropertyChangeListener);
+                       fPropertyChangeListener = null;
+               }
+
+               if (fMenu != null && !fMenu.isDisposed()) {
+                       fMenu.dispose();
+                       fMenu = null;
+               }
+
+               if (fActionGroups != null)
+                       fActionGroups.dispose();
+
+               fTogglePresentation.setEditor(null);
+               fPreviousAnnotation.setEditor(null);
+               fNextAnnotation.setEditor(null);
+
+               fOutlineViewer = null;
+
+               super.dispose();
+       }
+
+       public Control getControl() {
+               if (fOutlineViewer != null)
+                       return fOutlineViewer.getControl();
+               return null;
+       }
+
+       public void setInput(IJavaElement inputElement) {
+               fInput = inputElement;
+               if (fOutlineViewer != null)
+                       fOutlineViewer.setInput(fInput);
+       }
+
+       public void select(ISourceReference reference) {
+               if (fOutlineViewer != null) {
+
+                       ISelection s = fOutlineViewer.getSelection();
+                       if (s instanceof IStructuredSelection) {
+                               IStructuredSelection ss = (IStructuredSelection) s;
+                               List elements = ss.toList();
+                               if (!elements.contains(reference)) {
+                                       s = (reference == null ? StructuredSelection.EMPTY
+                                                       : new StructuredSelection(reference));
+                                       fOutlineViewer.setSelection(s, true);
+                               }
+                       }
+               }
+       }
+
+       public void setAction(String actionID, IAction action) {
+               Assert.isNotNull(actionID);
+               if (action == null)
+                       fActions.remove(actionID);
+               else
+                       fActions.put(actionID, action);
+       }
+
+       public IAction getAction(String actionID) {
+               Assert.isNotNull(actionID);
+               return (IAction) fActions.get(actionID);
+       }
+
+       /*
+        * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+        */
+       public Object getAdapter(Class key) {
+               if (key == IShowInSource.class) {
+                       return getShowInSource();
+               }
+               if (key == IShowInTargetList.class) {
+                       return new IShowInTargetList() {
+                               public String[] getShowInTargetIds() {
+                                       return new String[] { JavaUI.ID_PACKAGES };
+                               }
+
+                       };
+               }
+               if (key == IShowInTarget.class) {
+                       return getShowInTarget();
+               }
+
+               return null;
+       }
+
+       /**
+        * Convenience method to add the action installed under the given actionID
+        * to the specified group of the menu.
+        * 
+        * @param menu
+        *            the menu manager
+        * @param group
+        *            the group to which to add the action
+        * @param actionID
+        *            the ID of the new action
+        */
+       protected void addAction(IMenuManager menu, String group, String actionID) {
+               IAction action = getAction(actionID);
+               if (action != null) {
+                       if (action instanceof IUpdate)
+                               ((IUpdate) action).update();
+
+                       if (action.isEnabled()) {
+                               IMenuManager subMenu = menu.findMenuUsingPath(group);
+                               if (subMenu != null)
+                                       subMenu.add(action);
+                               else
+                                       menu.appendToGroup(group, action);
+                       }
+               }
+       }
+
+       protected void contextMenuAboutToShow(IMenuManager menu) {
+
+               WebUI.createStandardGroups(menu);
+
+               IStructuredSelection selection = (IStructuredSelection) getSelection();
+               fActionGroups.setContext(new ActionContext(selection));
+               fActionGroups.fillContextMenu(menu);
+       }
+
+       /*
+        * @see Page#setFocus()
+        */
+       public void setFocus() {
+               if (fOutlineViewer != null)
+                       fOutlineViewer.getControl().setFocus();
+       }
+
+       /**
+        * Checks whether a given Java element is an inner type.
+        * 
+        * @param element
+        *            the java element
+        * @return <code>true</code> iff the given element is an inner type
+        */
+       private boolean isInnerType(IJavaElement element) {
+
+               if (element != null && element.getElementType() == IJavaElement.TYPE) {
+                       IType type = (IType) element;
+                       try {
+                               return type.isMember();
+                       } catch (JavaModelException e) {
+                               IJavaElement parent = type.getParent();
+                               if (parent != null) {
+                                       int parentElementType = parent.getElementType();
+                                       return (parentElementType != IJavaElement.COMPILATION_UNIT && parentElementType != IJavaElement.CLASS_FILE);
+                               }
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Returns the <code>IShowInSource</code> for this view.
+        * 
+        * @return the {@link IShowInSource}
+        */
+       protected IShowInSource getShowInSource() {
+               return new IShowInSource() {
+                       public ShowInContext getShowInContext() {
+                               return new ShowInContext(null, getSite().getSelectionProvider()
+                                               .getSelection());
+                       }
+               };
+       }
+
+       /**
+        * Returns the <code>IShowInTarget</code> for this view.
+        * 
+        * @return the {@link IShowInTarget}
+        */
+       protected IShowInTarget getShowInTarget() {
+               return new IShowInTarget() {
+                       public boolean show(ShowInContext context) {
+                               ISelection sel = context.getSelection();
+                               if (sel instanceof ITextSelection) {
+                                       ITextSelection tsel = (ITextSelection) sel;
+                                       int offset = tsel.getOffset();
+                                       IJavaElement element = fEditor.getElementAt(offset);
+                                       if (element != null) {
+                                               setSelection(new StructuredSelection(element));
+                                               return true;
+                                       }
+                               }
+                               return false;
+                       }
+               };
+       }
+
+       private void initDragAndDrop() {
+               int ops = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
+               Transfer[] transfers = new Transfer[] { LocalSelectionTransfer
+                               .getInstance() };
+
+               // Drop Adapter
+               // TransferDropTargetListener[] dropListeners= new
+               // TransferDropTargetListener[] {
+               // new SelectionTransferDropAdapter(fOutlineViewer)
+               // };
+               // fOutlineViewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, new
+               // DelegatingDropAdapter(dropListeners));
+
+               // Drag Adapter
+               // TransferDragSourceListener[] dragListeners= new
+               // TransferDragSourceListener[] {
+               // new SelectionTransferDragAdapter(fOutlineViewer)
+               // };
+               // fOutlineViewer.addDragSupport(ops, transfers, new
+               // JdtViewerDragAdapter(fOutlineViewer, dragListeners));
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction.java
new file mode 100644 (file)
index 0000000..e265b54
--- /dev/null
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.Iterator;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorExtension;
+import org.eclipse.ui.texteditor.SelectMarkerRulerAction;
+
+/**
+ * A special select marker ruler action which activates quick fix if clicked on
+ * a quick fixable problem.
+ */
+public class JavaSelectMarkerRulerAction extends SelectMarkerRulerAction {
+
+       private ITextEditor fTextEditor;
+
+       private Position fPosition;
+
+       public JavaSelectMarkerRulerAction(ResourceBundle bundle, String prefix,
+                       ITextEditor editor, IVerticalRulerInfo ruler) {
+               super(bundle, prefix, editor, ruler);
+               fTextEditor = editor;
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                               IJavaHelpContextIds.JAVA_SELECT_MARKER_RULER_ACTION);
+       }
+
+       public void run() {
+               // if
+               // (PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
+               // return;
+
+               if (fPosition != null) {
+                       ITextOperationTarget operation = (ITextOperationTarget) fTextEditor
+                                       .getAdapter(ITextOperationTarget.class);
+                       // final int opCode= PHPUnitEditor.CORRECTIONASSIST_PROPOSALS;
+                       // if (operation != null && operation.canDoOperation(opCode)) {
+                       // fTextEditor.selectAndReveal(fPosition.getOffset(),
+                       // fPosition.getLength());
+                       // operation.doOperation(opCode);
+                       // return;
+                       // }
+                       return;
+               }
+               super.run();
+       }
+
+       public void update() {
+               // Begin Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20114
+               if (!(fTextEditor instanceof ITextEditorExtension)
+                               || ((ITextEditorExtension) fTextEditor).isEditorInputReadOnly()) {
+                       fPosition = null;
+                       super.update();
+                       return;
+               }
+               // End Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20114
+               fPosition = getJavaAnnotationPosition();
+               if (fPosition != null)
+                       setEnabled(true);
+               else
+                       super.update();
+       }
+
+       private Position getJavaAnnotationPosition() {
+               AbstractMarkerAnnotationModel model = getAnnotationModel();
+               IDocument document = getDocument();
+               if (model == null)
+                       return null;
+               ICompilationUnit cu = getCompilationUnit();
+               if (cu == null) {
+                       return null;
+               }
+
+               // boolean hasAssistLightbulb=
+               // PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.APPEARANCE_QUICKASSIST_LIGHTBULB);
+               Annotation assistAnnotation = null;
+
+               Iterator iter = model.getAnnotationIterator();
+               while (iter.hasNext()) {
+                       Annotation annotation = (Annotation) iter.next();
+                       if (annotation instanceof IJavaAnnotation) {
+                               IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
+                               if (!javaAnnotation.isMarkedDeleted()) {
+                                       Position position = model.getPosition(annotation);
+                                       // if (includesRulerLine(position, document) &&
+                                       // JavaCorrectionProcessor.hasCorrections(javaAnnotation))
+                                       // return position;
+                               }
+                       }
+                       // else if (hasAssistLightbulb && annotation instanceof
+                       // AssistAnnotation) {
+                       // // there is only one AssistAnnotation at a time
+                       // assistAnnotation= annotation;
+                       // }
+               }
+               if (assistAnnotation != null) {
+                       Position position = model.getPosition(assistAnnotation);
+                       // no need to check 'JavaCorrectionProcessor.hasAssists': annotation
+                       // only created when
+                       // there are assists
+                       if (includesRulerLine(position, document))
+                               return position;
+               }
+               return null;
+       }
+
+       private ICompilationUnit getCompilationUnit() {
+               IEditorInput input = fTextEditor.getEditorInput();
+               if (input instanceof IFileEditorInput) {
+                       IFile file = ((IFileEditorInput) input).getFile();
+                       IJavaElement element = JavaCore.create(file);
+                       if (element instanceof ICompilationUnit)
+                               return (ICompilationUnit) element;
+               }
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction2.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectMarkerRulerAction2.java
new file mode 100644 (file)
index 0000000..5b3abd8
--- /dev/null
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+
+import org.eclipse.jface.action.IAction;
+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.VerticalRulerEvent;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.texteditor.SelectAnnotationRulerAction;
+
+// import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+// import
+// net.sourceforge.phpdt.internal.ui.text.correction.JavaCorrectionProcessor;
+// import
+// net.sourceforge.phpdt.internal.ui.text.correction.QuickAssistLightBulbUpdater.AssistAnnotation;
+// import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaExpandHover;
+
+/**
+ * A special select marker ruler action which activates quick fix if clicked on
+ * a quick fixable problem.
+ */
+public class JavaSelectMarkerRulerAction2 extends SelectAnnotationRulerAction {
+
+       public JavaSelectMarkerRulerAction2(ResourceBundle bundle, String prefix,
+                       ITextEditor editor) {
+               super(bundle, prefix, editor);
+               PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                               IJavaHelpContextIds.JAVA_SELECT_MARKER_RULER_ACTION);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.IVerticalRulerListener#annotationDefaultSelected(org.eclipse.ui.texteditor.VerticalRulerEvent)
+        */
+       public void annotationDefaultSelected(VerticalRulerEvent event) {
+               Annotation annotation = event.getSelectedAnnotation();
+               IAnnotationModel model = getAnnotationModel();
+
+               // if (isOverrideIndicator(annotation)) {
+               // ((OverrideIndicatorManager.OverrideIndicator)annotation).open();
+               // return;
+               // }
+
+               if (isBreakpoint(annotation))
+                       triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK);
+
+               Position position = model.getPosition(annotation);
+               if (position == null)
+                       return;
+
+               // if (isQuickFixTarget(annotation)) {
+               // ITextOperationTarget operation= (ITextOperationTarget)
+               // getTextEditor().getAdapter(ITextOperationTarget.class);
+               // final int opCode= PHPUnitEditor.CORRECTIONASSIST_PROPOSALS;
+               // if (operation != null && operation.canDoOperation(opCode)) {
+               // getTextEditor().selectAndReveal(position.getOffset(),
+               // position.getLength());
+               // operation.doOperation(opCode);
+               // return;
+               // }
+               // }
+
+               // default:
+               super.annotationDefaultSelected(event);
+       }
+
+       /**
+        * Tells whether the given annotation is an override annotation.
+        * 
+        * @param annotation
+        *            the annotation
+        * @return <code>true</code> iff the annotation is an override annotation
+        */
+       private boolean isOverrideIndicator(Annotation annotation) {
+               return false; // annotation instanceof
+                                               // OverrideIndicatorManager.OverrideIndicator;
+       }
+
+       /**
+        * @param annotation
+        * @return
+        */
+       private boolean isBreakpoint(Annotation annotation) {
+               return annotation.getType().equals("org.eclipse.debug.core.breakpoint");
+               // ||
+               // annotation.getType().equals(JavaExpandHover.NO_BREAKPOINT_ANNOTATION);
+               // //$NON-NLS-1$
+
+       }
+
+       private boolean isQuickFixTarget(Annotation a) {
+               return false; // JavaCorrectionProcessor.hasCorrections(a) || a
+                                               // instanceof AssistAnnotation;
+       }
+
+       private void triggerAction(String actionID) {
+               IAction action = getTextEditor().getAction(actionID);
+               if (action != null) {
+                       if (action instanceof IUpdate)
+                               ((IUpdate) action).update();
+                       // hack to propagate line change
+                       if (action instanceof ISelectionListener) {
+                               ((ISelectionListener) action).selectionChanged(null, null);
+                       }
+                       if (action.isEnabled())
+                               action.run();
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectRulerAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSelectRulerAction.java
new file mode 100644 (file)
index 0000000..586ff2e
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.ui.texteditor.AbstractRulerActionDelegate;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class JavaSelectRulerAction extends AbstractRulerActionDelegate {
+
+       /*
+        * @see AbstractRulerActionDelegate#createAction(ITextEditor,
+        *      IVerticalRulerInfo)
+        */
+       protected IAction createAction(ITextEditor editor,
+                       IVerticalRulerInfo rulerInfo) {
+               return new JavaSelectMarkerRulerAction(PHPEditorMessages
+                               .getResourceBundle(),
+                               "JavaSelectMarkerRulerAction.", editor, rulerInfo); //$NON-NLS-1$
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java
new file mode 100644 (file)
index 0000000..124ee59
--- /dev/null
@@ -0,0 +1,471 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.ITextPresentationListener;
+import org.eclipse.jface.text.information.IInformationPresenter;
+import org.eclipse.jface.text.reconciler.IReconciler;
+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.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+
+public class JavaSourceViewer extends ProjectionViewer implements
+               IPropertyChangeListener {
+
+       /**
+        * 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;
+
+       private IInformationPresenter fOutlinePresenter;
+
+       private IInformationPresenter fStructurePresenter;
+
+       // private IInformationPresenter fHierarchyPresenter;
+
+       /**
+        * This viewer's foreground color.
+        * 
+        * @since 3.0
+        */
+       private Color fForegroundColor;
+
+       /**
+        * The viewer's background color.
+        * 
+        * @since 3.0
+        */
+       private Color fBackgroundColor;
+
+       /**
+        * This viewer's selection foreground color.
+        * 
+        * @since 3.0
+        */
+       private Color fSelectionForegroundColor;
+
+       /**
+        * The viewer's selection background color.
+        * 
+        * @since 3.0
+        */
+       private Color fSelectionBackgroundColor;
+
+       /**
+        * The preference store.
+        * 
+        * @since 3.0
+        */
+       private IPreferenceStore fPreferenceStore;
+
+       /**
+        * Is this source viewer configured?
+        * 
+        * @since 3.0
+        */
+       private boolean fIsConfigured;
+
+       /**
+        * The backspace manager of this viewer.
+        * 
+        * @since 3.0
+        */
+       private SmartBackspaceManager fBackspaceManager;
+
+       public JavaSourceViewer(Composite parent, IVerticalRuler verticalRuler,
+                       IOverviewRuler overviewRuler, boolean showAnnotationsOverview,
+                       int styles, IPreferenceStore store) {
+               super(parent, verticalRuler, overviewRuler, showAnnotationsOverview,
+                               styles);
+               setPreferenceStore(store);
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewer#createFormattingContext()
+        * @since 3.0
+        */
+       // public IFormattingContext createFormattingContext() {
+       //
+       // IFormattingContext context= new CommentFormattingContext();
+       // Map map= new Hashtable(JavaCore.getOptions());
+       //              
+       // context.storeToMap(PreferenceConstants.getPreferenceStore(), map, false);
+       // context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES,
+       // map);
+       //              
+       // return context;
+       // }
+       /*
+        * @see ITextOperationTarget#doOperation(int)
+        */
+       public void doOperation(int operation) {
+               if (getTextWidget() == null)
+                       return;
+
+               switch (operation) {
+               case SHOW_OUTLINE:
+                       fOutlinePresenter.showInformation();
+                       return;
+               case OPEN_STRUCTURE:
+                       fStructurePresenter.showInformation();
+                       return;
+               case SHOW_HIERARCHY:
+                       // fHierarchyPresenter.showInformation();
+                       return;
+               case FORMAT:
+                       Point point = getSelectedRange();
+                       if (point.y == 0) {
+                               // setSelectedRange(0, getDocument().getLength());
+                               revealRange(0, getDocument().getLength());
+                       }
+                       break;
+               }
+
+               super.doOperation(operation);
+       }
+
+       /*
+        * @see ITextOperationTarget#canDoOperation(int)
+        */
+       public boolean canDoOperation(int operation) {
+               if (operation == SHOW_OUTLINE)
+                       return fOutlinePresenter != null;
+               if (operation == OPEN_STRUCTURE)
+                       return fStructurePresenter != null;
+               if (operation == SHOW_HIERARCHY)
+                       // return fHierarchyPresenter != null;
+                       return false;
+
+               return super.canDoOperation(operation);
+       }
+
+       /*
+        * @see ISourceViewer#configure(SourceViewerConfiguration)
+        */
+       public void configure(SourceViewerConfiguration configuration) {
+               super.configure(configuration);
+               if (configuration instanceof PHPSourceViewerConfiguration) {
+                       fOutlinePresenter = ((PHPSourceViewerConfiguration) configuration)
+                                       .getOutlinePresenter(this, false);
+                       fOutlinePresenter.install(this);
+               }
+               if (configuration instanceof PHPSourceViewerConfiguration) {
+                       fStructurePresenter = ((PHPSourceViewerConfiguration) configuration)
+                                       .getOutlinePresenter(this, true);
+                       fStructurePresenter.install(this);
+               }
+               if (configuration instanceof PHPSourceViewerConfiguration) {
+                       // fHierarchyPresenter=
+                       // ((PHPSourceViewerConfiguration)configuration).getHierarchyPresenter(this,
+                       // true);
+                       // fHierarchyPresenter.install(this);
+
+                       if (fPreferenceStore != null) {
+                               fPreferenceStore.addPropertyChangeListener(this);
+                               initializeViewerColors();
+                       }
+               }
+               fIsConfigured = true;
+       }
+
+       protected void initializeViewerColors() {
+               if (fPreferenceStore != null) {
+
+                       StyledText styledText = getTextWidget();
+
+                       // ----------- foreground color --------------------
+                       Color color = fPreferenceStore
+                                       .getBoolean(PreferenceConstants.EDITOR_FOREGROUND_DEFAULT_COLOR) ? null
+                                       : createColor(fPreferenceStore,
+                                                       PreferenceConstants.EDITOR_FOREGROUND_COLOR,
+                                                       styledText.getDisplay());
+                       styledText.setForeground(color);
+
+                       if (fForegroundColor != null)
+                               fForegroundColor.dispose();
+
+                       fForegroundColor = color;
+
+                       // ---------- background color ----------------------
+                       color = fPreferenceStore
+                                       .getBoolean(PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR) ? null
+                                       : createColor(fPreferenceStore,
+                                                       PreferenceConstants.EDITOR_BACKGROUND_COLOR,
+                                                       styledText.getDisplay());
+                       styledText.setBackground(color);
+
+                       if (fBackgroundColor != null)
+                               fBackgroundColor.dispose();
+
+                       fBackgroundColor = color;
+
+                       // ----------- selection foreground color --------------------
+                       color = fPreferenceStore
+                                       .getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR) ? null
+                                       : createColor(
+                                                       fPreferenceStore,
+                                                       AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR,
+                                                       styledText.getDisplay());
+                       styledText.setSelectionForeground(color);
+
+                       if (fSelectionForegroundColor != null)
+                               fSelectionForegroundColor.dispose();
+
+                       fSelectionForegroundColor = color;
+
+                       // ---------- selection background color ----------------------
+                       color = fPreferenceStore
+                                       .getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR) ? null
+                                       : createColor(
+                                                       fPreferenceStore,
+                                                       AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR,
+                                                       styledText.getDisplay());
+                       styledText.setSelectionBackground(color);
+
+                       if (fSelectionBackgroundColor != null)
+                               fSelectionBackgroundColor.dispose();
+
+                       fSelectionBackgroundColor = color;
+               }
+       }
+
+       /**
+        * Creates a color from the information stored in the given preference
+        * store. Returns <code>null</code> if there is no such information
+        * available.
+        * 
+        * @param store
+        *            the store to read from
+        * @param key
+        *            the key used for the lookup in the preference store
+        * @param display
+        *            the display used create the color
+        * @return the created color according to the specification in the
+        *         preference store
+        * @since 3.0
+        */
+       private Color createColor(IPreferenceStore store, String key,
+                       Display display) {
+
+               RGB rgb = null;
+
+               if (store.contains(key)) {
+
+                       if (store.isDefault(key))
+                               rgb = PreferenceConverter.getDefaultColor(store, key);
+                       else
+                               rgb = PreferenceConverter.getColor(store, key);
+
+                       if (rgb != null)
+                               return new Color(display, rgb);
+               }
+
+               return null;
+       }
+
+       /*
+        * @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;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewer#rememberSelection()
+        */
+       public Point rememberSelection() {
+               return super.rememberSelection();
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewer#restoreSelection()
+        */
+       public void restoreSelection() {
+               super.restoreSelection();
+       }
+
+       /*
+        * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+        */
+       public void propertyChange(PropertyChangeEvent event) {
+               String property = event.getProperty();
+               if (PreferenceConstants.EDITOR_FOREGROUND_COLOR.equals(property)
+                               || PreferenceConstants.EDITOR_FOREGROUND_DEFAULT_COLOR
+                                               .equals(property)
+                               || PreferenceConstants.EDITOR_BACKGROUND_COLOR.equals(property)
+                               || PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR
+                                               .equals(property)
+                               || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR
+                                               .equals(property)
+                               || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR
+                                               .equals(property)
+                               || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR
+                                               .equals(property)
+                               || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR
+                                               .equals(property)) {
+                       initializeViewerColors();
+               }
+       }
+
+       /**
+        * Sets the preference store on this viewer.
+        * 
+        * @param store
+        *            the preference store
+        * 
+        * @since 3.0
+        */
+       public void setPreferenceStore(IPreferenceStore store) {
+               if (fIsConfigured && fPreferenceStore != null)
+                       fPreferenceStore.removePropertyChangeListener(this);
+
+               fPreferenceStore = store;
+
+               if (fIsConfigured && fPreferenceStore != null) {
+                       fPreferenceStore.addPropertyChangeListener(this);
+                       initializeViewerColors();
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewer#createControl(org.eclipse.swt.widgets.Composite,
+        *      int)
+        */
+       protected void createControl(Composite parent, int styles) {
+               super.createControl(parent, styles);
+
+               fBackspaceManager = new SmartBackspaceManager();
+               fBackspaceManager.install(this);
+       }
+
+       /**
+        * Returns the backspace manager for this viewer.
+        * 
+        * @return the backspace manager for this viewer, or <code>null</code> if
+        *         there is none
+        * @since 3.0
+        */
+       public SmartBackspaceManager getBackspaceManager() {
+               return fBackspaceManager;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewer#handleDispose()
+        */
+       protected void handleDispose() {
+               if (fBackspaceManager != null) {
+                       fBackspaceManager.uninstall();
+                       fBackspaceManager = null;
+               }
+
+               super.handleDispose();
+       }
+
+       /**
+        * Prepends the text presentation listener at the beginning of the viewer's
+        * list of text presentation listeners. If the listener is already
+        * registered with the viewer this call moves the listener to the beginning
+        * of the list.
+        * 
+        * @param listener
+        *            the text presentation listener
+        * @since 3.0
+        */
+       public void prependTextPresentationListener(
+                       ITextPresentationListener listener) {
+
+               Assert.isNotNull(listener);
+
+               if (fTextPresentationListeners == null)
+                       fTextPresentationListeners = new ArrayList();
+
+               fTextPresentationListeners.remove(listener);
+               fTextPresentationListeners.add(0, listener);
+       }
+
+       /**
+        * Sets the given reconciler.
+        * 
+        * @param reconciler
+        *            the reconciler
+        * @since 3.0
+        */
+       void setReconciler(IReconciler reconciler) {
+               fReconciler = reconciler;
+       }
+
+       /**
+        * Returns the reconciler.
+        * 
+        * @return the reconciler or <code>null</code> if not set
+        * @since 3.0
+        */
+       Object getReconciler() {
+               return fReconciler;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaStorageDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/JavaStorageDocumentProvider.java
new file mode 100644 (file)
index 0000000..350afb8
--- /dev/null
@@ -0,0 +1,47 @@
+/**********************************************************************
+ Copyright (c) 2000, 2003 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.editors.text.StorageDocumentProvider;
+
+/**
+ * @since 3.0
+ */
+public class JavaStorageDocumentProvider extends StorageDocumentProvider {
+
+       public JavaStorageDocumentProvider() {
+               super();
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.StorageDocumentProvider#setupDocument(java.lang.Object,
+        *      org.eclipse.jface.text.IDocument)
+        */
+       protected void setupDocument(Object element, IDocument document) {
+
+               if (document != null) {
+                       JavaTextTools tools = WebUI.getDefault()
+                                       .getJavaTextTools();
+                       tools.setupJavaDocumentPartitioner(document,
+                                       IPHPPartitions.PHP_PARTITIONING);
+
+                       // tools.setupJavaDocumentPartitioner(document,
+                       // IDocument.DEFAULT_CONTENT_TYPE, element); //IPHPPartitions.HTML,
+                       // element);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/LinePainter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/LinePainter.java
new file mode 100644 (file)
index 0000000..b0f7533
--- /dev/null
@@ -0,0 +1,187 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.custom.LineBackgroundEvent;
+import org.eclipse.swt.custom.LineBackgroundListener;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+
+public class LinePainter implements IPainter, LineBackgroundListener {
+
+       private final ISourceViewer fViewer;
+
+       private Color fHighlightColor;
+
+       private IPositionManager fPositionManager;
+
+       // positions to keep track of beginning and end of line to be painted or
+       // cleared
+       private Position fCurrentLine = new Position(0, 0);
+
+       private Position fLastLine = new Position(0, 0);
+
+       // used to keep track of the last line painted
+       private int fLastLineNumber = -1;
+
+       private boolean fIsActive;
+
+       public LinePainter(ISourceViewer sourceViewer) {
+               fViewer = sourceViewer;
+       }
+
+       public void setHighlightColor(Color highlightColor) {
+               fHighlightColor = highlightColor;
+       }
+
+       /*
+        * @see LineBackgroundListener#lineGetBackground(LineBackgroundEvent)
+        */
+       public void lineGetBackground(LineBackgroundEvent event) {
+               // don't use cached line information because of asynch painting
+
+               StyledText textWidget = fViewer.getTextWidget();
+               if (textWidget != null) {
+
+                       int caret = textWidget.getCaretOffset();
+                       int length = event.lineText.length();
+
+                       if (event.lineOffset <= caret && caret <= event.lineOffset + length)
+                               event.lineBackground = fHighlightColor;
+                       else
+                               event.lineBackground = textWidget.getBackground();
+               }
+       }
+
+       private boolean updateHighlightLine() {
+               try {
+
+                       IDocument document = fViewer.getDocument();
+
+                       int offset = fViewer.getTextWidget().getCaretOffset()
+                                       + fViewer.getVisibleRegion().getOffset();
+                       int lineNumber = document.getLineOfOffset(offset);
+
+                       // redraw if the current line number is different from the last line
+                       // number we painted
+                       // initially fLastLineNumber is -1
+                       if (lineNumber != fLastLineNumber) {
+
+                               fLastLine.offset = fCurrentLine.offset;
+                               fLastLine.length = fCurrentLine.length;
+                               fLastLine.isDeleted = fCurrentLine.isDeleted;
+
+                               fCurrentLine.isDeleted = false;
+                               fCurrentLine.offset = document.getLineOffset(lineNumber);
+                               if (lineNumber == document.getNumberOfLines() - 1)
+                                       fCurrentLine.length = document.getLength()
+                                                       - fCurrentLine.offset;
+                               else
+                                       fCurrentLine.length = document
+                                                       .getLineOffset(lineNumber + 1)
+                                                       - fCurrentLine.offset;
+
+                               fLastLineNumber = lineNumber;
+                               return true;
+
+                       }
+
+               } catch (BadLocationException e) {
+               }
+
+               return false;
+       }
+
+       private void drawHighlightLine(Position position, int visibleOffset) {
+               StyledText textWidget = fViewer.getTextWidget();
+
+               // if the position that is about to be drawn was deleted then we can't
+               if (position.isDeleted())
+                       return;
+
+               int delta = position.offset - visibleOffset;
+               if (0 <= delta && delta <= fViewer.getVisibleRegion().getLength()) {
+                       Point upperLeft = textWidget.getLocationAtOffset(delta);
+                       int width = textWidget.getClientArea().width
+                                       + textWidget.getHorizontalPixel();
+                       int height = textWidget.getLineHeight();
+                       textWidget.redraw(upperLeft.x, upperLeft.y, width, height, false);
+               }
+       }
+
+       /*
+        * @see IPainter#deactivate(boolean)
+        */
+       public void deactivate(boolean redraw) {
+               if (fIsActive) {
+                       fIsActive = false;
+
+                       /*
+                        * on turning off the feature one has to paint the currently
+                        * highlighted line with the standard background color
+                        */
+                       if (redraw)
+                               drawHighlightLine(fCurrentLine, fViewer.getVisibleRegion()
+                                               .getOffset());
+
+                       fViewer.getTextWidget().removeLineBackgroundListener(this);
+
+                       if (fPositionManager != null)
+                               fPositionManager.removeManagedPosition(fCurrentLine);
+
+                       fLastLineNumber = -1;
+               }
+       }
+
+       /*
+        * @see IPainter#dispose()
+        */
+       public void dispose() {
+       }
+
+       /*
+        * @see IPainter#paint(int)
+        */
+       public void paint(int reason) {
+
+               // check selection
+               Point selection = fViewer.getTextWidget().getSelectionRange();
+               if (selection.y > 0) {
+                       deactivate(true);
+                       return;
+               }
+
+               // initialization
+               if (!fIsActive) {
+                       fViewer.getTextWidget().addLineBackgroundListener(this);
+                       fPositionManager.addManagedPosition(fCurrentLine);
+                       fIsActive = true;
+               }
+
+               // redraw line highlight only if it hasn't been drawn yet on the
+               // respective line
+               if (updateHighlightLine()) {
+                       // used to handle segmented view of source files
+                       int visibleRegionOffset = fViewer.getVisibleRegion().getOffset();
+                       // clear last line
+                       drawHighlightLine(fLastLine, visibleRegionOffset);
+                       // draw new line
+                       drawHighlightLine(fCurrentLine, visibleRegionOffset);
+               }
+       }
+
+       /*
+        * @see IPainter#setPositionManager(IPositionManager)
+        */
+       public void setPositionManager(IPositionManager manager) {
+               fPositionManager = manager;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPAnnotationHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPAnnotationHover.java
new file mode 100644 (file)
index 0000000..7972adf
--- /dev/null
@@ -0,0 +1,177 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+/**
+ * The PHPAnnotationHover provides the hover support for PHP editors.
+ */
+
+public class PHPAnnotationHover implements IAnnotationHover {
+
+       /*
+        * (non-Javadoc) Method declared on IAnnotationHover
+        */
+       // public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+       // IDocument document= sourceViewer.getDocument();
+       //
+       // try {
+       // IRegion info= document.getLineInformation(lineNumber);
+       // return document.get(info.getOffset(), info.getLength());
+       // } catch (BadLocationException x) {
+       // }
+       //
+       // return null;
+       // }
+       //      
+       static final int MAX_INFO_LENGTH = 80;
+
+       /**
+        * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer,
+        *      int)
+        */
+
+       public String getHoverInfo(ISourceViewer viewer, int line) {
+               String info = null;
+               List markers = getMarkersForLine(viewer, line);
+               if (markers != null) {
+                       info = "";
+                       for (int i = 0; i < markers.size(); i++) {
+                               IMarker marker = (IMarker) markers.get(i);
+                               String message = marker.getAttribute(IMarker.MESSAGE,
+                                               (String) null);
+                               if (message != null && message.trim().length() > 0) {
+
+                                       if (message.length() > MAX_INFO_LENGTH) {
+                                               message = splitMessage(message);
+                                       }
+                                       info += message;
+
+                                       if (i != markers.size() - 1) {
+                                               info += "\n";
+                                       }
+                               }
+                       }
+               }
+               return info;
+       }
+
+       private String splitMessage(String message) {
+               String result = "";
+
+               if (message.length() <= MAX_INFO_LENGTH) {
+                       return message;
+               }
+
+               String tmpStr = new String(message);
+
+               while (tmpStr.length() > MAX_INFO_LENGTH) {
+
+                       int spacepos = tmpStr.indexOf(" ", MAX_INFO_LENGTH);
+
+                       if (spacepos != -1) {
+                               result += tmpStr.substring(0, spacepos) + "\n";
+                               tmpStr = tmpStr.substring(spacepos);
+                       } else {
+                               result += tmpStr.substring(0, MAX_INFO_LENGTH) + "\n";
+                               tmpStr = tmpStr.substring(MAX_INFO_LENGTH);
+                       }
+
+               }
+
+               result += tmpStr;
+
+               return result;
+       }
+
+       /**
+        * Returns all markers which includes the ruler's line of activity.
+        */
+       protected List getMarkersForLine(ISourceViewer aViewer, int aLine) {
+               List markers = new ArrayList();
+               IAnnotationModel model = aViewer.getAnnotationModel();
+               if (model != null) {
+                       Iterator e = model.getAnnotationIterator();
+                       while (e.hasNext()) {
+                               Object o = e.next();
+                               if (o instanceof MarkerAnnotation) {
+                                       MarkerAnnotation a = (MarkerAnnotation) o;
+                                       if (compareRulerLine(model.getPosition(a), aViewer
+                                                       .getDocument(), aLine) != 0) {
+                                               markers.add(a.getMarker());
+                                       }
+                               }
+                       }
+               }
+               return markers;
+       }
+
+       /**
+        * Returns one marker which includes the ruler's line of activity.
+        */
+       protected IMarker getMarkerForLine(ISourceViewer aViewer, int aLine) {
+               IMarker marker = null;
+               IAnnotationModel model = aViewer.getAnnotationModel();
+               if (model != null) {
+                       Iterator e = model.getAnnotationIterator();
+                       while (e.hasNext()) {
+                               Object o = e.next();
+                               if (o instanceof MarkerAnnotation) {
+                                       MarkerAnnotation a = (MarkerAnnotation) o;
+                                       if (compareRulerLine(model.getPosition(a), aViewer
+                                                       .getDocument(), aLine) != 0) {
+                                               marker = a.getMarker();
+                                       }
+                               }
+                       }
+               }
+               return marker;
+       }
+
+       /**
+        * Returns distance of given line to specified position (1 = same line, 2 =
+        * included in given position, 0 = not related).
+        */
+       protected int compareRulerLine(Position aPosition, IDocument aDocument,
+                       int aLine) {
+               int distance = 0;
+               if (aPosition.getOffset() > -1 && aPosition.getLength() > -1) {
+                       try {
+                               int markerLine = aDocument.getLineOfOffset(aPosition
+                                               .getOffset());
+                               if (aLine == markerLine) {
+                                       distance = 1;
+                               } else if (markerLine <= aLine
+                                               && aLine <= aDocument.getLineOfOffset(aPosition
+                                                               .getOffset()
+                                                               + aPosition.getLength())) {
+                                       distance = 2;
+                               }
+                       } catch (BadLocationException e) {
+                       }
+               }
+               return distance;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java
new file mode 100644 (file)
index 0000000..4bd3c76
--- /dev/null
@@ -0,0 +1,1730 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IProblemRequestor;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.java.IProblemRequestorExtension;
+import net.sourceforge.phpdt.internal.ui.text.spelling.SpellReconcileStrategy.SpellProblem;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceRuleFactory;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.ISynchronizable;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+import org.eclipse.jface.text.source.IAnnotationAccessExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelListener;
+import org.eclipse.jface.text.source.IAnnotationModelListenerExtension;
+import org.eclipse.jface.text.source.IAnnotationPresentation;
+import org.eclipse.jface.text.source.ImageUtilities;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.ForwardingDocumentProvider;
+import org.eclipse.ui.editors.text.TextFileDocumentProvider;
+import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.AnnotationPreferenceLookup;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.MarkerUtilities;
+import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
+
+/**
+ * The PHPDocumentProvider provides the IDocuments used by java editors.
+ */
+
+public class PHPDocumentProvider extends TextFileDocumentProvider implements
+               ICompilationUnitDocumentProvider {
+       /**
+        * Here for visibility issues only.
+        */
+
+       /**
+        * Bundle of all required informations to allow working copy management.
+        */
+       /**
+        * Bundle of all required informations to allow working copy management.
+        */
+       static protected class CompilationUnitInfo extends FileInfo {
+               public ICompilationUnit fCopy;
+       }
+
+       /**
+        * Annotation model dealing with java marker annotations and temporary
+        * problems. Also acts as problem requestor for its compilation unit.
+        * Initialiy inactive. Must explicitly be activated.
+        */
+       protected static class CompilationUnitAnnotationModel extends
+                       ResourceMarkerAnnotationModel implements IProblemRequestor,
+                       IProblemRequestorExtension {
+
+               private static class ProblemRequestorState {
+                       boolean fInsideReportingSequence = false;
+
+                       List fReportedProblems;
+               }
+
+               private ThreadLocal fProblemRequestorState = new ThreadLocal();
+
+               private int fStateCount = 0;
+
+               private ICompilationUnit fCompilationUnit;
+
+               private List fGeneratedAnnotations;
+
+               private IProgressMonitor fProgressMonitor;
+
+               private boolean fIsActive = false;
+
+               private ReverseMap fReverseMap = new ReverseMap();
+
+               private List fPreviouslyOverlaid = null;
+
+               private List fCurrentlyOverlaid = new ArrayList();
+
+               public CompilationUnitAnnotationModel(IResource resource) {
+                       super(resource);
+               }
+
+               public void setCompilationUnit(ICompilationUnit unit) {
+                       fCompilationUnit = unit;
+               }
+
+               protected MarkerAnnotation createMarkerAnnotation(IMarker marker) {
+                       String markerType = MarkerUtilities.getMarkerType(marker);
+                       if (markerType != null
+                                       && markerType
+                                                       .startsWith(JavaMarkerAnnotation.JAVA_MARKER_TYPE_PREFIX))
+                               return new JavaMarkerAnnotation(marker);
+                       return super.createMarkerAnnotation(marker);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.AnnotationModel#createAnnotationModelEvent()
+                */
+               protected AnnotationModelEvent createAnnotationModelEvent() {
+                       return new CompilationUnitAnnotationModelEvent(this, getResource());
+               }
+
+               protected Position createPositionFromProblem(IProblem problem) {
+                       int start = problem.getSourceStart();
+                       if (start < 0)
+                               return null;
+
+                       int length = problem.getSourceEnd() - problem.getSourceStart() + 1;
+                       if (length < 0)
+                               return null;
+
+                       return new Position(start, length);
+               }
+
+               /*
+                * @see IProblemRequestor#beginReporting()
+                */
+               public void beginReporting() {
+                       ProblemRequestorState state = (ProblemRequestorState) fProblemRequestorState
+                                       .get();
+                       if (state == null)
+                               internalBeginReporting(false);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.java.IProblemRequestorExtension#beginReportingSequence()
+                */
+               public void beginReportingSequence() {
+                       ProblemRequestorState state = (ProblemRequestorState) fProblemRequestorState
+                                       .get();
+                       if (state == null)
+                               internalBeginReporting(true);
+               }
+
+               /**
+                * Sets up the infrastructure necessary for problem reporting.
+                * 
+                * @param insideReportingSequence
+                *            <code>true</code> if this method call is issued from
+                *            inside a reporting sequence
+                */
+               private void internalBeginReporting(boolean insideReportingSequence) {
+                       if (fCompilationUnit != null) {
+                               // &&
+                               // fCompilationUnit.getJavaProject().isOnClasspath(fCompilationUnit))
+                               // {
+                               ProblemRequestorState state = new ProblemRequestorState();
+                               state.fInsideReportingSequence = insideReportingSequence;
+                               state.fReportedProblems = new ArrayList();
+                               synchronized (getLockObject()) {
+                                       fProblemRequestorState.set(state);
+                                       ++fStateCount;
+                               }
+                       }
+               }
+
+               /*
+                * @see IProblemRequestor#acceptProblem(IProblem)
+                */
+               public void acceptProblem(IProblem problem) {
+                       if (isActive()) {
+                               ProblemRequestorState state = (ProblemRequestorState) fProblemRequestorState
+                                               .get();
+                               if (state != null)
+                                       state.fReportedProblems.add(problem);
+                       }
+               }
+
+               /*
+                * @see IProblemRequestor#endReporting()
+                */
+               public void endReporting() {
+                       ProblemRequestorState state = (ProblemRequestorState) fProblemRequestorState
+                                       .get();
+                       if (state != null && !state.fInsideReportingSequence)
+                               internalEndReporting(state);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.text.java.IProblemRequestorExtension#endReportingSequence()
+                */
+               public void endReportingSequence() {
+                       ProblemRequestorState state = (ProblemRequestorState) fProblemRequestorState
+                                       .get();
+                       if (state != null && state.fInsideReportingSequence)
+                               internalEndReporting(state);
+               }
+
+               private void internalEndReporting(ProblemRequestorState state) {
+                       int stateCount = 0;
+                       synchronized (getLockObject()) {
+                               --fStateCount;
+                               stateCount = fStateCount;
+                               fProblemRequestorState.set(null);
+                       }
+
+                       if (stateCount == 0 && isActive())
+                               reportProblems(state.fReportedProblems);
+               }
+
+               /**
+                * Signals the end of problem reporting.
+                */
+               private void reportProblems(List reportedProblems) {
+                       if (fProgressMonitor != null && fProgressMonitor.isCanceled())
+                               return;
+
+                       boolean temporaryProblemsChanged = false;
+
+                       synchronized (getLockObject()) {
+
+                               boolean isCanceled = false;
+
+                               fPreviouslyOverlaid = fCurrentlyOverlaid;
+                               fCurrentlyOverlaid = new ArrayList();
+
+                               if (fGeneratedAnnotations.size() > 0) {
+                                       temporaryProblemsChanged = true;
+                                       removeAnnotations(fGeneratedAnnotations, false, true);
+                                       fGeneratedAnnotations.clear();
+                               }
+
+                               if (reportedProblems != null && reportedProblems.size() > 0) {
+
+                                       Iterator e = reportedProblems.iterator();
+                                       while (e.hasNext()) {
+
+                                               if (fProgressMonitor != null
+                                                               && fProgressMonitor.isCanceled()) {
+                                                       isCanceled = true;
+                                                       break;
+                                               }
+
+                                               IProblem problem = (IProblem) e.next();
+                                               Position position = createPositionFromProblem(problem);
+                                               if (position != null) {
+
+                                                       try {
+                                                               ProblemAnnotation annotation = new ProblemAnnotation(
+                                                                               problem, fCompilationUnit);
+                                                               overlayMarkers(position, annotation);
+                                                               addAnnotation(annotation, position, false);
+                                                               fGeneratedAnnotations.add(annotation);
+
+                                                               temporaryProblemsChanged = true;
+                                                       } catch (BadLocationException x) {
+                                                               // ignore invalid position
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               removeMarkerOverlays(isCanceled);
+                               fPreviouslyOverlaid = null;
+                       }
+
+                       if (temporaryProblemsChanged)
+                               fireModelChanged();
+               }
+
+               private void removeMarkerOverlays(boolean isCanceled) {
+                       if (isCanceled) {
+                               fCurrentlyOverlaid.addAll(fPreviouslyOverlaid);
+                       } else if (fPreviouslyOverlaid != null) {
+                               Iterator e = fPreviouslyOverlaid.iterator();
+                               while (e.hasNext()) {
+                                       JavaMarkerAnnotation annotation = (JavaMarkerAnnotation) e
+                                                       .next();
+                                       annotation.setOverlay(null);
+                               }
+                       }
+               }
+
+               /**
+                * Overlays value with problem annotation.
+                * 
+                * @param problemAnnotation
+                */
+               private void setOverlay(Object value,
+                               ProblemAnnotation problemAnnotation) {
+                       if (value instanceof JavaMarkerAnnotation) {
+                               JavaMarkerAnnotation annotation = (JavaMarkerAnnotation) value;
+                               if (annotation.isProblem()) {
+                                       annotation.setOverlay(problemAnnotation);
+                                       fPreviouslyOverlaid.remove(annotation);
+                                       fCurrentlyOverlaid.add(annotation);
+                               }
+                       } else {
+                       }
+               }
+
+               private void overlayMarkers(Position position,
+                               ProblemAnnotation problemAnnotation) {
+                       Object value = getAnnotations(position);
+                       if (value instanceof List) {
+                               List list = (List) value;
+                               for (Iterator e = list.iterator(); e.hasNext();)
+                                       setOverlay(e.next(), problemAnnotation);
+                       } else {
+                               setOverlay(value, problemAnnotation);
+                       }
+               }
+
+               /**
+                * Tells this annotation model to collect temporary problems from now
+                * on.
+                */
+               private void startCollectingProblems() {
+                       fGeneratedAnnotations = new ArrayList();
+               }
+
+               /**
+                * Tells this annotation model to no longer collect temporary problems.
+                */
+               private void stopCollectingProblems() {
+                       if (fGeneratedAnnotations != null)
+                               removeAnnotations(fGeneratedAnnotations, true, true);
+                       fGeneratedAnnotations = null;
+               }
+
+               /*
+                * @see IProblemRequestor#isActive()
+                */
+               public boolean isActive() {
+                       return fIsActive;
+               }
+
+               /*
+                * @see IProblemRequestorExtension#setProgressMonitor(IProgressMonitor)
+                */
+               public void setProgressMonitor(IProgressMonitor monitor) {
+                       fProgressMonitor = monitor;
+               }
+
+               /*
+                * @see IProblemRequestorExtension#setIsActive(boolean)
+                */
+               public void setIsActive(boolean isActive) {
+                       if (fIsActive != isActive) {
+                               fIsActive = isActive;
+                               if (fIsActive)
+                                       startCollectingProblems();
+                               else
+                                       stopCollectingProblems();
+                       }
+               }
+
+               private Object getAnnotations(Position position) {
+                       return fReverseMap.get(position);
+               }
+
+               /*
+                * @see AnnotationModel#addAnnotation(Annotation, Position, boolean)
+                */
+               protected void addAnnotation(Annotation annotation, Position position,
+                               boolean fireModelChanged) throws BadLocationException {
+                       super.addAnnotation(annotation, position, fireModelChanged);
+
+                       Object cached = fReverseMap.get(position);
+                       if (cached == null)
+                               fReverseMap.put(position, annotation);
+                       else if (cached instanceof List) {
+                               List list = (List) cached;
+                               list.add(annotation);
+                       } else if (cached instanceof Annotation) {
+                               List list = new ArrayList(2);
+                               list.add(cached);
+                               list.add(annotation);
+                               fReverseMap.put(position, list);
+                       }
+               }
+
+               /*
+                * @see AnnotationModel#removeAllAnnotations(boolean)
+                */
+               protected void removeAllAnnotations(boolean fireModelChanged) {
+                       super.removeAllAnnotations(fireModelChanged);
+                       fReverseMap.clear();
+               }
+
+               /*
+                * @see AnnotationModel#removeAnnotation(Annotation, boolean)
+                */
+               protected void removeAnnotation(Annotation annotation,
+                               boolean fireModelChanged) {
+                       Position position = getPosition(annotation);
+                       Object cached = fReverseMap.get(position);
+                       if (cached instanceof List) {
+                               List list = (List) cached;
+                               list.remove(annotation);
+                               if (list.size() == 1) {
+                                       fReverseMap.put(position, list.get(0));
+                                       list.clear();
+                               }
+                       } else if (cached instanceof Annotation) {
+                               fReverseMap.remove(position);
+                       }
+                       super.removeAnnotation(annotation, fireModelChanged);
+               }
+       }
+
+       protected static class GlobalAnnotationModelListener implements
+                       IAnnotationModelListener, IAnnotationModelListenerExtension {
+
+               private ListenerList fListenerList;
+
+               public GlobalAnnotationModelListener() {
+                       fListenerList = new ListenerList();
+               }
+
+               public void addListener(IAnnotationModelListener listener) {
+                       fListenerList.add(listener);
+               }
+
+               /**
+                * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent)
+                */
+               public void modelChanged(AnnotationModelEvent event) {
+                       Object[] listeners = fListenerList.getListeners();
+                       for (int i = 0; i < listeners.length; i++) {
+                               Object curr = listeners[i];
+                               if (curr instanceof IAnnotationModelListenerExtension) {
+                                       ((IAnnotationModelListenerExtension) curr)
+                                                       .modelChanged(event);
+                               }
+                       }
+               }
+
+               /**
+                * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+                */
+               public void modelChanged(IAnnotationModel model) {
+                       Object[] listeners = fListenerList.getListeners();
+                       for (int i = 0; i < listeners.length; i++) {
+                               ((IAnnotationModelListener) listeners[i]).modelChanged(model);
+                       }
+               }
+
+               public void removeListener(IAnnotationModelListener listener) {
+                       fListenerList.remove(listener);
+               }
+       }
+
+       /**
+        * Annotation representating an <code>IProblem</code>.
+        */
+       static public class ProblemAnnotation extends Annotation implements
+                       IJavaAnnotation, IAnnotationPresentation {
+
+               private static final String SPELLING_ANNOTATION_TYPE = "org.eclipse.ui.workbench.texteditor.spelling";
+
+               // XXX: To be fully correct these constants should be non-static
+               /**
+                * The layer in which task problem annotations are located.
+                */
+               private static final int TASK_LAYER;
+
+               /**
+                * The layer in which info problem annotations are located.
+                */
+               private static final int INFO_LAYER;
+
+               /**
+                * The layer in which warning problem annotations representing are
+                * located.
+                */
+               private static final int WARNING_LAYER;
+
+               /**
+                * The layer in which error problem annotations representing are
+                * located.
+                */
+               private static final int ERROR_LAYER;
+
+               static {
+                       AnnotationPreferenceLookup lookup = EditorsUI
+                                       .getAnnotationPreferenceLookup();
+                       TASK_LAYER = computeLayer(
+                                       "org.eclipse.ui.workbench.texteditor.task", lookup); //$NON-NLS-1$
+                       INFO_LAYER = computeLayer("net.sourceforge.phpdt.ui.info", lookup); //$NON-NLS-1$
+                       WARNING_LAYER = computeLayer(
+                                       "net.sourceforge.phpdt.ui.warning", lookup); //$NON-NLS-1$
+                       ERROR_LAYER = computeLayer("net.sourceforge.phpdt.ui.error", lookup); //$NON-NLS-1$
+               }
+
+               private static int computeLayer(String annotationType,
+                               AnnotationPreferenceLookup lookup) {
+                       Annotation annotation = new Annotation(annotationType, false, null);
+                       AnnotationPreference preference = lookup
+                                       .getAnnotationPreference(annotation);
+                       if (preference != null)
+                               return preference.getPresentationLayer() + 1;
+                       else
+                               return IAnnotationAccessExtension.DEFAULT_LAYER + 1;
+               }
+
+               // private static Image fgQuickFixImage;
+               // private static Image fgQuickFixErrorImage;
+               // private static boolean fgQuickFixImagesInitialized= false;
+
+               private ICompilationUnit fCompilationUnit;
+
+               private List fOverlaids;
+
+               private IProblem fProblem;
+
+               private Image fImage;
+
+               private boolean fQuickFixImagesInitialized = false;
+
+               private int fLayer = IAnnotationAccessExtension.DEFAULT_LAYER;
+
+               public ProblemAnnotation(IProblem problem, ICompilationUnit cu) {
+
+                       fProblem = problem;
+                       fCompilationUnit = cu;
+
+                       if (SpellProblem.Spelling == fProblem.getID()) {
+                               setType(SPELLING_ANNOTATION_TYPE);
+                               fLayer = WARNING_LAYER;
+                       } else if (IProblem.Task == fProblem.getID()) {
+                               setType(JavaMarkerAnnotation.TASK_ANNOTATION_TYPE);
+                               fLayer = TASK_LAYER;
+                       } else if (fProblem.isWarning()) {
+                               setType(JavaMarkerAnnotation.WARNING_ANNOTATION_TYPE);
+                               fLayer = WARNING_LAYER;
+                       } else if (fProblem.isError()) {
+                               setType(JavaMarkerAnnotation.ERROR_ANNOTATION_TYPE);
+                               fLayer = ERROR_LAYER;
+                       } else {
+                               setType(JavaMarkerAnnotation.INFO_ANNOTATION_TYPE);
+                               fLayer = INFO_LAYER;
+                       }
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer()
+                */
+               public int getLayer() {
+                       return fLayer;
+               }
+
+               private void initializeImages() {
+                       // http://bugs.eclipse.org/bugs/show_bug.cgi?id=18936
+                       // if (!fQuickFixImagesInitialized) {
+                       // if (isProblem() && indicateQuixFixableProblems() &&
+                       // JavaCorrectionProcessor.hasCorrections(this)) { // no light bulb
+                       // for tasks
+                       // if (!fgQuickFixImagesInitialized) {
+                       // fgQuickFixImage=
+                       // JavaPluginImages.get(JavaPluginImages.IMG_OBJS_FIXABLE_PROBLEM);
+                       // fgQuickFixErrorImage=
+                       // JavaPluginImages.get(JavaPluginImages.IMG_OBJS_FIXABLE_ERROR);
+                       // fgQuickFixImagesInitialized= true;
+                       // }
+                       // if (JavaMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(getType()))
+                       // fImage= fgQuickFixErrorImage;
+                       // else
+                       // fImage= fgQuickFixImage;
+                       // }
+                       // fQuickFixImagesInitialized= true;
+                       // }
+               }
+
+               private boolean indicateQuixFixableProblems() {
+                       return PreferenceConstants.getPreferenceStore().getBoolean(
+                                       PreferenceConstants.EDITOR_CORRECTION_INDICATION);
+               }
+
+               /*
+                * @see Annotation#paint
+                */
+               public void paint(GC gc, Canvas canvas, Rectangle r) {
+                       initializeImages();
+                       if (fImage != null)
+                               ImageUtilities.drawImage(fImage, gc, canvas, r, SWT.CENTER,
+                                               SWT.TOP);
+               }
+
+               /*
+                * @see IJavaAnnotation#getImage(Display)
+                */
+               public Image getImage(Display display) {
+                       initializeImages();
+                       return fImage;
+               }
+
+               /*
+                * @see IJavaAnnotation#getMessage()
+                */
+               public String getText() {
+                       return fProblem.getMessage();
+               }
+
+               /*
+                * @see IJavaAnnotation#getArguments()
+                */
+               public String[] getArguments() {
+                       return isProblem() ? fProblem.getArguments() : null;
+               }
+
+               /*
+                * @see IJavaAnnotation#getId()
+                */
+               public int getId() {
+                       return fProblem.getID();
+               }
+
+               /*
+                * @see IJavaAnnotation#isProblem()
+                */
+               public boolean isProblem() {
+                       String type = getType();
+                       return JavaMarkerAnnotation.WARNING_ANNOTATION_TYPE.equals(type)
+                                       || JavaMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(type)
+                                       || SPELLING_ANNOTATION_TYPE.equals(type);
+               }
+
+               /*
+                * @see IJavaAnnotation#hasOverlay()
+                */
+               public boolean hasOverlay() {
+                       return false;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.IJavaAnnotation#getOverlay()
+                */
+               public IJavaAnnotation getOverlay() {
+                       return null;
+               }
+
+               /*
+                * @see IJavaAnnotation#addOverlaid(IJavaAnnotation)
+                */
+               public void addOverlaid(IJavaAnnotation annotation) {
+                       if (fOverlaids == null)
+                               fOverlaids = new ArrayList(1);
+                       fOverlaids.add(annotation);
+               }
+
+               /*
+                * @see IJavaAnnotation#removeOverlaid(IJavaAnnotation)
+                */
+               public void removeOverlaid(IJavaAnnotation annotation) {
+                       if (fOverlaids != null) {
+                               fOverlaids.remove(annotation);
+                               if (fOverlaids.size() == 0)
+                                       fOverlaids = null;
+                       }
+               }
+
+               /*
+                * @see IJavaAnnotation#getOverlaidIterator()
+                */
+               public Iterator getOverlaidIterator() {
+                       if (fOverlaids != null)
+                               return fOverlaids.iterator();
+                       return null;
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.IJavaAnnotation#getCompilationUnit()
+                */
+               public ICompilationUnit getCompilationUnit() {
+                       return fCompilationUnit;
+               }
+       }
+
+       /**
+        * Internal structure for mapping positions to some value. The reason for
+        * this specific structure is that positions can change over time. Thus a
+        * lookup is based on value and not on hash value.
+        */
+       protected static class ReverseMap {
+
+               static class Entry {
+                       Position fPosition;
+
+                       Object fValue;
+               }
+
+               private int fAnchor = 0;
+
+               private List fList = new ArrayList(2);
+
+               public ReverseMap() {
+               }
+
+               public void clear() {
+                       fList.clear();
+               }
+
+               public Object get(Position position) {
+
+                       Entry entry;
+
+                       // behind anchor
+                       int length = fList.size();
+                       for (int i = fAnchor; i < length; i++) {
+                               entry = (Entry) fList.get(i);
+                               if (entry.fPosition.equals(position)) {
+                                       fAnchor = i;
+                                       return entry.fValue;
+                               }
+                       }
+
+                       // before anchor
+                       for (int i = 0; i < fAnchor; i++) {
+                               entry = (Entry) fList.get(i);
+                               if (entry.fPosition.equals(position)) {
+                                       fAnchor = i;
+                                       return entry.fValue;
+                               }
+                       }
+
+                       return null;
+               }
+
+               private int getIndex(Position position) {
+                       Entry entry;
+                       int length = fList.size();
+                       for (int i = 0; i < length; i++) {
+                               entry = (Entry) fList.get(i);
+                               if (entry.fPosition.equals(position))
+                                       return i;
+                       }
+                       return -1;
+               }
+
+               public void put(Position position, Object value) {
+                       int index = getIndex(position);
+                       if (index == -1) {
+                               Entry entry = new Entry();
+                               entry.fPosition = position;
+                               entry.fValue = value;
+                               fList.add(entry);
+                       } else {
+                               Entry entry = (Entry) fList.get(index);
+                               entry.fValue = value;
+                       }
+               }
+
+               public void remove(Position position) {
+                       int index = getIndex(position);
+                       if (index > -1)
+                               fList.remove(index);
+               }
+       }
+
+       /**
+        * Document that can also be used by a background reconciler.
+        */
+       protected static class PartiallySynchronizedDocument extends Document {
+
+               /*
+                * @see IDocumentExtension#startSequentialRewrite(boolean)
+                */
+               synchronized public void startSequentialRewrite(boolean normalized) {
+                       super.startSequentialRewrite(normalized);
+               }
+
+               /*
+                * @see IDocumentExtension#stopSequentialRewrite()
+                */
+               synchronized public void stopSequentialRewrite() {
+                       super.stopSequentialRewrite();
+               }
+
+               /*
+                * @see IDocument#get()
+                */
+               synchronized public String get() {
+                       return super.get();
+               }
+
+               /*
+                * @see IDocument#get(int, int)
+                */
+               synchronized public String get(int offset, int length)
+                               throws BadLocationException {
+                       return super.get(offset, length);
+               }
+
+               /*
+                * @see IDocument#getChar(int)
+                */
+               synchronized public char getChar(int offset)
+                               throws BadLocationException {
+                       return super.getChar(offset);
+               }
+
+               /*
+                * @see IDocument#replace(int, int, String)
+                */
+               synchronized public void replace(int offset, int length, String text)
+                               throws BadLocationException {
+                       super.replace(offset, length, text);
+               }
+
+               /*
+                * @see IDocument#set(String)
+                */
+               synchronized public void set(String text) {
+                       super.set(text);
+               }
+       };
+
+       //
+       // private static PHPPartitionScanner HTML_PARTITION_SCANNER = null;
+       //
+       // private static PHPPartitionScanner PHP_PARTITION_SCANNER = null;
+       // private static PHPPartitionScanner SMARTY_PARTITION_SCANNER = null;
+       //
+       // // private final static String[] TYPES= new String[] {
+       // PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC,
+       // PHPPartitionScanner.JAVA_MULTILINE_COMMENT };
+       // private final static String[] TYPES =
+       // new String[] {
+       // IPHPPartitionScannerConstants.PHP,
+       // IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT,
+       // IPHPPartitionScannerConstants.HTML,
+       // IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT,
+       // IPHPPartitionScannerConstants.JAVASCRIPT,
+       // IPHPPartitionScannerConstants.CSS,
+       // IPHPPartitionScannerConstants.SMARTY,
+       // IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT };
+       // private static PHPPartitionScanner XML_PARTITION_SCANNER = null;
+
+       /* Preference key for temporary problems */
+       private final static String HANDLE_TEMPORARY_PROBLEMS = PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS;
+
+       /** Indicates whether the save has been initialized by this provider */
+       private boolean fIsAboutToSave = false;
+
+       /** The save policy used by this provider */
+       private ISavePolicy fSavePolicy;
+
+       /** Internal property changed listener */
+       private IPropertyChangeListener fPropertyListener;
+
+       /** annotation model listener added to all created CU annotation models */
+       private GlobalAnnotationModelListener fGlobalAnnotationModelListener;
+
+       public PHPDocumentProvider() {
+               // IDocumentProvider provider= new TextFileDocumentProvider(new
+               // JavaStorageDocumentProvider());
+               IDocumentProvider provider = new TextFileDocumentProvider();
+               provider = new ForwardingDocumentProvider(
+                               IPHPPartitions.PHP_PARTITIONING,
+                               new JavaDocumentSetupParticipant(), provider);
+               setParentDocumentProvider(provider);
+
+               fGlobalAnnotationModelListener = new GlobalAnnotationModelListener();
+               fPropertyListener = new IPropertyChangeListener() {
+                       public void propertyChange(PropertyChangeEvent event) {
+                               if (HANDLE_TEMPORARY_PROBLEMS.equals(event.getProperty()))
+                                       enableHandlingTemporaryProblems();
+                       }
+               };
+               WebUI.getDefault().getPreferenceStore()
+                               .addPropertyChangeListener(fPropertyListener);
+
+       }
+
+       /**
+        * Sets the document provider's save policy.
+        */
+       public void setSavePolicy(ISavePolicy savePolicy) {
+               fSavePolicy = savePolicy;
+       }
+
+       /**
+        * Creates a compilation unit from the given file.
+        * 
+        * @param file
+        *            the file from which to create the compilation unit
+        */
+       protected ICompilationUnit createCompilationUnit(IFile file) {
+               Object element = JavaCore.create(file);
+               if (element instanceof ICompilationUnit)
+                       return (ICompilationUnit) element;
+               return null;
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createEmptyFileInfo()
+        */
+       protected FileInfo createEmptyFileInfo() {
+               return new CompilationUnitInfo();
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createAnnotationModel(org.eclipse.core.resources.IFile)
+        */
+       protected IAnnotationModel createAnnotationModel(IFile file) {
+               return new CompilationUnitAnnotationModel(file);
+       }
+
+       /*
+        * @see AbstractDocumentProvider#createElementInfo(Object)
+        */
+       // protected ElementInfo createElementInfo(Object element) throws
+       // CoreException {
+       //
+       // if (!(element instanceof IFileEditorInput))
+       // return super.createElementInfo(element);
+       //
+       // IFileEditorInput input = (IFileEditorInput) element;
+       // ICompilationUnit original = createCompilationUnit(input.getFile());
+       // if (original != null) {
+       //
+       // try {
+       //
+       // try {
+       // refreshFile(input.getFile());
+       // } catch (CoreException x) {
+       // handleCoreException(x,
+       // PHPEditorMessages.getString("PHPDocumentProvider.error.createElementInfo"));
+       // //$NON-NLS-1$
+       // }
+       //
+       // IAnnotationModel m = createCompilationUnitAnnotationModel(input);
+       // IProblemRequestor r = m instanceof IProblemRequestor ?
+       // (IProblemRequestor) m : null;
+       // ICompilationUnit c = (ICompilationUnit)
+       // original.getSharedWorkingCopy(getProgressMonitor(), fBufferFactory, r);
+       //
+       // DocumentAdapter a = null;
+       // try {
+       // a = (DocumentAdapter) c.getBuffer();
+       // } catch (ClassCastException x) {
+       // IStatus status = new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID,
+       // PHPStatusConstants.TEMPLATE_IO_EXCEPTION, "Shared working copy has wrong
+       // buffer", x); //$NON-NLS-1$
+       // throw new CoreException(status);
+       // }
+       //
+       // _FileSynchronizer f = new _FileSynchronizer(input);
+       // f.install();
+       //
+       // CompilationUnitInfo info = new CompilationUnitInfo(a.getDocument(), m, f,
+       // c);
+       // info.setModificationStamp(computeModificationStamp(input.getFile()));
+       // info.fStatus = a.getStatus();
+       // info.fEncoding = getPersistedEncoding(input);
+       //
+       // if (r instanceof IProblemRequestorExtension) {
+       // IProblemRequestorExtension extension = (IProblemRequestorExtension) r;
+       // extension.setIsActive(isHandlingTemporaryProblems());
+       // }
+       // m.addAnnotationModelListener(fGlobalAnnotationModelListener);
+       //
+       // return info;
+       //
+       // } catch (JavaModelException x) {
+       // throw new CoreException(x.getStatus());
+       // }
+       // } else {
+       // return super.createElementInfo(element);
+       // }
+       // }
+       /*
+        * @see AbstractDocumentProvider#disposeElementInfo(Object, ElementInfo)
+        */
+       // protected void disposeElementInfo(Object element, ElementInfo info) {
+       //
+       // if (info instanceof CompilationUnitInfo) {
+       // CompilationUnitInfo cuInfo = (CompilationUnitInfo) info;
+       // cuInfo.fCopy.destroy();
+       // cuInfo.fModel.removeAnnotationModelListener(fGlobalAnnotationModelListener);
+       // }
+       //
+       // super.disposeElementInfo(element, info);
+       // }
+       /*
+        * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object,
+        *      IDocument, boolean)
+        */
+       // protected void doSaveDocument(IProgressMonitor monitor, Object element,
+       // IDocument document, boolean overwrite)
+       // throws CoreException {
+       //
+       // ElementInfo elementInfo = getElementInfo(element);
+       // if (elementInfo instanceof CompilationUnitInfo) {
+       // CompilationUnitInfo info = (CompilationUnitInfo) elementInfo;
+       //
+       // // update structure, assumes lock on info.fCopy
+       // info.fCopy.reconcile();
+       //
+       // ICompilationUnit original = (ICompilationUnit)
+       // info.fCopy.getOriginalElement();
+       // IResource resource = original.getResource();
+       //
+       // if (resource == null) {
+       // // underlying resource has been deleted, just recreate file, ignore the
+       // rest
+       // super.doSaveDocument(monitor, element, document, overwrite);
+       // return;
+       // }
+       //
+       // if (resource != null && !overwrite)
+       // checkSynchronizationState(info.fModificationStamp, resource);
+       //
+       // if (fSavePolicy != null)
+       // fSavePolicy.preSave(info.fCopy);
+       //
+       // // inform about the upcoming content change
+       // fireElementStateChanging(element);
+       // try {
+       // fIsAboutToSave = true;
+       // // commit working copy
+       // info.fCopy.commit(overwrite, monitor);
+       // } catch (CoreException x) {
+       // // inform about the failure
+       // fireElementStateChangeFailed(element);
+       // throw x;
+       // } catch (RuntimeException x) {
+       // // inform about the failure
+       // fireElementStateChangeFailed(element);
+       // throw x;
+       // } finally {
+       // fIsAboutToSave = false;
+       // }
+       //
+       // // If here, the dirty state of the editor will change to "not dirty".
+       // // Thus, the state changing flag will be reset.
+       //
+       // AbstractMarkerAnnotationModel model = (AbstractMarkerAnnotationModel)
+       // info.fModel;
+       // model.updateMarkers(info.fDocument);
+       //
+       // if (resource != null)
+       // info.setModificationStamp(computeModificationStamp(resource));
+       //
+       // if (fSavePolicy != null) {
+       // ICompilationUnit unit = fSavePolicy.postSave(original);
+       // if (unit != null) {
+       // IResource r = unit.getResource();
+       // IMarker[] markers = r.findMarkers(IMarker.MARKER, true,
+       // IResource.DEPTH_ZERO);
+       // if (markers != null && markers.length > 0) {
+       // for (int i = 0; i < markers.length; i++)
+       // model.updateMarker(markers[i], info.fDocument, null);
+       // }
+       // }
+       // }
+       //
+       // } else {
+       // super.doSaveDocument(monitor, element, document, overwrite);
+       // }
+       // }
+       /*
+        * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createFileInfo(java.lang.Object)
+        */
+       protected FileInfo createFileInfo(Object element) throws CoreException {
+               if (!(element instanceof IFileEditorInput))
+                       return null;
+
+               IFileEditorInput input = (IFileEditorInput) element;
+               ICompilationUnit original = createCompilationUnit(input.getFile());
+               if (original == null)
+                       return null;
+
+               FileInfo info = super.createFileInfo(element);
+               if (!(info instanceof CompilationUnitInfo))
+                       return null;
+
+               CompilationUnitInfo cuInfo = (CompilationUnitInfo) info;
+               setUpSynchronization(cuInfo);
+
+               IProblemRequestor requestor = cuInfo.fModel instanceof IProblemRequestor ? (IProblemRequestor) cuInfo.fModel
+                               : null;
+
+               original.becomeWorkingCopy(requestor, getProgressMonitor());
+               cuInfo.fCopy = original;
+
+               if (cuInfo.fModel instanceof CompilationUnitAnnotationModel) {
+                       CompilationUnitAnnotationModel model = (CompilationUnitAnnotationModel) cuInfo.fModel;
+                       model.setCompilationUnit(cuInfo.fCopy);
+               }
+
+               if (cuInfo.fModel != null)
+                       cuInfo.fModel
+                                       .addAnnotationModelListener(fGlobalAnnotationModelListener);
+
+               if (requestor instanceof IProblemRequestorExtension) {
+                       IProblemRequestorExtension extension = (IProblemRequestorExtension) requestor;
+                       extension.setIsActive(isHandlingTemporaryProblems());
+               }
+
+               return cuInfo;
+       }
+
+       private void setUpSynchronization(CompilationUnitInfo cuInfo) {
+               IDocument document = cuInfo.fTextFileBuffer.getDocument();
+               IAnnotationModel model = cuInfo.fModel;
+
+               if (document instanceof ISynchronizable
+                               && model instanceof ISynchronizable) {
+                       Object lock = ((ISynchronizable) document).getLockObject();
+                       ((ISynchronizable) model).setLockObject(lock);
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#disposeFileInfo(java.lang.Object,
+        *      org.eclipse.ui.editors.text.TextFileDocumentProvider.FileInfo)
+        */
+       protected void disposeFileInfo(Object element, FileInfo info) {
+               if (info instanceof CompilationUnitInfo) {
+                       CompilationUnitInfo cuInfo = (CompilationUnitInfo) info;
+
+                       try {
+                               cuInfo.fCopy.discardWorkingCopy();
+                       } catch (JavaModelException x) {
+                               handleCoreException(x, x.getMessage());
+                       }
+
+                       if (cuInfo.fModel != null)
+                               cuInfo.fModel
+                                               .removeAnnotationModelListener(fGlobalAnnotationModelListener);
+               }
+               super.disposeFileInfo(element, info);
+       }
+
+       protected void commitWorkingCopy(IProgressMonitor monitor, Object element,
+                       CompilationUnitInfo info, boolean overwrite) throws CoreException {
+               synchronized (info.fCopy) {
+                       info.fCopy.reconcile();
+               }
+
+               IDocument document = info.fTextFileBuffer.getDocument();
+               IResource resource = info.fCopy.getResource();
+
+               Assert.isTrue(resource instanceof IFile);
+               if (!resource.exists()) {
+                       // underlying resource has been deleted, just recreate file, ignore
+                       // the rest
+                       createFileFromDocument(monitor, (IFile) resource, document);
+                       return;
+               }
+
+               if (fSavePolicy != null)
+                       fSavePolicy.preSave(info.fCopy);
+
+               try {
+
+                       fIsAboutToSave = true;
+                       info.fCopy.commitWorkingCopy(overwrite, monitor);
+
+               } catch (CoreException x) {
+                       // inform about the failure
+                       fireElementStateChangeFailed(element);
+                       throw x;
+               } catch (RuntimeException x) {
+                       // inform about the failure
+                       fireElementStateChangeFailed(element);
+                       throw x;
+               } finally {
+                       fIsAboutToSave = false;
+               }
+
+               // If here, the dirty state of the editor will change to "not dirty".
+               // Thus, the state changing flag will be reset.
+               if (info.fModel instanceof AbstractMarkerAnnotationModel) {
+                       AbstractMarkerAnnotationModel model = (AbstractMarkerAnnotationModel) info.fModel;
+                       model.updateMarkers(document);
+               }
+
+               if (fSavePolicy != null) {
+                       ICompilationUnit unit = fSavePolicy.postSave(info.fCopy);
+                       if (unit != null
+                                       && info.fModel instanceof AbstractMarkerAnnotationModel) {
+                               IResource r = unit.getResource();
+                               IMarker[] markers = r.findMarkers(IMarker.MARKER, true,
+                                               IResource.DEPTH_ZERO);
+                               if (markers != null && markers.length > 0) {
+                                       AbstractMarkerAnnotationModel model = (AbstractMarkerAnnotationModel) info.fModel;
+                                       for (int i = 0; i < markers.length; i++)
+                                               model.updateMarker(document, markers[i], null);
+                               }
+                       }
+               }
+
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createSaveOperation(java.lang.Object,
+        *      org.eclipse.jface.text.IDocument, boolean)
+        */
+       protected DocumentProviderOperation createSaveOperation(
+                       final Object element, final IDocument document,
+                       final boolean overwrite) throws CoreException {
+               // final FileInfo info= getFileInfo(element);
+               // if (info instanceof CompilationUnitInfo) {
+               // return new DocumentProviderOperation() {
+               // /*
+               // * @see
+               // org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+               // */
+               // protected void execute(IProgressMonitor monitor) throws CoreException
+               // {
+               // commitWorkingCopy(monitor, element, (CompilationUnitInfo) info,
+               // overwrite);
+               // }
+               // /*
+               // * @see
+               // org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
+               // */
+               // public ISchedulingRule getSchedulingRule() {
+               // if (info.fElement instanceof IFileEditorInput) {
+               // IFile file= ((IFileEditorInput) info.fElement).getFile();
+               // IResourceRuleFactory ruleFactory=
+               // ResourcesPlugin.getWorkspace().getRuleFactory();
+               // if (file == null || !file.exists())
+               // return ruleFactory.createRule(file);
+               // else
+               // return ruleFactory.modifyRule(file);
+               // } else
+               // return null;
+               // }
+               // };
+               // }
+               // return null;
+               final FileInfo info = getFileInfo(element);
+               if (info instanceof CompilationUnitInfo) {
+                       return new DocumentProviderOperation() {
+                               /*
+                                * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+                                */
+                               protected void execute(IProgressMonitor monitor)
+                                               throws CoreException {
+                                       commitWorkingCopy(monitor, element,
+                                                       (CompilationUnitInfo) info, overwrite);
+                               }
+
+                               /*
+                                * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
+                                */
+                               public ISchedulingRule getSchedulingRule() {
+                                       if (info.fElement instanceof IFileEditorInput) {
+                                               IFile file = ((IFileEditorInput) info.fElement)
+                                                               .getFile();
+                                               return computeSchedulingRule(file);
+                                       } else
+                                               return null;
+                               }
+                       };
+               }
+               return null;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on AbstractDocumentProvider
+        */
+       // protected IDocument createDocument(Object element) throws CoreException {
+       // if (element instanceof IEditorInput) {
+       // Document document = new PartiallySynchronizedDocument();
+       // if (setDocumentContent(document, (IEditorInput) element,
+       // getEncoding(element))) {
+       // initializeDocument(document, (IEditorInput) element);
+       //
+       // //
+       // // IDocument document = super.createDocument(element);
+       // // if (document != null) {
+       // // IDocumentPartitioner partitioner = null;
+       // // if (element instanceof FileEditorInput) {
+       // // IFile file = (IFile) ((FileEditorInput)
+       // element).getAdapter(IFile.class);
+       // // String filename = file.getLocation().toString();
+       // // String extension = filename.substring(filename.lastIndexOf("."),
+       // filename.length());
+       // // // System.out.println(extension);
+       // // if (extension.equalsIgnoreCase(".html") ||
+       // extension.equalsIgnoreCase(".htm")) {
+       // // // html
+       // // partitioner = createHTMLPartitioner();
+       // // } else if (extension.equalsIgnoreCase(".xml")) {
+       // // // xml
+       // // partitioner = createXMLPartitioner();
+       // // } else if (extension.equalsIgnoreCase(".js")) {
+       // // // javascript
+       // // partitioner = createJavaScriptPartitioner();
+       // // } else if (extension.equalsIgnoreCase(".css")) {
+       // // // cascading style sheets
+       // // partitioner = createCSSPartitioner();
+       // // } else if (extension.equalsIgnoreCase(".tpl")) {
+       // // // smarty ?
+       // // partitioner = createSmartyPartitioner();
+       // // } else if (extension.equalsIgnoreCase(".inc")) {
+       // // // php include files ?
+       // // partitioner = createIncludePartitioner();
+       // // }
+       // // }
+       // //
+       // // if (partitioner == null) {
+       // // partitioner = createPHPPartitioner();
+       // // }
+       // // document.setDocumentPartitioner(partitioner);
+       // // partitioner.connect(document);
+       // }
+       // return document;
+       // }
+       // return null;
+       // }
+       // /**
+       // * Return a partitioner for .html files.
+       // */
+       // private IDocumentPartitioner createHTMLPartitioner() {
+       // return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
+       // }
+       //
+       // private IDocumentPartitioner createIncludePartitioner() {
+       // return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+       // }
+       //
+       // private IDocumentPartitioner createJavaScriptPartitioner() {
+       // return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
+       // }
+       /**
+        * Creates a line tracker working with the same line delimiters as the
+        * document of the given element. Assumes the element to be managed by this
+        * document provider.
+        * 
+        * @param element
+        *            the element serving as blue print
+        * @return a line tracker based on the same line delimiters as the element's
+        *         document
+        */
+       public ILineTracker createLineTracker(Object element) {
+               return new DefaultLineTracker();
+       }
+
+       // /**
+       // * Return a partitioner for .php files.
+       // */
+       // private IDocumentPartitioner createPHPPartitioner() {
+       // return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+       // }
+       //
+       // private IDocumentPartitioner createSmartyPartitioner() {
+       // return new DefaultPartitioner(getSmartyPartitionScanner(), TYPES);
+       // }
+       //
+       // private IDocumentPartitioner createXMLPartitioner() {
+       // return new DefaultPartitioner(getXMLPartitionScanner(), TYPES);
+       // }
+       //
+       // /**
+       // * Return a scanner for creating html partitions.
+       // */
+       // private PHPPartitionScanner getHTMLPartitionScanner() {
+       // if (HTML_PARTITION_SCANNER == null)
+       // HTML_PARTITION_SCANNER = new
+       // PHPPartitionScanner(IPHPPartitionScannerConstants.HTML_FILE);
+       // return HTML_PARTITION_SCANNER;
+       // }
+       // /**
+       // * Return a scanner for creating php partitions.
+       // */
+       // private PHPPartitionScanner getPHPPartitionScanner() {
+       // if (PHP_PARTITION_SCANNER == null)
+       // PHP_PARTITION_SCANNER = new
+       // PHPPartitionScanner(IPHPPartitionScannerConstants.PHP_FILE);
+       // return PHP_PARTITION_SCANNER;
+       // }
+       //
+       // /**
+       // * Return a scanner for creating smarty partitions.
+       // */
+       // private PHPPartitionScanner getSmartyPartitionScanner() {
+       // if (SMARTY_PARTITION_SCANNER == null)
+       // SMARTY_PARTITION_SCANNER = new
+       // PHPPartitionScanner(IPHPPartitionScannerConstants.SMARTY_FILE);
+       // return SMARTY_PARTITION_SCANNER;
+       // }
+       //
+       // /**
+       // * Return a scanner for creating xml partitions.
+       // */
+       // private PHPPartitionScanner getXMLPartitionScanner() {
+       // if (XML_PARTITION_SCANNER == null)
+       // XML_PARTITION_SCANNER = new
+       // PHPPartitionScanner(IPHPPartitionScannerConstants.XML_FILE);
+       // return XML_PARTITION_SCANNER;
+       // }
+
+       // protected void initializeDocument(IDocument document, IEditorInput
+       // editorInput) {
+       // if (document != null) {
+       // JavaTextTools tools = PHPeclipsePlugin.getDefault().getJavaTextTools();
+       // IDocumentPartitioner partitioner = null;
+       // if (editorInput != null && editorInput instanceof FileEditorInput) {
+       // IFile file = (IFile) ((FileEditorInput)
+       // editorInput).getAdapter(IFile.class);
+       // String filename = file.getLocation().toString();
+       // String extension = filename.substring(filename.lastIndexOf("."),
+       // filename.length());
+       // partitioner = tools.createDocumentPartitioner(extension);
+       // } else {
+       // partitioner = tools.createDocumentPartitioner(".php");
+       // }
+       // document.setDocumentPartitioner(partitioner);
+       // partitioner.connect(document);
+       // }
+       // }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doResetDocument(java.lang.Object,
+        *      org.eclipse.core.runtime.IProgressMonitor)
+        */
+       // protected void doResetDocument(Object element, IProgressMonitor monitor)
+       // throws CoreException {
+       // if (element == null)
+       // return;
+       //
+       // ElementInfo elementInfo= getElementInfo(element);
+       // if (elementInfo instanceof CompilationUnitInfo) {
+       // CompilationUnitInfo info= (CompilationUnitInfo) elementInfo;
+       //
+       // IDocument document;
+       // IStatus status= null;
+       //
+       // try {
+       //
+       // ICompilationUnit original= (ICompilationUnit)
+       // info.fCopy.getOriginalElement();
+       // IResource resource= original.getResource();
+       // if (resource instanceof IFile) {
+       //
+       // IFile file= (IFile) resource;
+       //
+       // try {
+       // refreshFile(file, monitor);
+       // } catch (CoreException x) {
+       // handleCoreException(x,
+       // PHPEditorMessages.getString("CompilationUnitDocumentProvider.error.resetDocument"));
+       // //$NON-NLS-1$
+       // }
+       //
+       // IFileEditorInput input= new FileEditorInput(file);
+       // document= super.createDocument(input);
+       //
+       // } else {
+       // document= createEmptyDocument();
+       // }
+       //
+       // } catch (CoreException x) {
+       // document= createEmptyDocument();
+       // status= x.getStatus();
+       // }
+       //
+       // fireElementContentAboutToBeReplaced(element);
+       //
+       // removeUnchangedElementListeners(element, info);
+       // info.fDocument.set(document.get());
+       // info.fCanBeSaved= false;
+       // info.fStatus= status;
+       // addUnchangedElementListeners(element, info);
+       //
+       // fireElementContentReplaced(element);
+       // fireElementDirtyStateChanged(element, false);
+       //
+       // } else {
+       // super.doResetDocument(element, monitor);
+       // }
+       // }
+       /*
+        * @see AbstractDocumentProvider#resetDocument(Object)
+        */
+       // public void resetDocument(Object element) throws CoreException {
+       // if (element == null)
+       // return;
+       //
+       // ElementInfo elementInfo = getElementInfo(element);
+       // if (elementInfo instanceof CompilationUnitInfo) {
+       // CompilationUnitInfo info = (CompilationUnitInfo) elementInfo;
+       //
+       // IDocument document;
+       // IStatus status = null;
+       //
+       // try {
+       //
+       // ICompilationUnit original = (ICompilationUnit)
+       // info.fCopy.getOriginalElement();
+       // IResource resource = original.getResource();
+       // if (resource instanceof IFile) {
+       //
+       // IFile file = (IFile) resource;
+       //
+       // try {
+       // refreshFile(file);
+       // } catch (CoreException x) {
+       // handleCoreException(x,
+       // PHPEditorMessages.getString("PHPDocumentProvider.error.resetDocument"));
+       // //$NON-NLS-1$
+       // }
+       //
+       // IFileEditorInput input = new FileEditorInput(file);
+       // document = super.createDocument(input);
+       //
+       // } else {
+       // document = new Document();
+       // }
+       //
+       // } catch (CoreException x) {
+       // document = new Document();
+       // status = x.getStatus();
+       // }
+       //
+       // fireElementContentAboutToBeReplaced(element);
+       //
+       // removeUnchangedElementListeners(element, info);
+       // info.fDocument.set(document.get());
+       // info.fCanBeSaved = false;
+       // info.fStatus = status;
+       // addUnchangedElementListeners(element, info);
+       //
+       // fireElementContentReplaced(element);
+       // fireElementDirtyStateChanged(element, false);
+       //
+       // } else {
+       // super.resetDocument(element);
+       // }
+       // }
+       /**
+        * Saves the content of the given document to the given element. This is
+        * only performed when this provider initiated the save.
+        * 
+        * @param monitor
+        *            the progress monitor
+        * @param element
+        *            the element to which to save
+        * @param document
+        *            the document to save
+        * @param overwrite
+        *            <code>true</code> if the save should be enforced
+        */
+       public void saveDocumentContent(IProgressMonitor monitor, Object element,
+                       IDocument document, boolean overwrite) throws CoreException {
+               if (!fIsAboutToSave)
+                       return;
+               super.saveDocument(monitor, element, document, overwrite);
+               // if (!fIsAboutToSave)
+               // return;
+               //
+               // if (element instanceof IFileEditorInput) {
+               // IFileEditorInput input = (IFileEditorInput) element;
+               // try {
+               // String encoding = getEncoding(element);
+               // if (encoding == null)
+               // encoding = ResourcesPlugin.getEncoding();
+               // InputStream stream = new
+               // ByteArrayInputStream(document.get().getBytes(encoding));
+               // IFile file = input.getFile();
+               // file.setContents(stream, overwrite, true, monitor);
+               // } catch (IOException x) {
+               // IStatus s = new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID,
+               // IStatus.OK, x.getMessage(), x);
+               // throw new CoreException(s);
+               // }
+               // }
+       }
+
+       /**
+        * Returns the underlying resource for the given element.
+        * 
+        * @param the
+        *            element
+        * @return the underlying resource of the given element
+        */
+       // public IResource getUnderlyingResource(Object element) {
+       // if (element instanceof IFileEditorInput) {
+       // IFileEditorInput input = (IFileEditorInput) element;
+       // return input.getFile();
+       // }
+       // return null;
+       // }
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.ICompilationUnitDocumentProvider#getWorkingCopy(java.lang.Object)
+        */
+       public ICompilationUnit getWorkingCopy(Object element) {
+               FileInfo fileInfo = getFileInfo(element);
+               if (fileInfo instanceof CompilationUnitInfo) {
+                       CompilationUnitInfo info = (CompilationUnitInfo) fileInfo;
+                       return info.fCopy;
+               }
+               return null;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.ICompilationUnitDocumentProvider#shutdown()
+        */
+       public void shutdown() {
+               WebUI.getDefault().getPreferenceStore()
+                               .removePropertyChangeListener(fPropertyListener);
+               Iterator e = getConnectedElementsIterator();
+               while (e.hasNext())
+                       disconnect(e.next());
+       }
+
+       /**
+        * Returns the preference whether handling temporary problems is enabled.
+        */
+       protected boolean isHandlingTemporaryProblems() {
+               IPreferenceStore store = WebUI.getDefault()
+                               .getPreferenceStore();
+               return store.getBoolean(HANDLE_TEMPORARY_PROBLEMS);
+       }
+
+       /**
+        * Switches the state of problem acceptance according to the value in the
+        * preference store.
+        */
+       protected void enableHandlingTemporaryProblems() {
+               boolean enable = isHandlingTemporaryProblems();
+               for (Iterator iter = getFileInfosIterator(); iter.hasNext();) {
+                       FileInfo info = (FileInfo) iter.next();
+                       if (info.fModel instanceof IProblemRequestorExtension) {
+                               IProblemRequestorExtension extension = (IProblemRequestorExtension) info.fModel;
+                               extension.setIsActive(enable);
+                       }
+               }
+       }
+
+       /**
+        * Adds a listener that reports changes from all compilation unit annotation
+        * models.
+        */
+       public void addGlobalAnnotationModelListener(
+                       IAnnotationModelListener listener) {
+               fGlobalAnnotationModelListener.addListener(listener);
+       }
+
+       /**
+        * Removes the listener.
+        */
+       public void removeGlobalAnnotationModelListener(
+                       IAnnotationModelListener listener) {
+               fGlobalAnnotationModelListener.removeListener(listener);
+       }
+
+       /**
+        * Computes the scheduling rule needed to create or modify a resource. If
+        * the resource exists, its modify rule is returned. If it does not, the
+        * resource hierarchy is iterated towards the workspace root to find the
+        * first parent of <code>toCreateOrModify</code> that exists. Then the
+        * 'create' rule for the last non-existing resource is returned.
+        * <p>
+        * XXX This is a workaround for
+        * https://bugs.eclipse.org/bugs/show_bug.cgi?id=67601
+        * IResourceRuleFactory.createRule should iterate the hierarchy itself.
+        * </p>
+        * <p>
+        * XXX to be replaced by call to
+        * TextFileDocumentProvider.computeSchedulingRule after 3.0
+        * </p>
+        * 
+        * @param toCreateOrModify
+        *            the resource to create or modify
+        * @return the minimal scheduling rule needed to modify or create a resource
+        */
+       protected ISchedulingRule computeSchedulingRule(IResource toCreateOrModify) {
+               IResourceRuleFactory factory = ResourcesPlugin.getWorkspace()
+                               .getRuleFactory();
+               if (toCreateOrModify.exists()) {
+                       return factory.modifyRule(toCreateOrModify);
+               } else {
+                       IResource parent = toCreateOrModify;
+                       do {
+                               toCreateOrModify = parent;
+                               parent = toCreateOrModify.getParent();
+                       } while (parent != null && !parent.exists());
+
+                       return factory.createRule(toCreateOrModify);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java
new file mode 100644 (file)
index 0000000..446b848
--- /dev/null
@@ -0,0 +1,6104 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+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.StringTokenizer;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IImportContainer;
+import net.sourceforge.phpdt.core.IImportDeclaration;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
+import net.sourceforge.phpdt.internal.ui.actions.FoldingActionGroup;
+import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter;
+import net.sourceforge.phpdt.internal.ui.text.CustomSourceInformationControl;
+import net.sourceforge.phpdt.internal.ui.text.DocumentCharacterIterator;
+import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder;
+import net.sourceforge.phpdt.internal.ui.text.JavaWordIterator;
+import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
+import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaExpandHover;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ISelectionListenerWithAST;
+import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider;
+import net.sourceforge.phpdt.internal.ui.viewsupport.SelectionListenerWithASTManager;
+import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import net.sourceforge.phpdt.ui.JavaUI;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction;
+import net.sourceforge.phpdt.ui.actions.OpenEditorActionGroup;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.ExternalEditorInput;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.editor.BrowserUtil;
+import net.sourceforge.phpeclipse.webbrowser.views.BrowserView;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension4;
+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.ISelectionValidator;
+import org.eclipse.jface.text.ISynchronizable;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.ITextPresentationListener;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.ITextViewerExtension4;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.information.IInformationProvider;
+import org.eclipse.jface.text.information.InformationPresenter;
+import org.eclipse.jface.text.link.LinkedModeModel;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationRulerColumn;
+import org.eclipse.jface.text.source.CompositeRuler;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelExtension;
+import org.eclipse.jface.text.source.IOverviewRuler;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.ISourceViewerExtension2;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.IVerticalRulerColumn;
+import org.eclipse.jface.text.source.OverviewRuler;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.text.source.projection.ProjectionSupport;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+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.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BidiSegmentEvent;
+import org.eclipse.swt.custom.BidiSegmentListener;
+import org.eclipse.swt.custom.ST;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.editors.text.DefaultEncodingSupport;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.IEncodingSupport;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.IShowInSource;
+import org.eclipse.ui.part.IShowInTargetList;
+import org.eclipse.ui.part.ShowInContext;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.IEditorStatusLine;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
+import org.eclipse.ui.texteditor.TextEditorAction;
+import org.eclipse.ui.texteditor.TextNavigationAction;
+import org.eclipse.ui.texteditor.TextOperationAction;
+import org.eclipse.ui.views.contentoutline.ContentOutline;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.tasklist.TaskList;
+
+/**
+ * PHP specific text editor.
+ */
+public abstract class PHPEditor extends AbstractDecoratedTextEditor implements
+               IViewPartInputProvider, IShowInTargetList, IShowInSource {
+       // extends StatusTextEditor implements IViewPartInputProvider { // extends
+       // TextEditor {
+
+       /**
+        * Internal implementation class for a change listener.
+        * 
+        * @since 3.0
+        */
+       protected abstract class AbstractSelectionChangedListener implements
+                       ISelectionChangedListener {
+
+               /**
+                * Installs this selection changed listener with the given selection
+                * provider. If the selection provider is a post selection provider,
+                * post selection changed events are the preferred choice, otherwise
+                * normal selection changed events are requested.
+                * 
+                * @param selectionProvider
+                */
+               public void install(ISelectionProvider selectionProvider) {
+                       if (selectionProvider == null)
+                               return;
+
+                       if (selectionProvider instanceof IPostSelectionProvider) {
+                               IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
+                               provider.addPostSelectionChangedListener(this);
+                       } else {
+                               selectionProvider.addSelectionChangedListener(this);
+                       }
+               }
+
+               /**
+                * Removes this selection changed listener from the given selection
+                * provider.
+                * 
+                * @param selectionProvider
+                *            the selection provider
+                */
+               public void uninstall(ISelectionProvider selectionProvider) {
+                       if (selectionProvider == null)
+                               return;
+
+                       if (selectionProvider instanceof IPostSelectionProvider) {
+                               IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
+                               provider.removePostSelectionChangedListener(this);
+                       } else {
+                               selectionProvider.removeSelectionChangedListener(this);
+                       }
+               }
+       }
+
+       /**
+        * Updates the Java outline page selection and this editor's range
+        * indicator.
+        * 
+        * @since 3.0
+        */
+       private class EditorSelectionChangedListener extends
+                       AbstractSelectionChangedListener {
+
+               /*
+                * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+                */
+               public void selectionChanged(SelectionChangedEvent event) {
+                       // XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=56161
+                       PHPEditor.this.selectionChanged();
+               }
+       }
+
+       /**
+        * "Smart" runnable for updating the outline page's selection.
+        */
+       // class OutlinePageSelectionUpdater implements Runnable {
+       //
+       // /** Has the runnable already been posted? */
+       // private boolean fPosted = false;
+       //
+       // public OutlinePageSelectionUpdater() {
+       // }
+       //
+       // /*
+       // * @see Runnable#run()
+       // */
+       // public void run() {
+       // synchronizeOutlinePageSelection();
+       // fPosted = false;
+       // }
+       //
+       // /**
+       // * Posts this runnable into the event queue.
+       // */
+       // public void post() {
+       // if (fPosted)
+       // return;
+       //
+       // Shell shell = getSite().getShell();
+       // if (shell != null & !shell.isDisposed()) {
+       // fPosted = true;
+       // shell.getDisplay().asyncExec(this);
+       // }
+       // }
+       // };
+       class SelectionChangedListener implements ISelectionChangedListener {
+               public void selectionChanged(SelectionChangedEvent event) {
+                       doSelectionChanged(event);
+               }
+       };
+
+       /**
+        * Adapts an options {@link java.util.Map}to
+        * {@link org.eclipse.jface.preference.IPreferenceStore}.
+        * <p>
+        * This preference store is read-only i.e. write access throws an
+        * {@link java.lang.UnsupportedOperationException}.
+        * </p>
+        * 
+        * @since 3.0
+        */
+       private static class OptionsAdapter implements IPreferenceStore {
+
+               /**
+                * A property change event filter.
+                */
+               public interface IPropertyChangeEventFilter {
+
+                       /**
+                        * Should the given event be filtered?
+                        * 
+                        * @param event
+                        *            The property change event.
+                        * @return <code>true</code> iff the given event should be
+                        *         filtered.
+                        */
+                       public boolean isFiltered(PropertyChangeEvent event);
+
+               }
+
+               /**
+                * Property change listener. Listens for events in the options Map and
+                * fires a {@link org.eclipse.jface.util.PropertyChangeEvent}on this
+                * adapter with arguments from the received event.
+                */
+               private class PropertyChangeListener implements IPropertyChangeListener {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       public void propertyChange(PropertyChangeEvent event) {
+                               if (getFilter().isFiltered(event))
+                                       return;
+
+                               if (event.getNewValue() == null)
+                                       fOptions.remove(event.getProperty());
+                               else
+                                       fOptions.put(event.getProperty(), event.getNewValue());
+
+                               firePropertyChangeEvent(event.getProperty(), event
+                                               .getOldValue(), event.getNewValue());
+                       }
+               }
+
+               /** Listeners on this adapter */
+               private ListenerList fListeners = new ListenerList();
+
+               /** Listener on the adapted options Map */
+               private IPropertyChangeListener fListener = new PropertyChangeListener();
+
+               /** Adapted options Map */
+               private Map fOptions;
+
+               /** Preference store through which events are received. */
+               private IPreferenceStore fMockupPreferenceStore;
+
+               /** Property event filter. */
+               private IPropertyChangeEventFilter fFilter;
+
+               /**
+                * Initialize with the given options.
+                * 
+                * @param options
+                *            The options to wrap
+                * @param mockupPreferenceStore
+                *            the mock-up preference store
+                * @param filter
+                *            the property change filter
+                */
+               public OptionsAdapter(Map options,
+                               IPreferenceStore mockupPreferenceStore,
+                               IPropertyChangeEventFilter filter) {
+                       fMockupPreferenceStore = mockupPreferenceStore;
+                       fOptions = options;
+                       setFilter(filter);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void addPropertyChangeListener(IPropertyChangeListener listener) {
+                       if (fListeners.size() == 0)
+                               fMockupPreferenceStore.addPropertyChangeListener(fListener);
+                       fListeners.add(listener);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void removePropertyChangeListener(
+                               IPropertyChangeListener listener) {
+                       fListeners.remove(listener);
+                       if (fListeners.size() == 0)
+                               fMockupPreferenceStore.removePropertyChangeListener(fListener);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public boolean contains(String name) {
+                       return fOptions.containsKey(name);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void firePropertyChangeEvent(String name, Object oldValue,
+                               Object newValue) {
+                       PropertyChangeEvent event = new PropertyChangeEvent(this, name,
+                                       oldValue, newValue);
+                       Object[] listeners = fListeners.getListeners();
+                       for (int i = 0; i < listeners.length; i++)
+                               ((IPropertyChangeListener) listeners[i]).propertyChange(event);
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public boolean getBoolean(String name) {
+                       boolean value = BOOLEAN_DEFAULT_DEFAULT;
+                       String s = (String) fOptions.get(name);
+                       if (s != null)
+                               value = s.equals(TRUE);
+                       return value;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public boolean getDefaultBoolean(String name) {
+                       return BOOLEAN_DEFAULT_DEFAULT;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public double getDefaultDouble(String name) {
+                       return DOUBLE_DEFAULT_DEFAULT;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public float getDefaultFloat(String name) {
+                       return FLOAT_DEFAULT_DEFAULT;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public int getDefaultInt(String name) {
+                       return INT_DEFAULT_DEFAULT;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public long getDefaultLong(String name) {
+                       return LONG_DEFAULT_DEFAULT;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public String getDefaultString(String name) {
+                       return STRING_DEFAULT_DEFAULT;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public double getDouble(String name) {
+                       double value = DOUBLE_DEFAULT_DEFAULT;
+                       String s = (String) fOptions.get(name);
+                       if (s != null) {
+                               try {
+                                       value = new Double(s).doubleValue();
+                               } catch (NumberFormatException e) {
+                               }
+                       }
+                       return value;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public float getFloat(String name) {
+                       float value = FLOAT_DEFAULT_DEFAULT;
+                       String s = (String) fOptions.get(name);
+                       if (s != null) {
+                               try {
+                                       value = new Float(s).floatValue();
+                               } catch (NumberFormatException e) {
+                               }
+                       }
+                       return value;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public int getInt(String name) {
+                       int value = INT_DEFAULT_DEFAULT;
+                       String s = (String) fOptions.get(name);
+                       if (s != null) {
+                               try {
+                                       value = new Integer(s).intValue();
+                               } catch (NumberFormatException e) {
+                               }
+                       }
+                       return value;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public long getLong(String name) {
+                       long value = LONG_DEFAULT_DEFAULT;
+                       String s = (String) fOptions.get(name);
+                       if (s != null) {
+                               try {
+                                       value = new Long(s).longValue();
+                               } catch (NumberFormatException e) {
+                               }
+                       }
+                       return value;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public String getString(String name) {
+                       String value = (String) fOptions.get(name);
+                       if (value == null)
+                               value = STRING_DEFAULT_DEFAULT;
+                       return value;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public boolean isDefault(String name) {
+                       return false;
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public boolean needsSaving() {
+                       return !fOptions.isEmpty();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void putValue(String name, String value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setDefault(String name, double value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setDefault(String name, float value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setDefault(String name, int value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setDefault(String name, long value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setDefault(String name, String defaultObject) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setDefault(String name, boolean value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setToDefault(String name) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setValue(String name, double value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setValue(String name, float value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setValue(String name, int value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setValue(String name, long value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setValue(String name, String value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * {@inheritDoc}
+                */
+               public void setValue(String name, boolean value) {
+                       throw new UnsupportedOperationException();
+               }
+
+               /**
+                * Returns the adapted options Map.
+                * 
+                * @return Returns the adapted options Map.
+                */
+               public Map getOptions() {
+                       return fOptions;
+               }
+
+               /**
+                * Returns the mock-up preference store, events are received through
+                * this preference store.
+                * 
+                * @return Returns the mock-up preference store.
+                */
+               public IPreferenceStore getMockupPreferenceStore() {
+                       return fMockupPreferenceStore;
+               }
+
+               /**
+                * Set the event filter to the given filter.
+                * 
+                * @param filter
+                *            The new filter.
+                */
+               public void setFilter(IPropertyChangeEventFilter filter) {
+                       fFilter = filter;
+               }
+
+               /**
+                * Returns the event filter.
+                * 
+                * @return The event filter.
+                */
+               public IPropertyChangeEventFilter getFilter() {
+                       return fFilter;
+               }
+       }
+
+       /*
+        * Link mode.
+        */
+       // class MouseClickListener implements KeyListener, MouseListener,
+       // MouseMoveListener, FocusListener, PaintListener,
+       // IPropertyChangeListener, IDocumentListener, ITextInputListener {
+       //
+       // /** The session is active. */
+       // private boolean fActive;
+       //
+       // /** The currently active style range. */
+       // private IRegion fActiveRegion;
+       //
+       // /** The currently active style range as position. */
+       // private Position fRememberedPosition;
+       //
+       // /** The hand cursor. */
+       // private Cursor fCursor;
+       //
+       // /** The link color. */
+       // private Color fColor;
+       //
+       // /** The key modifier mask. */
+       // private int fKeyModifierMask;
+       //
+       // public void deactivate() {
+       // deactivate(false);
+       // }
+       //
+       // public void deactivate(boolean redrawAll) {
+       // if (!fActive)
+       // return;
+       //
+       // repairRepresentation(redrawAll);
+       // fActive = false;
+       // }
+       //
+       // public void install() {
+       //
+       // ISourceViewer sourceViewer = getSourceViewer();
+       // if (sourceViewer == null)
+       // return;
+       //
+       // StyledText text = sourceViewer.getTextWidget();
+       // if (text == null || text.isDisposed())
+       // return;
+       //
+       // updateColor(sourceViewer);
+       //
+       // sourceViewer.addTextInputListener(this);
+       //
+       // IDocument document = sourceViewer.getDocument();
+       // if (document != null)
+       // document.addDocumentListener(this);
+       //
+       // text.addKeyListener(this);
+       // text.addMouseListener(this);
+       // text.addMouseMoveListener(this);
+       // text.addFocusListener(this);
+       // text.addPaintListener(this);
+       //
+       // updateKeyModifierMask();
+       //
+       // IPreferenceStore preferenceStore = getPreferenceStore();
+       // preferenceStore.addPropertyChangeListener(this);
+       // }
+       //
+       // private void updateKeyModifierMask() {
+       // String modifiers =
+       // getPreferenceStore().getString(BROWSER_LIKE_LINKS_KEY_MODIFIER);
+       // fKeyModifierMask = computeStateMask(modifiers);
+       // if (fKeyModifierMask == -1) {
+       // // Fallback to stored state mask
+       // fKeyModifierMask =
+       // getPreferenceStore().getInt(BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK);
+       // }
+       // ;
+       // }
+       //
+       // private int computeStateMask(String modifiers) {
+       // if (modifiers == null)
+       // return -1;
+       //
+       // if (modifiers.length() == 0)
+       // return SWT.NONE;
+       //
+       // int stateMask = 0;
+       // StringTokenizer modifierTokenizer = new StringTokenizer(modifiers,
+       // ",;.:+-*
+       // "); //$NON-NLS-1$
+       // while (modifierTokenizer.hasMoreTokens()) {
+       // int modifier =
+       // EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken());
+       // if (modifier == 0 || (stateMask & modifier) == modifier)
+       // return -1;
+       // stateMask = stateMask | modifier;
+       // }
+       // return stateMask;
+       // }
+       //
+       // public void uninstall() {
+       //
+       // if (fColor != null) {
+       // fColor.dispose();
+       // fColor = null;
+       // }
+       //
+       // if (fCursor != null) {
+       // fCursor.dispose();
+       // fCursor = null;
+       // }
+       //
+       // ISourceViewer sourceViewer = getSourceViewer();
+       // if (sourceViewer == null)
+       // return;
+       //
+       // sourceViewer.removeTextInputListener(this);
+       //
+       // IDocument document = sourceViewer.getDocument();
+       // if (document != null)
+       // document.removeDocumentListener(this);
+       //
+       // IPreferenceStore preferenceStore = getPreferenceStore();
+       // if (preferenceStore != null)
+       // preferenceStore.removePropertyChangeListener(this);
+       //
+       // StyledText text = sourceViewer.getTextWidget();
+       // if (text == null || text.isDisposed())
+       // return;
+       //
+       // text.removeKeyListener(this);
+       // text.removeMouseListener(this);
+       // text.removeMouseMoveListener(this);
+       // text.removeFocusListener(this);
+       // text.removePaintListener(this);
+       // }
+       //
+       // /*
+       // * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+       // */
+       // public void propertyChange(PropertyChangeEvent event) {
+       // if (event.getProperty().equals(PHPEditor.LINK_COLOR)) {
+       // ISourceViewer viewer = getSourceViewer();
+       // if (viewer != null)
+       // updateColor(viewer);
+       // } else if (event.getProperty().equals(BROWSER_LIKE_LINKS_KEY_MODIFIER)) {
+       // updateKeyModifierMask();
+       // }
+       // }
+       //
+       // private void updateColor(ISourceViewer viewer) {
+       // if (fColor != null)
+       // fColor.dispose();
+       //
+       // StyledText text = viewer.getTextWidget();
+       // if (text == null || text.isDisposed())
+       // return;
+       //
+       // Display display = text.getDisplay();
+       // fColor = createColor(getPreferenceStore(), PHPEditor.LINK_COLOR,
+       // display);
+       // }
+       //
+       // /**
+       // * Creates a color from the information stored in the given preference
+       // store. Returns <code>null</code> if there is no such
+       // * information available.
+       // */
+       // private Color createColor(IPreferenceStore store, String key, Display
+       // display) {
+       //
+       // RGB rgb = null;
+       //
+       // if (store.contains(key)) {
+       //
+       // if (store.isDefault(key))
+       // rgb = PreferenceConverter.getDefaultColor(store, key);
+       // else
+       // rgb = PreferenceConverter.getColor(store, key);
+       //
+       // if (rgb != null)
+       // return new Color(display, rgb);
+       // }
+       //
+       // return null;
+       // }
+       //
+       // private void repairRepresentation() {
+       // repairRepresentation(false);
+       // }
+       //
+       // private void repairRepresentation(boolean redrawAll) {
+       //
+       // if (fActiveRegion == null)
+       // return;
+       //
+       // ISourceViewer viewer = getSourceViewer();
+       // if (viewer != null) {
+       // resetCursor(viewer);
+       //
+       // int offset = fActiveRegion.getOffset();
+       // int length = fActiveRegion.getLength();
+       //
+       // // remove style
+       // if (!redrawAll && viewer instanceof ITextViewerExtension2)
+       // ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset,
+       // length);
+       // else
+       // viewer.invalidateTextPresentation();
+       //
+       // // remove underline
+       // if (viewer instanceof ITextViewerExtension3) {
+       // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+       // offset = extension.modelOffset2WidgetOffset(offset);
+       // } else {
+       // offset -= viewer.getVisibleRegion().getOffset();
+       // }
+       //
+       // StyledText text = viewer.getTextWidget();
+       // try {
+       // text.redrawRange(offset, length, true);
+       // } catch (IllegalArgumentException x) {
+       // PHPeclipsePlugin.log(x);
+       // }
+       // }
+       //
+       // fActiveRegion = null;
+       // }
+       //
+       // // will eventually be replaced by a method provided by jdt.core
+       // private IRegion selectWord(IDocument document, int anchor) {
+       //
+       // try {
+       // int offset = anchor;
+       // char c;
+       //
+       // while (offset >= 0) {
+       // c = document.getChar(offset);
+       // if (!Scanner.isPHPIdentifierPart(c))
+       // break;
+       // --offset;
+       // }
+       //
+       // int start = offset;
+       //
+       // offset = anchor;
+       // int length = document.getLength();
+       //
+       // while (offset < length) {
+       // c = document.getChar(offset);
+       // if (!Scanner.isPHPIdentifierPart(c))
+       // break;
+       // ++offset;
+       // }
+       //
+       // int end = offset;
+       //
+       // if (start == end)
+       // return new Region(start, 0);
+       // else
+       // return new Region(start + 1, end - start - 1);
+       //
+       // } catch (BadLocationException x) {
+       // return null;
+       // }
+       // }
+       //
+       // IRegion getCurrentTextRegion(ISourceViewer viewer) {
+       //
+       // int offset = getCurrentTextOffset(viewer);
+       // if (offset == -1)
+       // return null;
+       //
+       // return null;
+       // // IJavaElement input= SelectionConverter.getInput(PHPEditor.this);
+       // // if (input == null)
+       // // return null;
+       // //
+       // // try {
+       // //
+       // // IJavaElement[] elements= null;
+       // // synchronized (input) {
+       // // elements= ((ICodeAssist) input).codeSelect(offset, 0);
+       // // }
+       // //
+       // // if (elements == null || elements.length == 0)
+       // // return null;
+       // //
+       // // return selectWord(viewer.getDocument(), offset);
+       // //
+       // // } catch (JavaModelException e) {
+       // // return null;
+       // // }
+       // }
+       //
+       // private int getCurrentTextOffset(ISourceViewer viewer) {
+       //
+       // try {
+       // StyledText text = viewer.getTextWidget();
+       // if (text == null || text.isDisposed())
+       // return -1;
+       //
+       // Display display = text.getDisplay();
+       // Point absolutePosition = display.getCursorLocation();
+       // Point relativePosition = text.toControl(absolutePosition);
+       //
+       // int widgetOffset = text.getOffsetAtLocation(relativePosition);
+       // if (viewer instanceof ITextViewerExtension3) {
+       // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+       // return extension.widgetOffset2ModelOffset(widgetOffset);
+       // } else {
+       // return widgetOffset + viewer.getVisibleRegion().getOffset();
+       // }
+       //
+       // } catch (IllegalArgumentException e) {
+       // return -1;
+       // }
+       // }
+       //
+       // private void highlightRegion(ISourceViewer viewer, IRegion region) {
+       //
+       // if (region.equals(fActiveRegion))
+       // return;
+       //
+       // repairRepresentation();
+       //
+       // StyledText text = viewer.getTextWidget();
+       // if (text == null || text.isDisposed())
+       // return;
+       //
+       // // highlight region
+       // int offset = 0;
+       // int length = 0;
+       //
+       // if (viewer instanceof ITextViewerExtension3) {
+       // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+       // IRegion widgetRange = extension.modelRange2WidgetRange(region);
+       // if (widgetRange == null)
+       // return;
+       //
+       // offset = widgetRange.getOffset();
+       // length = widgetRange.getLength();
+       //
+       // } else {
+       // offset = region.getOffset() - viewer.getVisibleRegion().getOffset();
+       // length = region.getLength();
+       // }
+       //
+       // StyleRange oldStyleRange = text.getStyleRangeAtOffset(offset);
+       // Color foregroundColor = fColor;
+       // Color backgroundColor = oldStyleRange == null ? text.getBackground() :
+       // oldStyleRange.background;
+       // StyleRange styleRange = new StyleRange(offset, length, foregroundColor,
+       // backgroundColor);
+       // text.setStyleRange(styleRange);
+       //
+       // // underline
+       // text.redrawRange(offset, length, true);
+       //
+       // fActiveRegion = region;
+       // }
+       //
+       // private void activateCursor(ISourceViewer viewer) {
+       // StyledText text = viewer.getTextWidget();
+       // if (text == null || text.isDisposed())
+       // return;
+       // Display display = text.getDisplay();
+       // if (fCursor == null)
+       // fCursor = new Cursor(display, SWT.CURSOR_HAND);
+       // text.setCursor(fCursor);
+       // }
+       //
+       // private void resetCursor(ISourceViewer viewer) {
+       // StyledText text = viewer.getTextWidget();
+       // if (text != null && !text.isDisposed())
+       // text.setCursor(null);
+       //
+       // if (fCursor != null) {
+       // fCursor.dispose();
+       // fCursor = null;
+       // }
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+       // */
+       // public void keyPressed(KeyEvent event) {
+       //
+       // if (fActive) {
+       // deactivate();
+       // return;
+       // }
+       //
+       // if (event.keyCode != fKeyModifierMask) {
+       // deactivate();
+       // return;
+       // }
+       //
+       // fActive = true;
+       //
+       // // removed for #25871
+       // //
+       // // ISourceViewer viewer= getSourceViewer();
+       // // if (viewer == null)
+       // // return;
+       // //
+       // // IRegion region= getCurrentTextRegion(viewer);
+       // // if (region == null)
+       // // return;
+       // //
+       // // highlightRegion(viewer, region);
+       // // activateCursor(viewer);
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+       // */
+       // public void keyReleased(KeyEvent event) {
+       //
+       // if (!fActive)
+       // return;
+       //
+       // deactivate();
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+       // */
+       // public void mouseDoubleClick(MouseEvent e) {
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+       // */
+       // public void mouseDown(MouseEvent event) {
+       //
+       // if (!fActive)
+       // return;
+       //
+       // if (event.stateMask != fKeyModifierMask) {
+       // deactivate();
+       // return;
+       // }
+       //
+       // if (event.button != 1) {
+       // deactivate();
+       // return;
+       // }
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+       // */
+       // public void mouseUp(MouseEvent e) {
+       //
+       // if (!fActive)
+       // return;
+       //
+       // if (e.button != 1) {
+       // deactivate();
+       // return;
+       // }
+       //
+       // boolean wasActive = fCursor != null;
+       //
+       // deactivate();
+       //
+       // if (wasActive) {
+       // IAction action = getAction("OpenEditor"); //$NON-NLS-1$
+       // if (action != null)
+       // action.run();
+       // }
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+       // */
+       // public void mouseMove(MouseEvent event) {
+       //
+       // if (event.widget instanceof Control && !((Control)
+       // event.widget).isFocusControl()) {
+       // deactivate();
+       // return;
+       // }
+       //
+       // if (!fActive) {
+       // if (event.stateMask != fKeyModifierMask)
+       // return;
+       // // modifier was already pressed
+       // fActive = true;
+       // }
+       //
+       // ISourceViewer viewer = getSourceViewer();
+       // if (viewer == null) {
+       // deactivate();
+       // return;
+       // }
+       //
+       // StyledText text = viewer.getTextWidget();
+       // if (text == null || text.isDisposed()) {
+       // deactivate();
+       // return;
+       // }
+       //
+       // if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() !=
+       // 0)
+       // {
+       // deactivate();
+       // return;
+       // }
+       //
+       // IRegion region = getCurrentTextRegion(viewer);
+       // if (region == null || region.getLength() == 0) {
+       // repairRepresentation();
+       // return;
+       // }
+       //
+       // highlightRegion(viewer, region);
+       // activateCursor(viewer);
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+       // */
+       // public void focusGained(FocusEvent e) {
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+       // */
+       // public void focusLost(FocusEvent event) {
+       // deactivate();
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+       // */
+       // public void documentAboutToBeChanged(DocumentEvent event) {
+       // if (fActive && fActiveRegion != null) {
+       // fRememberedPosition = new Position(fActiveRegion.getOffset(),
+       // fActiveRegion.getLength());
+       // try {
+       // event.getDocument().addPosition(fRememberedPosition);
+       // } catch (BadLocationException x) {
+       // fRememberedPosition = null;
+       // }
+       // }
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+       // */
+       // public void documentChanged(DocumentEvent event) {
+       // if (fRememberedPosition != null && !fRememberedPosition.isDeleted()) {
+       // event.getDocument().removePosition(fRememberedPosition);
+       // fActiveRegion = new Region(fRememberedPosition.getOffset(),
+       // fRememberedPosition.getLength());
+       // }
+       // fRememberedPosition = null;
+       //
+       // ISourceViewer viewer = getSourceViewer();
+       // if (viewer != null) {
+       // StyledText widget = viewer.getTextWidget();
+       // if (widget != null && !widget.isDisposed()) {
+       // widget.getDisplay().asyncExec(new Runnable() {
+       // public void run() {
+       // deactivate();
+       // }
+       // });
+       // }
+       // }
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
+       // * org.eclipse.jface.text.IDocument)
+       // */
+       // public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument
+       // newInput) {
+       // if (oldInput == null)
+       // return;
+       // deactivate();
+       // oldInput.removeDocumentListener(this);
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
+       // * org.eclipse.jface.text.IDocument)
+       // */
+       // public void inputDocumentChanged(IDocument oldInput, IDocument newInput)
+       // {
+       // if (newInput == null)
+       // return;
+       // newInput.addDocumentListener(this);
+       // }
+       //
+       // /*
+       // * @see PaintListener#paintControl(PaintEvent)
+       // */
+       // public void paintControl(PaintEvent event) {
+       // if (fActiveRegion == null)
+       // return;
+       //
+       // ISourceViewer viewer = getSourceViewer();
+       // if (viewer == null)
+       // return;
+       //
+       // StyledText text = viewer.getTextWidget();
+       // if (text == null || text.isDisposed())
+       // return;
+       //
+       // int offset = 0;
+       // int length = 0;
+       //
+       // if (viewer instanceof ITextViewerExtension3) {
+       //
+       // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+       // IRegion widgetRange = extension.modelRange2WidgetRange(new Region(offset,
+       // length));
+       // if (widgetRange == null)
+       // return;
+       //
+       // offset = widgetRange.getOffset();
+       // length = widgetRange.getLength();
+       //
+       // } else {
+       //
+       // IRegion region = viewer.getVisibleRegion();
+       // if (!includes(region, fActiveRegion))
+       // return;
+       //
+       // offset = fActiveRegion.getOffset() - region.getOffset();
+       // length = fActiveRegion.getLength();
+       // }
+       //
+       // // support for bidi
+       // Point minLocation = getMinimumLocation(text, offset, length);
+       // Point maxLocation = getMaximumLocation(text, offset, length);
+       //
+       // int x1 = minLocation.x;
+       // int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
+       // int y = minLocation.y + text.getLineHeight() - 1;
+       //
+       // GC gc = event.gc;
+       // if (fColor != null && !fColor.isDisposed())
+       // gc.setForeground(fColor);
+       // gc.drawLine(x1, y, x2, y);
+       // }
+       //
+       // private boolean includes(IRegion region, IRegion position) {
+       // return position.getOffset() >= region.getOffset()
+       // && position.getOffset() + position.getLength() <= region.getOffset() +
+       // region.getLength();
+       // }
+       //
+       // private Point getMinimumLocation(StyledText text, int offset, int length)
+       // {
+       // Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
+       //
+       // for (int i = 0; i <= length; i++) {
+       // Point location = text.getLocationAtOffset(offset + i);
+       //
+       // if (location.x < minLocation.x)
+       // minLocation.x = location.x;
+       // if (location.y < minLocation.y)
+       // minLocation.y = location.y;
+       // }
+       //
+       // return minLocation;
+       // }
+       //
+       // private Point getMaximumLocation(StyledText text, int offset, int length)
+       // {
+       // Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
+       //
+       // for (int i = 0; i <= length; i++) {
+       // Point location = text.getLocationAtOffset(offset + i);
+       //
+       // if (location.x > maxLocation.x)
+       // maxLocation.x = location.x;
+       // if (location.y > maxLocation.y)
+       // maxLocation.y = location.y;
+       // }
+       //
+       // return maxLocation;
+       // }
+       // };
+       /*
+        * Link mode.
+        */
+       class MouseClickListener implements KeyListener, MouseListener,
+                       MouseMoveListener, FocusListener, PaintListener,
+                       IPropertyChangeListener, IDocumentListener, ITextInputListener,
+                       ITextPresentationListener {
+
+               /** The session is active. */
+               private boolean fActive;
+
+               /** The currently active style range. */
+               private IRegion fActiveRegion;
+
+               /** The currently active style range as position. */
+               private Position fRememberedPosition;
+
+               /** The hand cursor. */
+               private Cursor fCursor;
+
+               /** The link color. */
+               private Color fColor;
+
+               /** The key modifier mask. */
+               private int fKeyModifierMask;
+
+               public void deactivate() {
+                       deactivate(false);
+               }
+
+               public void deactivate(boolean redrawAll) {
+                       if (!fActive)
+                               return;
+
+                       repairRepresentation(redrawAll);
+                       fActive = false;
+               }
+
+               public void install() {
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer == null)
+                               return;
+
+                       StyledText text = sourceViewer.getTextWidget();
+                       if (text == null || text.isDisposed())
+                               return;
+
+                       updateColor(sourceViewer);
+
+                       sourceViewer.addTextInputListener(this);
+
+                       IDocument document = sourceViewer.getDocument();
+                       if (document != null)
+                               document.addDocumentListener(this);
+
+                       text.addKeyListener(this);
+                       text.addMouseListener(this);
+                       text.addMouseMoveListener(this);
+                       text.addFocusListener(this);
+                       text.addPaintListener(this);
+
+                       ((ITextViewerExtension4) sourceViewer)
+                                       .addTextPresentationListener(this);
+
+                       updateKeyModifierMask();
+
+                       IPreferenceStore preferenceStore = getPreferenceStore();
+                       preferenceStore.addPropertyChangeListener(this);
+               }
+
+               private void updateKeyModifierMask() {
+                       String modifiers = getPreferenceStore().getString(
+                                       BROWSER_LIKE_LINKS_KEY_MODIFIER);
+                       fKeyModifierMask = computeStateMask(modifiers);
+                       if (fKeyModifierMask == -1) {
+                               // Fall back to stored state mask
+                               fKeyModifierMask = getPreferenceStore().getInt(
+                                               BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK);
+                       }
+               }
+
+               private int computeStateMask(String modifiers) {
+                       if (modifiers == null)
+                               return -1;
+
+                       if (modifiers.length() == 0)
+                               return SWT.NONE;
+
+                       int stateMask = 0;
+                       StringTokenizer modifierTokenizer = new StringTokenizer(modifiers,
+                                       ",;.:+-* "); //$NON-NLS-1$
+                       while (modifierTokenizer.hasMoreTokens()) {
+                               int modifier = EditorUtility
+                                               .findLocalizedModifier(modifierTokenizer.nextToken());
+                               if (modifier == 0 || (stateMask & modifier) == modifier)
+                                       return -1;
+                               stateMask = stateMask | modifier;
+                       }
+                       return stateMask;
+               }
+
+               public void uninstall() {
+
+                       if (fColor != null) {
+                               fColor.dispose();
+                               fColor = null;
+                       }
+
+                       if (fCursor != null) {
+                               fCursor.dispose();
+                               fCursor = null;
+                       }
+
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer != null)
+                               sourceViewer.removeTextInputListener(this);
+
+                       IDocumentProvider documentProvider = getDocumentProvider();
+                       if (documentProvider != null) {
+                               IDocument document = documentProvider
+                                               .getDocument(getEditorInput());
+                               if (document != null)
+                                       document.removeDocumentListener(this);
+                       }
+
+                       IPreferenceStore preferenceStore = getPreferenceStore();
+                       if (preferenceStore != null)
+                               preferenceStore.removePropertyChangeListener(this);
+
+                       if (sourceViewer == null)
+                               return;
+
+                       StyledText text = sourceViewer.getTextWidget();
+                       if (text == null || text.isDisposed())
+                               return;
+
+                       text.removeKeyListener(this);
+                       text.removeMouseListener(this);
+                       text.removeMouseMoveListener(this);
+                       text.removeFocusListener(this);
+                       text.removePaintListener(this);
+
+                       ((ITextViewerExtension4) sourceViewer)
+                                       .removeTextPresentationListener(this);
+               }
+
+               /*
+                * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+                */
+               public void propertyChange(PropertyChangeEvent event) {
+                       if (event.getProperty().equals(PHPEditor.LINK_COLOR)) {
+                               ISourceViewer viewer = getSourceViewer();
+                               if (viewer != null)
+                                       updateColor(viewer);
+                       } else if (event.getProperty().equals(
+                                       BROWSER_LIKE_LINKS_KEY_MODIFIER)) {
+                               updateKeyModifierMask();
+                       }
+               }
+
+               private void updateColor(ISourceViewer viewer) {
+                       if (fColor != null)
+                               fColor.dispose();
+
+                       StyledText text = viewer.getTextWidget();
+                       if (text == null || text.isDisposed())
+                               return;
+
+                       Display display = text.getDisplay();
+                       fColor = createColor(getPreferenceStore(), PHPEditor.LINK_COLOR,
+                                       display);
+               }
+
+               /**
+                * Creates a color from the information stored in the given preference
+                * store.
+                * 
+                * @param store
+                *            the preference store
+                * @param key
+                *            the key
+                * @param display
+                *            the display
+                * @return the color or <code>null</code> if there is no such
+                *         information available
+                */
+               private Color createColor(IPreferenceStore store, String key,
+                               Display display) {
+
+                       RGB rgb = null;
+
+                       if (store.contains(key)) {
+
+                               if (store.isDefault(key))
+                                       rgb = PreferenceConverter.getDefaultColor(store, key);
+                               else
+                                       rgb = PreferenceConverter.getColor(store, key);
+
+                               if (rgb != null)
+                                       return new Color(display, rgb);
+                       }
+
+                       return null;
+               }
+
+               private void repairRepresentation() {
+                       repairRepresentation(false);
+               }
+
+               private void repairRepresentation(boolean redrawAll) {
+
+                       if (fActiveRegion == null)
+                               return;
+
+                       int offset = fActiveRegion.getOffset();
+                       int length = fActiveRegion.getLength();
+                       fActiveRegion = null;
+
+                       ISourceViewer viewer = getSourceViewer();
+                       if (viewer != null) {
+
+                               resetCursor(viewer);
+
+                               // Invalidate ==> remove applied text presentation
+                               if (!redrawAll && viewer instanceof ITextViewerExtension2)
+                                       ((ITextViewerExtension2) viewer)
+                                                       .invalidateTextPresentation(offset, length);
+                               else
+                                       viewer.invalidateTextPresentation();
+
+                               // Remove underline
+                               if (viewer instanceof ITextViewerExtension5) {
+                                       ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+                                       offset = extension.modelOffset2WidgetOffset(offset);
+                               } else {
+                                       offset -= viewer.getVisibleRegion().getOffset();
+                               }
+                               try {
+                                       StyledText text = viewer.getTextWidget();
+
+                                       text.redrawRange(offset, length, false);
+                               } catch (IllegalArgumentException x) {
+                                       // JavaPlugin.log(x);
+                               }
+                       }
+               }
+
+               // will eventually be replaced by a method provided by jdt.core
+               private IRegion selectWord(IDocument document, int anchor) {
+
+                       try {
+                               int offset = anchor;
+                               char c;
+
+                               while (offset >= 0) {
+                                       c = document.getChar(offset);
+                                       if (!Scanner.isPHPIdentifierPart(c) && c != '$')
+                                               break;
+                                       --offset;
+                               }
+
+                               int start = offset;
+
+                               offset = anchor;
+                               int length = document.getLength();
+
+                               while (offset < length) {
+                                       c = document.getChar(offset);
+                                       if (!Scanner.isPHPIdentifierPart(c) && c != '$')
+                                               break;
+                                       ++offset;
+                               }
+
+                               int end = offset;
+
+                               if (start == end)
+                                       return new Region(start, 0);
+                               else
+                                       return new Region(start + 1, end - start - 1);
+
+                       } catch (BadLocationException x) {
+                               return null;
+                       }
+               }
+
+               IRegion getCurrentTextRegion(ISourceViewer viewer) {
+
+                       int offset = getCurrentTextOffset(viewer);
+                       if (offset == -1)
+                               return null;
+
+                       IJavaElement input = SelectionConverter.getInput(PHPEditor.this);
+                       if (input == null)
+                               return null;
+
+                       // try {
+
+                       // IJavaElement[] elements= null;
+                       // synchronized (input) {
+                       // elements= ((ICodeAssist) input).codeSelect(offset, 0);
+                       // }
+                       //
+                       // if (elements == null || elements.length == 0)
+                       // return null;
+
+                       return selectWord(viewer.getDocument(), offset);
+
+                       // } catch (JavaModelException e) {
+                       // return null;
+                       // }
+               }
+
+               private int getCurrentTextOffset(ISourceViewer viewer) {
+
+                       try {
+                               StyledText text = viewer.getTextWidget();
+                               if (text == null || text.isDisposed())
+                                       return -1;
+
+                               Display display = text.getDisplay();
+                               Point absolutePosition = display.getCursorLocation();
+                               Point relativePosition = text.toControl(absolutePosition);
+
+                               int widgetOffset = text.getOffsetAtLocation(relativePosition);
+                               if (viewer instanceof ITextViewerExtension5) {
+                                       ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+                                       return extension.widgetOffset2ModelOffset(widgetOffset);
+                               } else {
+                                       return widgetOffset + viewer.getVisibleRegion().getOffset();
+                               }
+
+                       } catch (IllegalArgumentException e) {
+                               return -1;
+                       }
+               }
+
+               public void applyTextPresentation(TextPresentation textPresentation) {
+                       if (fActiveRegion == null)
+                               return;
+                       IRegion region = textPresentation.getExtent();
+                       if (fActiveRegion.getOffset() + fActiveRegion.getLength() >= region
+                                       .getOffset()
+                                       && region.getOffset() + region.getLength() > fActiveRegion
+                                                       .getOffset())
+                               textPresentation.mergeStyleRange(new StyleRange(fActiveRegion
+                                               .getOffset(), fActiveRegion.getLength(), fColor, null));
+               }
+
+               private void highlightRegion(ISourceViewer viewer, IRegion region) {
+
+                       if (region.equals(fActiveRegion))
+                               return;
+
+                       repairRepresentation();
+
+                       StyledText text = viewer.getTextWidget();
+                       if (text == null || text.isDisposed())
+                               return;
+
+                       // Underline
+                       int offset = 0;
+                       int length = 0;
+                       if (viewer instanceof ITextViewerExtension5) {
+                               ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+                               IRegion widgetRange = extension.modelRange2WidgetRange(region);
+                               if (widgetRange == null)
+                                       return;
+
+                               offset = widgetRange.getOffset();
+                               length = widgetRange.getLength();
+
+                       } else {
+                               offset = region.getOffset()
+                                               - viewer.getVisibleRegion().getOffset();
+                               length = region.getLength();
+                       }
+                       text.redrawRange(offset, length, false);
+
+                       // Invalidate region ==> apply text presentation
+                       fActiveRegion = region;
+                       if (viewer instanceof ITextViewerExtension2)
+                               ((ITextViewerExtension2) viewer).invalidateTextPresentation(
+                                               region.getOffset(), region.getLength());
+                       else
+                               viewer.invalidateTextPresentation();
+               }
+
+               private void activateCursor(ISourceViewer viewer) {
+                       StyledText text = viewer.getTextWidget();
+                       if (text == null || text.isDisposed())
+                               return;
+                       Display display = text.getDisplay();
+                       if (fCursor == null)
+                               fCursor = new Cursor(display, SWT.CURSOR_HAND);
+                       text.setCursor(fCursor);
+               }
+
+               private void resetCursor(ISourceViewer viewer) {
+                       StyledText text = viewer.getTextWidget();
+                       if (text != null && !text.isDisposed())
+                               text.setCursor(null);
+
+                       if (fCursor != null) {
+                               fCursor.dispose();
+                               fCursor = null;
+                       }
+               }
+
+               /*
+                * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+                */
+               public void keyPressed(KeyEvent event) {
+
+                       if (fActive) {
+                               deactivate();
+                               return;
+                       }
+
+                       if (event.keyCode != fKeyModifierMask) {
+                               deactivate();
+                               return;
+                       }
+
+                       fActive = true;
+
+                       // removed for #25871
+                       //
+                       // ISourceViewer viewer= getSourceViewer();
+                       // if (viewer == null)
+                       // return;
+                       //
+                       // IRegion region= getCurrentTextRegion(viewer);
+                       // if (region == null)
+                       // return;
+                       //
+                       // highlightRegion(viewer, region);
+                       // activateCursor(viewer);
+               }
+
+               /*
+                * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+                */
+               public void keyReleased(KeyEvent event) {
+
+                       if (!fActive)
+                               return;
+
+                       deactivate();
+               }
+
+               /*
+                * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseDoubleClick(MouseEvent e) {
+               }
+
+               /*
+                * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseDown(MouseEvent event) {
+
+                       if (!fActive)
+                               return;
+
+                       if (event.stateMask != fKeyModifierMask) {
+                               deactivate();
+                               return;
+                       }
+
+                       if (event.button != 1) {
+                               deactivate();
+                               return;
+                       }
+               }
+
+               /*
+                * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseUp(MouseEvent e) {
+
+                       if (!fActive)
+                               return;
+
+                       if (e.button != 1) {
+                               deactivate();
+                               return;
+                       }
+
+                       boolean wasActive = fCursor != null;
+
+                       deactivate();
+
+                       if (wasActive) {
+                               IAction action = getAction("OpenEditor"); //$NON-NLS-1$
+                               if (action != null)
+                                       action.run();
+                       }
+               }
+
+               /*
+                * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+                */
+               public void mouseMove(MouseEvent event) {
+
+                       if (event.widget instanceof Control
+                                       && !((Control) event.widget).isFocusControl()) {
+                               deactivate();
+                               return;
+                       }
+
+                       if (!fActive) {
+                               if (event.stateMask != fKeyModifierMask)
+                                       return;
+                               // modifier was already pressed
+                               fActive = true;
+                       }
+
+                       ISourceViewer viewer = getSourceViewer();
+                       if (viewer == null) {
+                               deactivate();
+                               return;
+                       }
+
+                       StyledText text = viewer.getTextWidget();
+                       if (text == null || text.isDisposed()) {
+                               deactivate();
+                               return;
+                       }
+
+                       if ((event.stateMask & SWT.BUTTON1) != 0
+                                       && text.getSelectionCount() != 0) {
+                               deactivate();
+                               return;
+                       }
+
+                       IRegion region = getCurrentTextRegion(viewer);
+                       if (region == null || region.getLength() == 0) {
+                               repairRepresentation();
+                               return;
+                       }
+
+                       highlightRegion(viewer, region);
+                       activateCursor(viewer);
+               }
+
+               /*
+                * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+                */
+               public void focusGained(FocusEvent e) {
+               }
+
+               /*
+                * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+                */
+               public void focusLost(FocusEvent event) {
+                       deactivate();
+               }
+
+               /*
+                * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+                */
+               public void documentAboutToBeChanged(DocumentEvent event) {
+                       if (fActive && fActiveRegion != null) {
+                               fRememberedPosition = new Position(fActiveRegion.getOffset(),
+                                               fActiveRegion.getLength());
+                               try {
+                                       event.getDocument().addPosition(fRememberedPosition);
+                               } catch (BadLocationException x) {
+                                       fRememberedPosition = null;
+                               }
+                       }
+               }
+
+               /*
+                * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+                */
+               public void documentChanged(DocumentEvent event) {
+                       if (fRememberedPosition != null) {
+                               if (!fRememberedPosition.isDeleted()) {
+
+                                       event.getDocument().removePosition(fRememberedPosition);
+                                       fActiveRegion = new Region(fRememberedPosition.getOffset(),
+                                                       fRememberedPosition.getLength());
+                                       fRememberedPosition = null;
+
+                                       ISourceViewer viewer = getSourceViewer();
+                                       if (viewer != null) {
+                                               StyledText widget = viewer.getTextWidget();
+                                               if (widget != null && !widget.isDisposed()) {
+                                                       widget.getDisplay().asyncExec(new Runnable() {
+                                                               public void run() {
+                                                                       deactivate();
+                                                               }
+                                                       });
+                                               }
+                                       }
+
+                               } else {
+                                       fActiveRegion = null;
+                                       fRememberedPosition = null;
+                                       deactivate();
+                               }
+                       }
+               }
+
+               /*
+                * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
+                *      org.eclipse.jface.text.IDocument)
+                */
+               public void inputDocumentAboutToBeChanged(IDocument oldInput,
+                               IDocument newInput) {
+                       if (oldInput == null)
+                               return;
+                       deactivate();
+                       oldInput.removeDocumentListener(this);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
+                *      org.eclipse.jface.text.IDocument)
+                */
+               public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+                       if (newInput == null)
+                               return;
+                       newInput.addDocumentListener(this);
+               }
+
+               /*
+                * @see PaintListener#paintControl(PaintEvent)
+                */
+               public void paintControl(PaintEvent event) {
+                       if (fActiveRegion == null)
+                               return;
+
+                       ISourceViewer viewer = getSourceViewer();
+                       if (viewer == null)
+                               return;
+
+                       StyledText text = viewer.getTextWidget();
+                       if (text == null || text.isDisposed())
+                               return;
+
+                       int offset = 0;
+                       int length = 0;
+
+                       if (viewer instanceof ITextViewerExtension5) {
+
+                               ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+                               IRegion widgetRange = extension
+                                               .modelRange2WidgetRange(fActiveRegion);
+                               if (widgetRange == null)
+                                       return;
+
+                               offset = widgetRange.getOffset();
+                               length = widgetRange.getLength();
+
+                       } else {
+
+                               IRegion region = viewer.getVisibleRegion();
+                               if (!includes(region, fActiveRegion))
+                                       return;
+
+                               offset = fActiveRegion.getOffset() - region.getOffset();
+                               length = fActiveRegion.getLength();
+                       }
+
+                       // support for bidi
+                       Point minLocation = getMinimumLocation(text, offset, length);
+                       Point maxLocation = getMaximumLocation(text, offset, length);
+
+                       int x1 = minLocation.x;
+                       int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
+                       int y = minLocation.y + text.getLineHeight() - 1;
+
+                       GC gc = event.gc;
+                       if (fColor != null && !fColor.isDisposed())
+                               gc.setForeground(fColor);
+                       gc.drawLine(x1, y, x2, y);
+               }
+
+               private boolean includes(IRegion region, IRegion position) {
+                       return position.getOffset() >= region.getOffset()
+                                       && position.getOffset() + position.getLength() <= region
+                                                       .getOffset()
+                                                       + region.getLength();
+               }
+
+               private Point getMinimumLocation(StyledText text, int offset, int length) {
+                       Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+                       for (int i = 0; i <= length; i++) {
+                               Point location = text.getLocationAtOffset(offset + i);
+
+                               if (location.x < minLocation.x)
+                                       minLocation.x = location.x;
+                               if (location.y < minLocation.y)
+                                       minLocation.y = location.y;
+                       }
+
+                       return minLocation;
+               }
+
+               private Point getMaximumLocation(StyledText text, int offset, int length) {
+                       Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
+
+                       for (int i = 0; i <= length; i++) {
+                               Point location = text.getLocationAtOffset(offset + i);
+
+                               if (location.x > maxLocation.x)
+                                       maxLocation.x = location.x;
+                               if (location.y > maxLocation.y)
+                                       maxLocation.y = location.y;
+                       }
+
+                       return maxLocation;
+               }
+       }
+
+       /**
+        * This action dispatches into two behaviours: If there is no current text
+        * hover, the javadoc is displayed using information presenter. If there is
+        * a current text hover, it is converted into a information presenter in
+        * order to make it sticky.
+        */
+       class InformationDispatchAction extends TextEditorAction {
+
+               /** The wrapped text operation action. */
+               private final TextOperationAction fTextOperationAction;
+
+               /**
+                * Creates a dispatch action.
+                */
+               public InformationDispatchAction(ResourceBundle resourceBundle,
+                               String prefix, final TextOperationAction textOperationAction) {
+                       super(resourceBundle, prefix, PHPEditor.this);
+                       if (textOperationAction == null)
+                               throw new IllegalArgumentException();
+                       fTextOperationAction = textOperationAction;
+               }
+
+               /*
+                * @see org.eclipse.jface.action.IAction#run()
+                */
+               public void run() {
+
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer == null) {
+                               fTextOperationAction.run();
+                               return;
+                       }
+
+                       if (!(sourceViewer instanceof ITextViewerExtension2)) {
+                               fTextOperationAction.run();
+                               return;
+                       }
+
+                       ITextViewerExtension2 textViewerExtension2 = (ITextViewerExtension2) sourceViewer;
+
+                       // does a text hover exist?
+                       ITextHover textHover = textViewerExtension2.getCurrentTextHover();
+                       if (textHover == null) {
+                               fTextOperationAction.run();
+                               return;
+                       }
+
+                       Point hoverEventLocation = textViewerExtension2
+                                       .getHoverEventLocation();
+                       int offset = computeOffsetAtLocation(sourceViewer,
+                                       hoverEventLocation.x, hoverEventLocation.y);
+                       if (offset == -1) {
+                               fTextOperationAction.run();
+                               return;
+                       }
+
+                       try {
+                               // get the text hover content
+                               IDocument document = sourceViewer.getDocument();
+                               String contentType = document.getContentType(offset);
+
+                               final IRegion hoverRegion = textHover.getHoverRegion(
+                                               sourceViewer, offset);
+                               if (hoverRegion == null)
+                                       return;
+
+                               final String hoverInfo = textHover.getHoverInfo(sourceViewer,
+                                               hoverRegion);
+
+                               // with information provider
+                               IInformationProvider informationProvider = new IInformationProvider() {
+                                       /*
+                                        * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer,
+                                        *      int)
+                                        */
+                                       public IRegion getSubject(ITextViewer textViewer, int offset) {
+                                               return hoverRegion;
+                                       }
+
+                                       /*
+                                        * @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer,
+                                        *      org.eclipse.jface.text.IRegion)
+                                        */
+                                       public String getInformation(ITextViewer textViewer,
+                                                       IRegion subject) {
+                                               return hoverInfo;
+                                       }
+                               };
+
+                               fInformationPresenter.setOffset(offset);
+                               fInformationPresenter.setInformationProvider(
+                                               informationProvider, contentType);
+                               fInformationPresenter.showInformation();
+
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               // modified version from TextViewer
+               private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) {
+
+                       StyledText styledText = textViewer.getTextWidget();
+                       IDocument document = textViewer.getDocument();
+
+                       if (document == null)
+                               return -1;
+
+                       try {
+                               int widgetLocation = styledText.getOffsetAtLocation(new Point(
+                                               x, y));
+                               if (textViewer instanceof ITextViewerExtension5) {
+                                       ITextViewerExtension5 extension = (ITextViewerExtension5) textViewer;
+                                       return extension.widgetOffset2ModelOffset(widgetLocation);
+                               } else {
+                                       IRegion visibleRegion = textViewer.getVisibleRegion();
+                                       return widgetLocation + visibleRegion.getOffset();
+                               }
+                       } catch (IllegalArgumentException e) {
+                               return -1;
+                       }
+
+               }
+       };
+
+       /**
+        * This action implements smart home.
+        * 
+        * Instead of going to the start of a line it does the following: - if smart
+        * home/end is enabled and the caret is after the line's first
+        * non-whitespace then the caret is moved directly before it, taking JavaDoc
+        * and multi-line comments into account. - if the caret is before the line's
+        * first non-whitespace the caret is moved to the beginning of the line - if
+        * the caret is at the beginning of the line see first case.
+        * 
+        * @since 3.0
+        */
+       protected class SmartLineStartAction extends LineStartAction {
+
+               /**
+                * Creates a new smart line start action
+                * 
+                * @param textWidget
+                *            the styled text widget
+                * @param doSelect
+                *            a boolean flag which tells if the text up to the beginning
+                *            of the line should be selected
+                */
+               public SmartLineStartAction(final StyledText textWidget,
+                               final boolean doSelect) {
+                       super(textWidget, doSelect);
+               }
+
+               /*
+                * @see org.eclipse.ui.texteditor.AbstractTextEditor.LineStartAction#getLineStartPosition(java.lang.String,
+                *      int, java.lang.String)
+                */
+               protected int getLineStartPosition(final IDocument document,
+                               final String line, final int length, final int offset) {
+
+                       String type = IDocument.DEFAULT_CONTENT_TYPE;
+                       try {
+                               type = TextUtilities.getContentType(document,
+                                               IPHPPartitions.PHP_PARTITIONING, offset, true);
+                       } catch (BadLocationException exception) {
+                               // Should not happen
+                       }
+
+                       int index = super.getLineStartPosition(document, line, length,
+                                       offset);
+                       if (type.equals(IPHPPartitions.PHP_PHPDOC_COMMENT)
+                                       || type.equals(IPHPPartitions.PHP_MULTILINE_COMMENT)) {
+                               if (index < length - 1 && line.charAt(index) == '*'
+                                               && line.charAt(index + 1) != '/') {
+                                       do {
+                                               ++index;
+                                       } while (index < length
+                                                       && Character.isWhitespace(line.charAt(index)));
+                               }
+                       } else {
+                               if (index < length - 1 && line.charAt(index) == '/'
+                                               && line.charAt(index + 1) == '/') {
+                                       index++;
+                                       do {
+                                               ++index;
+                                       } while (index < length
+                                                       && Character.isWhitespace(line.charAt(index)));
+                               }
+                       }
+                       return index;
+               }
+       }
+
+       /**
+        * Text navigation action to navigate to the next sub-word.
+        * 
+        * @since 3.0
+        */
+       protected abstract class NextSubWordAction extends TextNavigationAction {
+
+               protected JavaWordIterator fIterator = new JavaWordIterator();
+
+               /**
+                * Creates a new next sub-word action.
+                * 
+                * @param code
+                *            Action code for the default operation. Must be an action
+                *            code from
+                * @see org.eclipse.swt.custom.ST.
+                */
+               protected NextSubWordAction(int code) {
+                       super(getSourceViewer().getTextWidget(), code);
+               }
+
+               /*
+                * @see org.eclipse.jface.action.IAction#run()
+                */
+               public void run() {
+                       // Check whether we are in a java code partition and the preference
+                       // is
+                       // enabled
+                       final IPreferenceStore store = getPreferenceStore();
+                       if (!store
+                                       .getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
+                               super.run();
+                               return;
+                       }
+
+                       final ISourceViewer viewer = getSourceViewer();
+                       final IDocument document = viewer.getDocument();
+                       fIterator
+                                       .setText((CharacterIterator) new DocumentCharacterIterator(
+                                                       document));
+                       int position = widgetOffset2ModelOffset(viewer, viewer
+                                       .getTextWidget().getCaretOffset());
+                       if (position == -1)
+                               return;
+
+                       int next = findNextPosition(position);
+                       if (next != BreakIterator.DONE) {
+                               setCaretPosition(next);
+                               getTextWidget().showSelection();
+                               fireSelectionChanged();
+                       }
+
+               }
+               
+               /**
+                * Finds the next position after the given position.
+                * 
+                * @param position
+                *            the current position
+                * @return the next position
+                */
+               protected int findNextPosition(int position) {
+                       ISourceViewer viewer = getSourceViewer();
+                       int widget = -1;
+                       while (position != BreakIterator.DONE && widget == -1) { // TODO:
+                               // optimize
+                               position = fIterator.following(position);
+                               if (position != BreakIterator.DONE)
+                                       widget = modelOffset2WidgetOffset(viewer, position);
+                       }
+                       return position;
+               }
+
+               /**
+                * Sets the caret position to the sub-word boundary given with
+                * <code>position</code>.
+                * 
+                * @param position
+                *            Position where the action should move the caret
+                */
+               protected abstract void setCaretPosition(int position);
+       }
+
+       /**
+        * Text navigation action to navigate to the next sub-word.
+        * 
+        * @since 3.0
+        */
+       protected class NavigateNextSubWordAction extends NextSubWordAction {
+
+               /**
+                * Creates a new navigate next sub-word action.
+                */
+               public NavigateNextSubWordAction() {
+                       super(ST.WORD_NEXT);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
+                */
+               protected void setCaretPosition(final int position) {
+                       getTextWidget().setCaretOffset(
+                                       modelOffset2WidgetOffset(getSourceViewer(), position));
+               }
+       }
+
+       /**
+        * Text operation action to delete the next sub-word.
+        * 
+        * @since 3.0
+        */
+       protected class DeleteNextSubWordAction extends NextSubWordAction implements
+                       IUpdate {
+
+               /**
+                * Creates a new delete next sub-word action.
+                */
+               public DeleteNextSubWordAction() {
+                       super(ST.DELETE_WORD_NEXT);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
+                */
+               protected void setCaretPosition(final int position) {
+                       if (!validateEditorInputState())
+                               return;
+
+                       final ISourceViewer viewer = getSourceViewer();
+                       final int caret = widgetOffset2ModelOffset(viewer, viewer
+                                       .getTextWidget().getCaretOffset());
+
+                       try {
+                               viewer.getDocument().replace(caret, position - caret, ""); //$NON-NLS-1$
+                       } catch (BadLocationException exception) {
+                               // Should not happen
+                       }
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#findNextPosition(int)
+                */
+               protected int findNextPosition(int position) {
+                       return fIterator.following(position);
+               }
+
+               /*
+                * @see org.eclipse.ui.texteditor.IUpdate#update()
+                */
+               public void update() {
+                       setEnabled(isEditorInputModifiable());
+               }
+       }
+
+       /**
+        * Text operation action to select the next sub-word.
+        * 
+        * @since 3.0
+        */
+       protected class SelectNextSubWordAction extends NextSubWordAction {
+
+               /**
+                * Creates a new select next sub-word action.
+                */
+               public SelectNextSubWordAction() {
+                       super(ST.SELECT_WORD_NEXT);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
+                */
+               protected void setCaretPosition(final int position) {
+                       final ISourceViewer viewer = getSourceViewer();
+
+                       final StyledText text = viewer.getTextWidget();
+                       if (text != null && !text.isDisposed()) {
+
+                               final Point selection = text.getSelection();
+                               final int caret = text.getCaretOffset();
+                               final int offset = modelOffset2WidgetOffset(viewer, position);
+
+                               if (caret == selection.x)
+                                       text.setSelectionRange(selection.y, offset - selection.y);
+                               else
+                                       text.setSelectionRange(selection.x, offset - selection.x);
+                       }
+               }
+       }
+
+       /**
+        * Text navigation action to navigate to the previous sub-word.
+        * 
+        * @since 3.0
+        */
+       protected abstract class PreviousSubWordAction extends TextNavigationAction {
+
+               protected JavaWordIterator fIterator = new JavaWordIterator();
+
+               /**
+                * Creates a new previous sub-word action.
+                * 
+                * @param code
+                *            Action code for the default operation. Must be an action
+                *            code from
+                * @see org.eclipse.swt.custom.ST.
+                */
+               protected PreviousSubWordAction(final int code) {
+                       super(getSourceViewer().getTextWidget(), code);
+               }
+
+               /*
+                * @see org.eclipse.jface.action.IAction#run()
+                */
+               public void run() {
+                       // Check whether we are in a java code partition and the preference
+                       // is
+                       // enabled
+                       final IPreferenceStore store = getPreferenceStore();
+                       if (!store
+                                       .getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
+                               super.run();
+                               return;
+                       }
+
+                       final ISourceViewer viewer = getSourceViewer();
+                       final IDocument document = viewer.getDocument();
+                       fIterator
+                                       .setText((CharacterIterator) new DocumentCharacterIterator(
+                                                       document));
+                       int position = widgetOffset2ModelOffset(viewer, viewer
+                                       .getTextWidget().getCaretOffset());
+                       if (position == -1)
+                               return;
+
+                       int previous = findPreviousPosition(position);
+                       if (previous != BreakIterator.DONE) {
+                               setCaretPosition(previous);
+                               getTextWidget().showSelection();
+                               fireSelectionChanged();
+                       }
+
+               }
+
+               /**
+                * Finds the previous position before the given position.
+                * 
+                * @param position
+                *            the current position
+                * @return the previous position
+                */
+               protected int findPreviousPosition(int position) {
+                       ISourceViewer viewer = getSourceViewer();
+                       int widget = -1;
+                       while (position != BreakIterator.DONE && widget == -1) { // TODO:
+                               // optimize
+                               position = fIterator.preceding(position);
+                               if (position != BreakIterator.DONE)
+                                       widget = modelOffset2WidgetOffset(viewer, position);
+                       }
+                       return position;
+               }
+
+               /**
+                * Sets the caret position to the sub-word boundary given with
+                * <code>position</code>.
+                * 
+                * @param position
+                *            Position where the action should move the caret
+                */
+               protected abstract void setCaretPosition(int position);
+       }
+
+       /**
+        * Text navigation action to navigate to the previous sub-word.
+        * 
+        * @since 3.0
+        */
+       protected class NavigatePreviousSubWordAction extends PreviousSubWordAction {
+
+               /**
+                * Creates a new navigate previous sub-word action.
+                */
+               public NavigatePreviousSubWordAction() {
+                       super(ST.WORD_PREVIOUS);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
+                */
+               protected void setCaretPosition(final int position) {
+                       getTextWidget().setCaretOffset(
+                                       modelOffset2WidgetOffset(getSourceViewer(), position));
+               }
+       }
+
+       /**
+        * Text operation action to delete the previous sub-word.
+        * 
+        * @since 3.0
+        */
+       protected class DeletePreviousSubWordAction extends PreviousSubWordAction
+                       implements IUpdate {
+
+               /**
+                * Creates a new delete previous sub-word action.
+                */
+               public DeletePreviousSubWordAction() {
+                       super(ST.DELETE_WORD_PREVIOUS);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
+                */
+               protected void setCaretPosition(final int position) {
+                       if (!validateEditorInputState())
+                               return;
+
+                       final ISourceViewer viewer = getSourceViewer();
+                       final int caret = widgetOffset2ModelOffset(viewer, viewer
+                                       .getTextWidget().getCaretOffset());
+
+                       try {
+                               viewer.getDocument().replace(position, caret - position, ""); //$NON-NLS-1$
+                       } catch (BadLocationException exception) {
+                               // Should not happen
+                       }
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#findPreviousPosition(int)
+                */
+               protected int findPreviousPosition(int position) {
+                       return fIterator.preceding(position);
+               }
+
+               /*
+                * @see org.eclipse.ui.texteditor.IUpdate#update()
+                */
+               public void update() {
+                       setEnabled(isEditorInputModifiable());
+               }
+       }
+
+       /**
+        * Text operation action to select the previous sub-word.
+        * 
+        * @since 3.0
+        */
+       protected class SelectPreviousSubWordAction extends PreviousSubWordAction {
+
+               /**
+                * Creates a new select previous sub-word action.
+                */
+               public SelectPreviousSubWordAction() {
+                       super(ST.SELECT_WORD_PREVIOUS);
+               }
+
+               /*
+                * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
+                */
+               protected void setCaretPosition(final int position) {
+                       final ISourceViewer viewer = getSourceViewer();
+
+                       final StyledText text = viewer.getTextWidget();
+                       if (text != null && !text.isDisposed()) {
+
+                               final Point selection = text.getSelection();
+                               final int caret = text.getCaretOffset();
+                               final int offset = modelOffset2WidgetOffset(viewer, position);
+
+                               if (caret == selection.x)
+                                       text.setSelectionRange(selection.y, offset - selection.y);
+                               else
+                                       text.setSelectionRange(selection.x, offset - selection.x);
+                       }
+               }
+       }
+
+       // static protected class AnnotationAccess implements IAnnotationAccess {
+       // /*
+       // * @see
+       // org.eclipse.jface.text.source.IAnnotationAccess#getType(org.eclipse.jface.text.source.Annotation)
+       // */
+       // public Object getType(Annotation annotation) {
+       // if (annotation instanceof IJavaAnnotation) {
+       // IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
+       // // if (javaAnnotation.isRelevant())
+       // // return javaAnnotation.getAnnotationType();
+       // }
+       // return null;
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.jface.text.source.IAnnotationAccess#isMultiLine(org.eclipse.jface.text.source.Annotation)
+       // */
+       // public boolean isMultiLine(Annotation annotation) {
+       // return true;
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.jface.text.source.IAnnotationAccess#isTemporary(org.eclipse.jface.text.source.Annotation)
+       // */
+       // public boolean isTemporary(Annotation annotation) {
+       // if (annotation instanceof IJavaAnnotation) {
+       // IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
+       // if (javaAnnotation.isRelevant())
+       // return javaAnnotation.isTemporary();
+       // }
+       // return false;
+       // }
+       // };
+
+       private class PropertyChangeListener implements
+                       org.eclipse.core.runtime.Preferences.IPropertyChangeListener {
+               /*
+                * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+                */
+               public void propertyChange(
+                               org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+                       handlePreferencePropertyChanged(event);
+               }
+       };
+
+       /**
+        * Finds and marks occurrence annotations.
+        * 
+        * @since 3.0
+        */
+       class OccurrencesFinderJob extends Job {
+
+               private IDocument fDocument;
+
+               private ISelection fSelection;
+
+               private ISelectionValidator fPostSelectionValidator;
+
+               private boolean fCanceled = false;
+
+               private IProgressMonitor fProgressMonitor;
+
+               private Position[] fPositions;
+
+               public OccurrencesFinderJob(IDocument document, Position[] positions,
+                               ISelection selection) {
+                       super(PHPEditorMessages.JavaEditor_markOccurrences_job_name);
+                       fDocument = document;
+                       fSelection = selection;
+                       fPositions = positions;
+
+                       if (getSelectionProvider() instanceof ISelectionValidator)
+                               fPostSelectionValidator = (ISelectionValidator) getSelectionProvider();
+               }
+
+               // cannot use cancel() because it is declared final
+               void doCancel() {
+                       fCanceled = true;
+                       cancel();
+               }
+
+               private boolean isCanceled() {
+                       return fCanceled
+                                       || fProgressMonitor.isCanceled()
+                                       || fPostSelectionValidator != null
+                                       && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection)
+                                       || LinkedModeModel.hasInstalledModel(fDocument);
+               }
+
+               /*
+                * @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
+                */
+               public IStatus run(IProgressMonitor progressMonitor) {
+
+                       fProgressMonitor = progressMonitor;
+
+                       if (isCanceled())
+                               return Status.CANCEL_STATUS;
+
+                       ITextViewer textViewer = getViewer();
+                       if (textViewer == null)
+                               return Status.CANCEL_STATUS;
+
+                       IDocument document = textViewer.getDocument();
+                       if (document == null)
+                               return Status.CANCEL_STATUS;
+
+                       IDocumentProvider documentProvider = getDocumentProvider();
+                       if (documentProvider == null)
+                               return Status.CANCEL_STATUS;
+
+                       IAnnotationModel annotationModel = documentProvider
+                                       .getAnnotationModel(getEditorInput());
+                       if (annotationModel == null)
+                               return Status.CANCEL_STATUS;
+
+                       // Add occurrence annotations
+                       int length = fPositions.length;
+                       Map annotationMap = new HashMap(length);
+                       for (int i = 0; i < length; i++) {
+
+                               if (isCanceled())
+                                       return Status.CANCEL_STATUS;
+
+                               String message;
+                               Position position = fPositions[i];
+
+                               // Create & add annotation
+                               try {
+                                       message = document.get(position.offset, position.length);
+                               } catch (BadLocationException ex) {
+                                       // Skip this match
+                                       continue;
+                               }
+                               annotationMap
+                                               .put(
+                                                               new Annotation(
+                                                                               "net.sourceforge.phpdt.ui.occurrences", false, message), //$NON-NLS-1$
+                                                               position);
+                       }
+
+                       if (isCanceled())
+                               return Status.CANCEL_STATUS;
+
+                       synchronized (getLockObject(annotationModel)) {
+                               if (annotationModel instanceof IAnnotationModelExtension) {
+                                       ((IAnnotationModelExtension) annotationModel)
+                                                       .replaceAnnotations(fOccurrenceAnnotations,
+                                                                       annotationMap);
+                               } else {
+                                       removeOccurrenceAnnotations();
+                                       Iterator iter = annotationMap.entrySet().iterator();
+                                       while (iter.hasNext()) {
+                                               Map.Entry mapEntry = (Map.Entry) iter.next();
+                                               annotationModel.addAnnotation((Annotation) mapEntry
+                                                               .getKey(), (Position) mapEntry.getValue());
+                                       }
+                               }
+                               fOccurrenceAnnotations = (Annotation[]) annotationMap.keySet()
+                                               .toArray(new Annotation[annotationMap.keySet().size()]);
+                       }
+
+                       return Status.OK_STATUS;
+               }
+       }
+
+       /**
+        * Cancels the occurrences finder job upon document changes.
+        * 
+        * @since 3.0
+        */
+       class OccurrencesFinderJobCanceler implements IDocumentListener,
+                       ITextInputListener {
+
+               public void install() {
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer == null)
+                               return;
+
+                       StyledText text = sourceViewer.getTextWidget();
+                       if (text == null || text.isDisposed())
+                               return;
+
+                       sourceViewer.addTextInputListener(this);
+
+                       IDocument document = sourceViewer.getDocument();
+                       if (document != null)
+                               document.addDocumentListener(this);
+               }
+
+               public void uninstall() {
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer != null)
+                               sourceViewer.removeTextInputListener(this);
+
+                       IDocumentProvider documentProvider = getDocumentProvider();
+                       if (documentProvider != null) {
+                               IDocument document = documentProvider
+                                               .getDocument(getEditorInput());
+                               if (document != null)
+                                       document.removeDocumentListener(this);
+                       }
+               }
+
+               /*
+                * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+                */
+               public void documentAboutToBeChanged(DocumentEvent event) {
+                       if (fOccurrencesFinderJob != null)
+                               fOccurrencesFinderJob.doCancel();
+               }
+
+               /*
+                * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+                */
+               public void documentChanged(DocumentEvent event) {
+               }
+
+               /*
+                * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
+                *      org.eclipse.jface.text.IDocument)
+                */
+               public void inputDocumentAboutToBeChanged(IDocument oldInput,
+                               IDocument newInput) {
+                       if (oldInput == null)
+                               return;
+
+                       oldInput.removeDocumentListener(this);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
+                *      org.eclipse.jface.text.IDocument)
+                */
+               public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+                       if (newInput == null)
+                               return;
+                       newInput.addDocumentListener(this);
+               }
+       }
+
+       /**
+        * Internal activation listener.
+        * 
+        * @since 3.0
+        */
+       private class ActivationListener implements IWindowListener {
+
+               /*
+                * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
+                * @since 3.1
+                */
+               public void windowActivated(IWorkbenchWindow window) {
+                       if (window == getEditorSite().getWorkbenchWindow()
+                                       && fMarkOccurrenceAnnotations && isActivePart()) {
+                               fForcedMarkOccurrencesSelection = getSelectionProvider()
+                                               .getSelection();
+                               SelectionListenerWithASTManager
+                                               .getDefault()
+                                               .forceSelectionChange(
+                                                               PHPEditor.this,
+                                                               (ITextSelection) fForcedMarkOccurrencesSelection);
+                       }
+               }
+
+               /*
+                * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
+                * @since 3.1
+                */
+               public void windowDeactivated(IWorkbenchWindow window) {
+                       if (window == getEditorSite().getWorkbenchWindow()
+                                       && fMarkOccurrenceAnnotations && isActivePart())
+                               removeOccurrenceAnnotations();
+               }
+
+               /*
+                * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
+                * @since 3.1
+                */
+               public void windowClosed(IWorkbenchWindow window) {
+               }
+
+               /*
+                * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
+                * @since 3.1
+                */
+               public void windowOpened(IWorkbenchWindow window) {
+               }
+       }
+
+       /**
+        * Updates the selection in the editor's widget with the selection of the
+        * outline page.
+        */
+       class OutlineSelectionChangedListener extends
+                       AbstractSelectionChangedListener {
+               public void selectionChanged(SelectionChangedEvent event) {
+                       doSelectionChanged(event);
+               }
+       }
+
+       /**
+        * The internal shell activation listener for updating occurrences.
+        * 
+        * @since 3.0
+        */
+       private ActivationListener fActivationListener = new ActivationListener();
+
+       private ISelectionListenerWithAST fPostSelectionListenerWithAST;
+
+       private OccurrencesFinderJob fOccurrencesFinderJob;
+
+       /** The occurrences finder job canceler */
+       private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler;
+
+       /**
+        * Holds the current occurrence annotations.
+        * 
+        * @since 3.0
+        */
+       private Annotation[] fOccurrenceAnnotations = null;
+
+       /**
+        * Tells whether all occurrences of the element at the current caret
+        * location are automatically marked in this editor.
+        * 
+        * @since 3.0
+        */
+       private boolean fMarkOccurrenceAnnotations;
+
+       /**
+        * The selection used when forcing occurrence marking through code.
+        * 
+        * @since 3.0
+        */
+       private ISelection fForcedMarkOccurrencesSelection;
+
+       /**
+        * The document modification stamp at the time when the last occurrence
+        * marking took place.
+        * 
+        * @since 3.1
+        */
+       private long fMarkOccurrenceModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+
+       /**
+        * The region of the word under the caret used to when computing the current
+        * occurrence markings.
+        * 
+        * @since 3.1
+        */
+       private IRegion fMarkOccurrenceTargetRegion;
+
+       /**
+        * Tells whether the occurrence annotations are sticky i.e. whether they
+        * stay even if there's no valid Java element at the current caret position.
+        * Only valid if {@link #fMarkOccurrenceAnnotations} is <code>true</code>.
+        * 
+        * @since 3.0
+        */
+       private boolean fStickyOccurrenceAnnotations;
+
+       /** Preference key for the link color */
+       private final static String LINK_COLOR = PreferenceConstants.EDITOR_LINK_COLOR;
+
+       /** Preference key for compiler task tags */
+       private final static String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;
+
+       // protected PHPActionGroup fActionGroups;
+       // /** The outline page */
+       // private AbstractContentOutlinePage fOutlinePage;
+       /** The outline page */
+       protected JavaOutlinePage fOutlinePage;
+
+       /** Outliner context menu Id */
+       protected String fOutlinerContextMenuId;
+
+       /**
+        * Indicates whether this editor should react on outline page selection
+        * changes
+        */
+       private int fIgnoreOutlinePageSelection;
+
+       /** The outline page selection updater */
+       // private OutlinePageSelectionUpdater fUpdater;
+       // protected PHPSyntaxParserThread fValidationThread = null;
+       // private IPreferenceStore fPHPPrefStore;
+       /** The selection changed listener */
+       // protected ISelectionChangedListener fSelectionChangedListener = new
+       // SelectionChangedListener();
+       /**
+        * The editor selection changed listener.
+        * 
+        * @since 3.0
+        */
+       private EditorSelectionChangedListener fEditorSelectionChangedListener;
+
+       /** The selection changed listener */
+       protected AbstractSelectionChangedListener fOutlineSelectionChangedListener = new OutlineSelectionChangedListener();
+
+       /** The editor's bracket matcher */
+       private PHPPairMatcher fBracketMatcher = new PHPPairMatcher(BRACKETS);
+
+       /** The line number ruler column */
+       // private LineNumberRulerColumn fLineNumberRulerColumn;
+       /** This editor's encoding support */
+       private DefaultEncodingSupport fEncodingSupport;
+
+       /** The mouse listener */
+       private MouseClickListener fMouseListener;
+
+       /**
+        * Indicates whether this editor is about to update any annotation views.
+        * 
+        * @since 3.0
+        */
+       private boolean fIsUpdatingAnnotationViews = false;
+
+       /**
+        * The marker that served as last target for a goto marker request.
+        * 
+        * @since 3.0
+        */
+       private IMarker fLastMarkerTarget = null;
+
+       protected CompositeActionGroup fActionGroups;
+
+       protected CompositeActionGroup fContextMenuGroup;
+
+       /**
+        * This editor's projection support
+        * 
+        * @since 3.0
+        */
+       private ProjectionSupport fProjectionSupport;
+
+       /**
+        * This editor's projection model updater
+        * 
+        * @since 3.0
+        */
+       private IJavaFoldingStructureProvider fProjectionModelUpdater;
+
+       /**
+        * The override and implements indicator manager for this editor.
+        * 
+        * @since 3.0
+        */
+       // protected OverrideIndicatorManager fOverrideIndicatorManager;
+       /**
+        * The action group for folding.
+        * 
+        * @since 3.0
+        */
+       private FoldingActionGroup fFoldingGroup;
+
+       /** The information presenter. */
+       private InformationPresenter fInformationPresenter;
+
+       /** The annotation access */
+       // protected IAnnotationAccess fAnnotationAccess = new AnnotationAccess();
+       /** The overview ruler */
+       protected OverviewRuler isOverviewRulerVisible;
+
+       /** The source viewer decoration support */
+       // protected SourceViewerDecorationSupport fSourceViewerDecorationSupport;
+       /** The overview ruler */
+       // protected OverviewRuler fOverviewRuler;
+       /** The preference property change listener for java core. */
+       private org.eclipse.core.runtime.Preferences.IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
+
+       /**
+        * Returns the most narrow java element including the given offset
+        * 
+        * @param offset
+        *            the offset inside of the requested element
+        */
+       abstract protected IJavaElement getElementAt(int offset);
+
+       /**
+        * Returns the java element of this editor's input corresponding to the
+        * given IJavaElement
+        */
+       abstract protected IJavaElement getCorrespondingElement(IJavaElement element);
+
+       /**
+        * Sets the input of the editor's outline page.
+        */
+       abstract protected void setOutlinePageInput(JavaOutlinePage page,
+                       IEditorInput input);
+
+       /**
+        * Default constructor.
+        */
+       public PHPEditor() {
+               super();                
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeKeyBindingScopes()
+        */
+       protected void initializeKeyBindingScopes() {
+               setKeyBindingScopes(new String[] { "net.sourceforge.phpdt.ui.phpEditorScope" }); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor()
+        */
+       protected void initializeEditor() {
+               // jsurfer old code
+               // JavaTextTools textTools =
+               // PHPeclipsePlugin.getDefault().getJavaTextTools();
+               // setSourceViewerConfiguration(new
+               // PHPSourceViewerConfiguration(textTools,
+               // this, IPHPPartitions.PHP_PARTITIONING)); //,
+               // IJavaPartitions.JAVA_PARTITIONING));
+               IPreferenceStore store = createCombinedPreferenceStore(null);
+               setPreferenceStore(store);
+               JavaTextTools textTools = WebUI.getDefault()
+                               .getJavaTextTools();
+               setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools
+                               .getColorManager(), store, this,
+                               IPHPPartitions.PHP_PARTITIONING));
+               
+               // TODO changed in 3.x ?
+               // setRangeIndicator(new DefaultRangeIndicator());
+               // if
+               // (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
+               // fUpdater = new OutlinePageSelectionUpdater();
+               // jsurfer end
+
+               // IPreferenceStore store= createCombinedPreferenceStore(null);
+               // setPreferenceStore(store);
+               // JavaTextTools textTools=
+               // PHPeclipsePlugin.getDefault().getJavaTextTools();
+               // setSourceViewerConfiguration(new
+               // JavaSourceViewerConfiguration(textTools.getColorManager(), store,
+               // this, IJavaPartitions.JAVA_PARTITIONING));
+               fMarkOccurrenceAnnotations = store
+                               .getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES);
+               fStickyOccurrenceAnnotations = store
+                               .getBoolean(PreferenceConstants.EDITOR_STICKY_OCCURRENCES);
+               // fMarkTypeOccurrences=
+               // store.getBoolean(PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES);
+               // fMarkMethodOccurrences=
+               // store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES);
+               // fMarkConstantOccurrences=
+               // store.getBoolean(PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES);
+               // fMarkFieldOccurrences=
+               // store.getBoolean(PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES);
+               // fMarkLocalVariableypeOccurrences=
+               // store.getBoolean(PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES);
+               // fMarkExceptions=
+               // store.getBoolean(PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES);
+               // fMarkImplementors=
+               // store.getBoolean(PreferenceConstants.EDITOR_MARK_IMPLEMENTORS);
+               // fMarkMethodExitPoints=
+               // store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS);
+
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#updatePropertyDependentActions()
+        */
+       protected void updatePropertyDependentActions() {
+               super.updatePropertyDependentActions();
+               if (fEncodingSupport != null)
+                       fEncodingSupport.reset();
+       }
+
+       /*
+        * Update the hovering behavior depending on the preferences.
+        */
+       private void updateHoverBehavior() {
+               SourceViewerConfiguration configuration = getSourceViewerConfiguration();
+               String[] types = configuration
+                               .getConfiguredContentTypes(getSourceViewer());
+
+               for (int i = 0; i < types.length; i++) {
+
+                       String t = types[i];
+
+                       int[] stateMasks = configuration.getConfiguredTextHoverStateMasks(
+                                       getSourceViewer(), t);
+
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer instanceof ITextViewerExtension2) {
+                               if (stateMasks != null) {
+                                       for (int j = 0; j < stateMasks.length; j++) {
+                                               int stateMask = stateMasks[j];
+                                               ITextHover textHover = configuration.getTextHover(
+                                                               sourceViewer, t, stateMask);
+                                               ((ITextViewerExtension2) sourceViewer).setTextHover(
+                                                               textHover, t, stateMask);
+                                       }
+                               } else {
+                                       ITextHover textHover = configuration.getTextHover(
+                                                       sourceViewer, t);
+                                       ((ITextViewerExtension2) sourceViewer).setTextHover(
+                                                       textHover, t,
+                                                       ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+                               }
+                       } else
+                               sourceViewer.setTextHover(configuration.getTextHover(
+                                               sourceViewer, t), t);
+               }
+       }
+
+       public void updatedTitleImage(Image image) {
+               setTitleImage(image);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
+        */
+       public Object getViewPartInput() {
+               return getEditorInput().getAdapter(IResource.class);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(ISelection)
+        */
+       protected void doSetSelection(ISelection selection) {
+               super.doSetSelection(selection);
+               synchronizeOutlinePageSelection();
+       }
+
+       boolean isFoldingEnabled() {
+               return WebUI.getDefault().getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_FOLDING_ENABLED);
+       }
+
+       /*
+        * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.
+        *      widgets.Composite)
+        */
+       public void createPartControl(Composite parent) {
+               super.createPartControl(parent);
+
+               // fSourceViewerDecorationSupport.install(getPreferenceStore());
+
+               ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
+
+               fProjectionSupport = new ProjectionSupport(projectionViewer,
+                               getAnnotationAccess(), getSharedColors());
+               fProjectionSupport
+                               .addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$
+               fProjectionSupport
+                               .addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$
+               fProjectionSupport
+                               .setHoverControlCreator(new IInformationControlCreator() {
+                                       public IInformationControl createInformationControl(
+                                                       Shell shell) {
+                                               return new CustomSourceInformationControl(shell,
+                                                               IDocument.DEFAULT_CONTENT_TYPE);
+                                       }
+                               });
+               fProjectionSupport.install();
+
+               fProjectionModelUpdater = WebUI.getDefault()
+                               .getFoldingStructureProviderRegistry()
+                               .getCurrentFoldingProvider();
+               if (fProjectionModelUpdater != null)
+                       fProjectionModelUpdater.install(this, projectionViewer);
+
+               if (isFoldingEnabled())
+                       projectionViewer.doOperation(ProjectionViewer.TOGGLE);
+               Preferences preferences = PHPeclipsePlugin.getDefault()
+                               .getPluginPreferences();
+               preferences.addPropertyChangeListener(fPropertyChangeListener);
+               IInformationControlCreator informationControlCreator = new IInformationControlCreator() {
+                       public IInformationControl createInformationControl(Shell parent) {
+                               boolean cutDown = false;
+                               int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
+                               return new DefaultInformationControl(parent, SWT.RESIZE, style,
+                                               new HTMLTextPresenter(cutDown));
+                       }
+               };
+
+               fInformationPresenter = new InformationPresenter(
+                               informationControlCreator);
+               fInformationPresenter.setSizeConstraints(60, 10, true, true);
+               fInformationPresenter.install(getSourceViewer());
+
+               fEditorSelectionChangedListener = new EditorSelectionChangedListener();
+               fEditorSelectionChangedListener.install(getSelectionProvider());
+
+               if (isBrowserLikeLinks())
+                       enableBrowserLikeLinks();
+
+               if (PreferenceConstants.getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE))
+                       enableOverwriteMode(false);
+
+               if (fMarkOccurrenceAnnotations)
+                       installOccurrencesFinder();
+
+               PlatformUI.getWorkbench().addWindowListener(fActivationListener);
+               
+               /*
+                * start of EDITOR_SAVE_ON_BLUR
+                * ed_mann
+                */
+               final PHPEditor editor = this;
+               FocusListener focusListener = new FocusListener() {
+                       
+                     public void focusGained(FocusEvent e) {
+                         return;
+                       }
+
+                       public void focusLost(FocusEvent e) {
+                               //viewer.get
+                               if(editor.isDirty() && WebUI.getDefault().getPreferenceStore()
+                                                       .getBoolean(PreferenceConstants.EDITOR_SAVE_ON_BLUR)){
+                                       editor.doSave(null);
+                               }
+                       }
+                     };
+                 projectionViewer.getTextWidget().addFocusListener(focusListener);
+                       /*
+                        * end of EDITOR_SAVE_ON_BLUR
+                        * ed_mann
+                        */
+                 
+               setWordWrap();
+       }
+
+       private void setWordWrap() {
+               if (getSourceViewer() != null) {
+                       getSourceViewer().getTextWidget().setWordWrap(
+                                       WebUI.getDefault().getPreferenceStore()
+                                                       .getBoolean(PreferenceConstants.EDITOR_WRAP_WORDS));
+               }
+       }
+
+       protected void configureSourceViewerDecorationSupport(
+                       SourceViewerDecorationSupport support) {
+
+               support.setCharacterPairMatcher(fBracketMatcher);
+               support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS,
+                               MATCHING_BRACKETS_COLOR);
+
+               super.configureSourceViewerDecorationSupport(support);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#gotoMarker(org.eclipse.core.resources.IMarker)
+        */
+       public void gotoMarker(IMarker marker) {
+               fLastMarkerTarget = marker;
+               if (!fIsUpdatingAnnotationViews) {
+                       super.gotoMarker(marker);
+               }
+       }
+
+       /**
+        * 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 gotoAnnotation(boolean forward) {
+               ITextSelection selection = (ITextSelection) getSelectionProvider()
+                               .getSelection();
+               Position position = new Position(0, 0);
+               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 = 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 lock object for the given annotation model.
+        * 
+        * @param annotationModel
+        *            the annotation model
+        * @return the annotation model's lock object
+        * @since 3.0
+        */
+       private Object getLockObject(IAnnotationModel annotationModel) {
+               if (annotationModel instanceof ISynchronizable)
+                       return ((ISynchronizable) annotationModel).getLockObject();
+               else
+                       return annotationModel;
+       }
+
+       /**
+        * 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
+               }
+       }
+
+       /**
+        * Returns this document's complete text.
+        * 
+        * @return the document's complete text
+        */
+       public String get() {
+               IDocument doc = this.getDocumentProvider().getDocument(
+                               this.getEditorInput());
+               return doc.get();
+       }
+
+       /**
+        * Sets the outliner's context menu ID.
+        */
+       protected void setOutlinerContextMenuId(String menuId) {
+               fOutlinerContextMenuId = menuId;
+       }
+
+       /**
+        * Returns the standard action group of this editor.
+        */
+       protected ActionGroup getActionGroup() {
+               return fActionGroups;
+       }
+
+       // public JavaOutlinePage getfOutlinePage() {
+       // return fOutlinePage;
+       // }
+
+       /**
+        * The <code>PHPEditor</code> implementation of this
+        * <code>AbstractTextEditor</code> method extend the actions to add those
+        * specific to the receiver
+        */
+       protected void createActions() {
+               super.createActions();
+
+               ActionGroup oeg, ovg, jsg, sg;
+               fActionGroups = new CompositeActionGroup(
+                               new ActionGroup[] { oeg = new OpenEditorActionGroup(this),
+                               // sg= new ShowActionGroup(this),
+                               // ovg= new OpenViewActionGroup(this),
+                               // jsg= new JavaSearchActionGroup(this)
+                               });
+               fContextMenuGroup = new CompositeActionGroup(new ActionGroup[] { oeg });
+               // , ovg, sg, jsg});
+
+               fFoldingGroup = new FoldingActionGroup(this, getViewer());
+
+               // ResourceAction resAction = new
+               // TextOperationAction(PHPEditorMessages.getResourceBundle(),
+               // "ShowJavaDoc.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$
+               // resAction = new
+               // InformationDispatchAction(PHPEditorMessages.getResourceBundle(),
+               // "ShowJavaDoc.", (TextOperationAction) resAction); //$NON-NLS-1$
+               // resAction.setActionDefinitionId(net.sourceforge.phpdt.ui.actions.PHPEditorActionDefinitionIds.SHOW_JAVADOC);
+               // setAction("ShowJavaDoc", resAction); //$NON-NLS-1$
+
+               // WorkbenchHelp.setHelp(resAction,
+               // IJavaHelpContextIds.SHOW_JAVADOC_ACTION);
+
+               Action action = new GotoMatchingBracketAction(this);
+               action
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
+               setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action);
+
+               // action= new
+               // TextOperationAction(PHPEditorMessages.getResourceBundle(),"ShowOutline.",
+               // this, JavaSourceViewer.SHOW_OUTLINE, true); //$NON-NLS-1$
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE);
+               // setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE, action);
+               // // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.SHOW_OUTLINE_ACTION);
+               //
+               // action= new
+               // TextOperationAction(PHPEditorMessages.getResourceBundle(),"OpenStructure.",
+               // this, JavaSourceViewer.OPEN_STRUCTURE, true); //$NON-NLS-1$
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_STRUCTURE);
+               // setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_STRUCTURE,
+               // action);
+               // // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.OPEN_STRUCTURE_ACTION);
+               //
+               // action= new
+               // TextOperationAction(PHPEditorMessages.getResourceBundle(),"OpenHierarchy.",
+               // this, JavaSourceViewer.SHOW_HIERARCHY, true); //$NON-NLS-1$
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_HIERARCHY);
+               // setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_HIERARCHY,
+               // action);
+               // // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.OPEN_HIERARCHY_ACTION);
+
+               fEncodingSupport = new DefaultEncodingSupport();
+               fEncodingSupport.initialize(this);
+
+               // fSelectionHistory= new SelectionHistory(this);
+               //
+               // action= new StructureSelectEnclosingAction(this, fSelectionHistory);
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_ENCLOSING);
+               // setAction(StructureSelectionAction.ENCLOSING, action);
+               //
+               // action= new StructureSelectNextAction(this, fSelectionHistory);
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_NEXT);
+               // setAction(StructureSelectionAction.NEXT, action);
+               //
+               // action= new StructureSelectPreviousAction(this, fSelectionHistory);
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_PREVIOUS);
+               // setAction(StructureSelectionAction.PREVIOUS, action);
+               //
+               // StructureSelectHistoryAction historyAction= new
+               // StructureSelectHistoryAction(this, fSelectionHistory);
+               // historyAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_LAST);
+               // setAction(StructureSelectionAction.HISTORY, historyAction);
+               // fSelectionHistory.setHistoryAction(historyAction);
+               //
+               // action= GoToNextPreviousMemberAction.newGoToNextMemberAction(this);
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_NEXT_MEMBER);
+               // setAction(GoToNextPreviousMemberAction.NEXT_MEMBER, action);
+               //
+               // action=
+               // GoToNextPreviousMemberAction.newGoToPreviousMemberAction(this);
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER);
+               // setAction(GoToNextPreviousMemberAction.PREVIOUS_MEMBER, action);
+               //
+               // action= new QuickFormatAction();
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.QUICK_FORMAT);
+               // setAction(IJavaEditorActionDefinitionIds.QUICK_FORMAT, action);
+               //
+               // action= new RemoveOccurrenceAnnotations(this);
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_OCCURRENCE_ANNOTATIONS);
+               // setAction("RemoveOccurrenceAnnotations", action); //$NON-NLS-1$
+
+               // add annotation actions
+               action = new JavaSelectMarkerRulerAction2(PHPEditorMessages
+                               .getResourceBundle(), "Editor.RulerAnnotationSelection.", this); //$NON-NLS-1$
+               setAction("AnnotationAction", action); //$NON-NLS-1$
+       }
+
+       private void internalDoSetInput(IEditorInput input) throws CoreException {
+               super.doSetInput(input);
+
+               if (getSourceViewer() instanceof JavaSourceViewer) {
+                       JavaSourceViewer viewer = (JavaSourceViewer) getSourceViewer();
+                       if (viewer.getReconciler() == null) {
+                               IReconciler reconciler = getSourceViewerConfiguration()
+                                               .getReconciler(viewer);
+                               if (reconciler != null) {
+                                       reconciler.install(viewer);
+                                       viewer.setReconciler(reconciler);
+                               }
+                       }
+               }
+
+               if (fEncodingSupport != null)
+                       fEncodingSupport.reset();
+
+               setOutlinePageInput(fOutlinePage, input);
+
+               if (fProjectionModelUpdater != null)
+                       fProjectionModelUpdater.initialize();
+
+               // if (isShowingOverrideIndicators())
+               // installOverrideIndicator(false);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#setPreferenceStore(org.eclipse.jface.preference.IPreferenceStore)
+        * @since 3.0
+        */
+       protected void setPreferenceStore(IPreferenceStore store) {
+               super.setPreferenceStore(store);
+               if (getSourceViewerConfiguration() instanceof PHPSourceViewerConfiguration) {
+                       JavaTextTools textTools = WebUI.getDefault()
+                                       .getJavaTextTools();
+                       setSourceViewerConfiguration(new PHPSourceViewerConfiguration(
+                                       textTools.getColorManager(), store, this,
+                                       IPHPPartitions.PHP_PARTITIONING));
+               }
+               if (getSourceViewer() instanceof JavaSourceViewer)
+                       ((JavaSourceViewer) getSourceViewer()).setPreferenceStore(store);
+       }
+
+       /**
+        * The <code>PHPEditor</code> implementation of this
+        * <code>AbstractTextEditor</code> method performs any extra disposal
+        * actions required by the php editor.
+        */
+       public void dispose() {
+               if (fProjectionModelUpdater != null) {
+                       fProjectionModelUpdater.uninstall();
+                       fProjectionModelUpdater = null;
+               }
+
+               if (fProjectionSupport != null) {
+                       fProjectionSupport.dispose();
+                       fProjectionSupport = null;
+               }
+               // PHPEditorEnvironment.disconnect(this);
+               if (fOutlinePage != null)
+                       fOutlinePage.setInput(null);
+
+               if (fActionGroups != null)
+                       fActionGroups.dispose();
+
+               if (isBrowserLikeLinks())
+                       disableBrowserLikeLinks();
+
+               // cancel possible running computation
+               fMarkOccurrenceAnnotations = false;
+               uninstallOccurrencesFinder();
+
+               uninstallOverrideIndicator();
+
+               if (fActivationListener != null) {
+                       PlatformUI.getWorkbench().removeWindowListener(fActivationListener);
+                       fActivationListener = null;
+               }
+
+               if (fEncodingSupport != null) {
+                       fEncodingSupport.dispose();
+                       fEncodingSupport = null;
+               }
+
+               if (fPropertyChangeListener != null) {
+                       Preferences preferences = PHPeclipsePlugin.getDefault()
+                                       .getPluginPreferences();
+                       preferences.removePropertyChangeListener(fPropertyChangeListener);
+                       fPropertyChangeListener = null;
+               }
+
+               // if (fSourceViewerDecorationSupport != null) {
+               // fSourceViewerDecorationSupport.dispose();
+               // fSourceViewerDecorationSupport = null;
+               // }
+
+               if (fBracketMatcher != null) {
+                       fBracketMatcher.dispose();
+                       fBracketMatcher = null;
+               }
+
+               if (fEditorSelectionChangedListener != null) {
+                       fEditorSelectionChangedListener.uninstall(getSelectionProvider());
+                       fEditorSelectionChangedListener = null;
+               }
+
+               super.dispose();
+       }
+
+       /**
+        * The <code>PHPEditor</code> implementation of this
+        * <code>AbstractTextEditor</code> method performs any extra revert
+        * behavior required by the php editor.
+        */
+       // public void doRevertToSaved() {
+       // super.doRevertToSaved();
+       // if (fOutlinePage != null)
+       // fOutlinePage.update();
+       // }
+       /**
+        * The <code>PHPEditor</code> implementation of this
+        * <code>AbstractTextEditor</code> method performs any extra save behavior
+        * required by the php editor.
+        */
+       // public void doSave(IProgressMonitor monitor) {
+       // super.doSave(monitor);
+       // compile or not, according to the user preferences
+       // IPreferenceStore store = getPreferenceStore();
+       // the parse on save was changed to the eclipse "builders" concept
+       // if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) {
+       // IAction a = PHPParserAction.getInstance();
+       // if (a != null)
+       // a.run();
+       // }
+       // if (SWT.getPlatform().equals("win32")) {
+       // IAction a = ShowExternalPreviewAction.getInstance();
+       // if (a != null)
+       // a.run();
+       // }
+       // if (fOutlinePage != null)
+       // fOutlinePage.update();
+       // }
+       /**
+        * The <code>PHPEditor</code> implementation of this
+        * <code>AbstractTextEditor</code> method performs any extra save as
+        * behavior required by the php editor.
+        */
+       // public void doSaveAs() {
+       // super.doSaveAs();
+       // if (fOutlinePage != null)
+       // fOutlinePage.update();
+       // }
+       /*
+        * @see StatusTextEditor#getStatusHeader(IStatus)
+        */
+       protected String getStatusHeader(IStatus status) {
+               if (fEncodingSupport != null) {
+                       String message = fEncodingSupport.getStatusHeader(status);
+                       if (message != null)
+                               return message;
+               }
+               return super.getStatusHeader(status);
+       }
+
+       /*
+        * @see StatusTextEditor#getStatusBanner(IStatus)
+        */
+       protected String getStatusBanner(IStatus status) {
+               if (fEncodingSupport != null) {
+                       String message = fEncodingSupport.getStatusBanner(status);
+                       if (message != null)
+                               return message;
+               }
+               return super.getStatusBanner(status);
+       }
+
+       /*
+        * @see StatusTextEditor#getStatusMessage(IStatus)
+        */
+       protected String getStatusMessage(IStatus status) {
+               if (fEncodingSupport != null) {
+                       String message = fEncodingSupport.getStatusMessage(status);
+                       if (message != null)
+                               return message;
+               }
+               return super.getStatusMessage(status);
+       }
+
+       /**
+        * The <code>PHPEditor</code> implementation of this
+        * <code>AbstractTextEditor</code> method performs sets the input of the
+        * outline page after AbstractTextEditor has set input.
+        */
+       // protected void doSetInput(IEditorInput input) throws CoreException {
+       // super.doSetInput(input);
+       // if (fEncodingSupport != null)
+       // fEncodingSupport.reset();
+       // setOutlinePageInput(fOutlinePage, input);
+       // }
+       /*
+        * @see AbstractTextEditor#doSetInput
+        */
+       protected void doSetInput(IEditorInput input) throws CoreException {
+               ISourceViewer sourceViewer = getSourceViewer();
+               if (!(sourceViewer instanceof ISourceViewerExtension2)) {
+                       setPreferenceStore(createCombinedPreferenceStore(input));
+                       internalDoSetInput(input);
+                       return;
+               }
+
+               // uninstall & unregister preference store listener
+               if (isBrowserLikeLinks())
+                       disableBrowserLikeLinks();
+               getSourceViewerDecorationSupport(sourceViewer).uninstall();
+               ((ISourceViewerExtension2) sourceViewer).unconfigure();
+
+               setPreferenceStore(createCombinedPreferenceStore(input));
+
+               // install & register preference store listener
+               sourceViewer.configure(getSourceViewerConfiguration());
+               getSourceViewerDecorationSupport(sourceViewer).install(
+                               getPreferenceStore());
+               if (isBrowserLikeLinks())
+                       enableBrowserLikeLinks();
+
+               internalDoSetInput(input);
+       }
+
+       /*
+        * @see org.phpeclipse.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
+        */
+       // public Object getViewPartInput() {
+       // return getEditorInput().getAdapter(IFile.class);
+       // }
+       /**
+        * The <code>PHPEditor</code> implementation of this
+        * <code>AbstractTextEditor</code> method adds any PHPEditor specific
+        * entries.
+        */
+       public void editorContextMenuAboutToShow(MenuManager menu) {
+               super.editorContextMenuAboutToShow(menu);
+               menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO,
+                               new Separator(IContextMenuConstants.GROUP_OPEN));
+               menu.insertAfter(IContextMenuConstants.GROUP_OPEN, new GroupMarker(
+                               IContextMenuConstants.GROUP_SHOW));
+
+               ActionContext context = new ActionContext(getSelectionProvider()
+                               .getSelection());
+               fContextMenuGroup.setContext(context);
+               fContextMenuGroup.fillContextMenu(menu);
+               fContextMenuGroup.setContext(null);
+               // addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Format");
+               // //$NON-NLS-1$
+               //
+               // ActionContext context =
+               // new ActionContext(getSelectionProvider().getSelection());
+               // fContextMenuGroup.setContext(context);
+               // fContextMenuGroup.fillContextMenu(menu);
+               // fContextMenuGroup.setContext(null);
+       }
+
+       /**
+        * Creates the outline page used with this editor.
+        */
+       protected JavaOutlinePage createOutlinePage() {
+               JavaOutlinePage page = new JavaOutlinePage(fOutlinerContextMenuId, this);
+               fOutlineSelectionChangedListener.install(page);
+               setOutlinePageInput(page, getEditorInput());
+               return page;
+       }
+
+       /**
+        * Informs the editor that its outliner has been closed.
+        */
+       public void outlinePageClosed() {
+               if (fOutlinePage != null) {
+                       fOutlineSelectionChangedListener.uninstall(fOutlinePage);
+                       fOutlinePage = null;
+                       resetHighlightRange();
+               }
+       }
+
+       /**
+        * Synchronizes the outliner selection with the given element position in
+        * the editor.
+        * 
+        * @param element
+        *            the java element to select
+        */
+       protected void synchronizeOutlinePage(ISourceReference element) {
+               synchronizeOutlinePage(element, true);
+       }
+
+       /**
+        * Synchronizes the outliner selection with the given element position in
+        * the editor.
+        * 
+        * @param element
+        *            the java element to select
+        * @param checkIfOutlinePageActive
+        *            <code>true</code> if check for active outline page needs to
+        *            be done
+        */
+       protected void synchronizeOutlinePage(ISourceReference element,
+                       boolean checkIfOutlinePageActive) {
+               if (fOutlinePage != null && element != null
+                               && !(checkIfOutlinePageActive && isJavaOutlinePageActive())) {
+                       fOutlineSelectionChangedListener.uninstall(fOutlinePage);
+                       fOutlinePage.select(element);
+                       fOutlineSelectionChangedListener.install(fOutlinePage);
+               }
+       }
+
+       /**
+        * Synchronizes the outliner selection with the actual cursor position in
+        * the editor.
+        */
+       public void synchronizeOutlinePageSelection() {
+               synchronizeOutlinePage(computeHighlightRangeSourceReference());
+
+               // ISourceViewer sourceViewer = getSourceViewer();
+               // if (sourceViewer == null || fOutlinePage == null)
+               // return;
+               //
+               // StyledText styledText = sourceViewer.getTextWidget();
+               // if (styledText == null)
+               // return;
+               //
+               // int caret = 0;
+               // if (sourceViewer instanceof ITextViewerExtension3) {
+               // ITextViewerExtension3 extension = (ITextViewerExtension3)
+               // sourceViewer;
+               // caret =
+               // extension.widgetOffset2ModelOffset(styledText.getCaretOffset());
+               // } else {
+               // int offset = sourceViewer.getVisibleRegion().getOffset();
+               // caret = offset + styledText.getCaretOffset();
+               // }
+               //
+               // IJavaElement element = getElementAt(caret);
+               // if (element instanceof ISourceReference) {
+               // fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
+               // fOutlinePage.select((ISourceReference) element);
+               // fOutlinePage.addSelectionChangedListener(fSelectionChangedListener);
+               // }
+       }
+
+       protected void setSelection(ISourceReference reference, boolean moveCursor) {
+
+               ISelection selection = getSelectionProvider().getSelection();
+               if (selection instanceof TextSelection) {
+                       TextSelection textSelection = (TextSelection) selection;
+                       if (textSelection.getOffset() != 0
+                                       || textSelection.getLength() != 0)
+                               markInNavigationHistory();
+               }
+
+               if (reference != null) {
+
+                       StyledText textWidget = null;
+
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer != null)
+                               textWidget = sourceViewer.getTextWidget();
+
+                       if (textWidget == null)
+                               return;
+
+                       try {
+
+                               ISourceRange range = reference.getSourceRange();
+                               if (range == null)
+                                       return;
+
+                               int offset = range.getOffset();
+                               int length = range.getLength();
+
+                               if (offset < 0 || length < 0)
+                                       return;
+
+                               textWidget.setRedraw(false);
+
+                               setHighlightRange(offset, length, moveCursor);
+
+                               if (!moveCursor)
+                                       return;
+
+                               offset = -1;
+                               length = -1;
+
+                               if (reference instanceof IMember) {
+                                       range = ((IMember) reference).getNameRange();
+                                       if (range != null) {
+                                               offset = range.getOffset();
+                                               length = range.getLength();
+                                       }
+                               }
+                               // else if (reference instanceof IImportDeclaration) {
+                               // String name= ((IImportDeclaration)
+                               // reference).getElementName();
+                               // if (name != null && name.length() > 0) {
+                               // String content= reference.getSource();
+                               // if (content != null) {
+                               // offset= range.getOffset() + content.indexOf(name);
+                               // length= name.length();
+                               // }
+                               // }
+                               // } else if (reference instanceof IPackageDeclaration) {
+                               // String name= ((IPackageDeclaration)
+                               // reference).getElementName();
+                               // if (name != null && name.length() > 0) {
+                               // String content= reference.getSource();
+                               // if (content != null) {
+                               // offset= range.getOffset() + content.indexOf(name);
+                               // length= name.length();
+                               // }
+                               // }
+                               // }
+
+                               if (offset > -1 && length > 0) {
+                                       sourceViewer.revealRange(offset, length);
+                                       sourceViewer.setSelectedRange(offset, length);
+                               }
+
+                       } catch (JavaModelException x) {
+                       } catch (IllegalArgumentException x) {
+                       } finally {
+                               if (textWidget != null)
+                                       textWidget.setRedraw(true);
+                       }
+
+               } else if (moveCursor) {
+                       resetHighlightRange();
+               }
+
+               markInNavigationHistory();
+       }
+
+       public void setSelection(IJavaElement element) {
+               if (element == null || element instanceof ICompilationUnit) { // ||
+                       // element
+                       // instanceof
+                       // IClassFile)
+                       // {
+                       /*
+                        * If the element is an ICompilationUnit this unit is either the
+                        * input of this editor or not being displayed. In both cases,
+                        * nothing should happened.
+                        * (http://dev.eclipse.org/bugs/show_bug.cgi?id=5128)
+                        */
+                       return;
+               }
+
+               IJavaElement corresponding = getCorrespondingElement(element);
+               if (corresponding instanceof ISourceReference) {
+                       ISourceReference reference = (ISourceReference) corresponding;
+                       // set highlight range
+                       setSelection(reference, true);
+                       // set outliner selection
+                       if (fOutlinePage != null) {
+                               fOutlineSelectionChangedListener.uninstall(fOutlinePage);
+                               fOutlinePage.select(reference);
+                               fOutlineSelectionChangedListener.install(fOutlinePage);
+                       }
+               }
+       }
+
+       public synchronized void editingScriptStarted() {
+               ++fIgnoreOutlinePageSelection;
+       }
+
+       public synchronized void editingScriptEnded() {
+               --fIgnoreOutlinePageSelection;
+       }
+
+       public synchronized boolean isEditingScriptRunning() {
+               return (fIgnoreOutlinePageSelection > 0);
+       }
+
+       /**
+        * The <code>PHPEditor</code> implementation of this
+        * <code>AbstractTextEditor</code> method performs gets the java content
+        * outline page if request is for a an outline page.
+        */
+       public Object getAdapter(Class required) {
+
+               if (IContentOutlinePage.class.equals(required)) {
+                       if (fOutlinePage == null)
+                               fOutlinePage = createOutlinePage();
+                       return fOutlinePage;
+               }
+
+               if (IEncodingSupport.class.equals(required))
+                       return fEncodingSupport;
+
+               if (required == IShowInTargetList.class) {
+                       return new IShowInTargetList() {
+                               public String[] getShowInTargetIds() {
+                                       return new String[] { JavaUI.ID_PACKAGES,
+                                                       IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV };
+                               }
+
+                       };
+               }
+               if (fProjectionSupport != null) {
+                       Object adapter = fProjectionSupport.getAdapter(getSourceViewer(),
+                                       required);
+                       if (adapter != null)
+                               return adapter;
+               }
+
+               return super.getAdapter(required);
+       }
+
+       // public Object getAdapter(Class required) {
+       // if (IContentOutlinePage.class.equals(required)) {
+       // if (fOutlinePage == null) {
+       // fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this);
+       // if (getEditorInput() != null)
+       // fOutlinePage.setInput(getEditorInput());
+       // }
+       // return fOutlinePage;
+       // }
+       //
+       // if (IEncodingSupport.class.equals(required))
+       // return fEncodingSupport;
+       //
+       // return super.getAdapter(required);
+       // }
+
+       protected void doSelectionChanged(SelectionChangedEvent event) {
+               ISourceReference reference = null;
+
+               ISelection selection = event.getSelection();
+               Iterator iter = ((IStructuredSelection) selection).iterator();
+               while (iter.hasNext()) {
+                       Object o = iter.next();
+                       if (o instanceof ISourceReference) {
+                               reference = (ISourceReference) o;
+                               break;
+                       }
+               }
+
+               if (!isActivePart() && WebUI.getActivePage() != null)
+                       WebUI.getActivePage().bringToTop(this);
+
+               try {
+                       editingScriptStarted();
+                       setSelection(reference, !isActivePart());
+               } finally {
+                       editingScriptEnded();
+               }
+       }
+
+       /*
+        * @see AbstractTextEditor#adjustHighlightRange(int, int)
+        */
+       protected void adjustHighlightRange(int offset, int length) {
+
+               try {
+
+                       IJavaElement element = getElementAt(offset);
+                       while (element instanceof ISourceReference) {
+                               ISourceRange range = ((ISourceReference) element)
+                                               .getSourceRange();
+                               if (offset < range.getOffset() + range.getLength()
+                                               && range.getOffset() < offset + length) {
+
+                                       ISourceViewer viewer = getSourceViewer();
+                                       if (viewer instanceof ITextViewerExtension5) {
+                                               ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+                                               extension.exposeModelRange(new Region(
+                                                               range.getOffset(), range.getLength()));
+                                       }
+
+                                       setHighlightRange(range.getOffset(), range.getLength(),
+                                                       true);
+                                       if (fOutlinePage != null) {
+                                               fOutlineSelectionChangedListener
+                                                               .uninstall(fOutlinePage);
+                                               fOutlinePage.select((ISourceReference) element);
+                                               fOutlineSelectionChangedListener.install(fOutlinePage);
+                                       }
+
+                                       return;
+                               }
+                               element = element.getParent();
+                       }
+
+               } catch (JavaModelException x) {
+                       PHPeclipsePlugin.log(x.getStatus());
+               }
+
+               ISourceViewer viewer = getSourceViewer();
+               if (viewer instanceof ITextViewerExtension5) {
+                       ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+                       extension.exposeModelRange(new Region(offset, length));
+               } else {
+                       resetHighlightRange();
+               }
+
+       }
+
+       protected boolean isActivePart() {
+               IWorkbenchWindow window = getSite().getWorkbenchWindow();
+               IPartService service = window.getPartService();
+               IWorkbenchPart part = service.getActivePart();
+               return part != null && part.equals(this);
+       }
+
+       // public void openContextHelp() {
+       // IDocument doc =
+       // this.getDocumentProvider().getDocument(this.getEditorInput());
+       // ITextSelection selection = (ITextSelection)
+       // this.getSelectionProvider().getSelection();
+       // int pos = selection.getOffset();
+       // String word = getFunctionName(doc, pos);
+       // openContextHelp(word);
+       // }
+       //
+       // private void openContextHelp(String word) {
+       // open(word);
+       // }
+       //
+       // public static void open(String word) {
+       // IHelp help = WorkbenchHelp.getHelpSupport();
+       // if (help != null) {
+       // IHelpResource helpResource = new PHPFunctionHelpResource(word);
+       // WorkbenchHelp.getHelpSupport().displayHelpResource(helpResource);
+       // } else {
+       // // showMessage(shell, dialogTitle, ActionMessages.getString("Open help
+       // not available"), false); //$NON-NLS-1$
+       // }
+       // }
+
+       // private String getFunctionName(IDocument doc, int pos) {
+       // Point word = PHPWordExtractor.findWord(doc, pos);
+       // if (word != null) {
+       // try {
+       // return doc.get(word.x, word.y).replace('_', '-');
+       // } catch (BadLocationException e) {
+       // }
+       // }
+       // return "";
+       // }
+
+       /*
+        * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
+        */
+       protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+
+               try {
+
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer == null)
+                               return;
+
+                       String property = event.getProperty();
+
+                       if (PreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
+                               Object value = event.getNewValue();
+                               if (value instanceof Integer) {
+                                       sourceViewer.getTextWidget().setTabs(
+                                                       ((Integer) value).intValue());
+                               } else if (value instanceof String) {
+                                       try {
+                                               sourceViewer.getTextWidget().setTabs(
+                                                               Integer.parseInt((String) value));
+                                       } catch (NumberFormatException e) {
+                                               // bug #1038071 - set default tab:
+                                               sourceViewer.getTextWidget().setTabs(80);
+                                       }
+                               }
+                               return;
+                       }
+
+                       // if (OVERVIEW_RULER.equals(property)) {
+                       // if (isOverviewRulerVisible())
+                       // showOverviewRuler();
+                       // else
+                       // hideOverviewRuler();
+                       // return;
+                       // }
+
+                       // if (LINE_NUMBER_RULER.equals(property)) {
+                       // if (isLineNumberRulerVisible())
+                       // showLineNumberRuler();
+                       // else
+                       // hideLineNumberRuler();
+                       // return;
+                       // }
+
+                       // if (fLineNumberRulerColumn != null
+                       // && (LINE_NUMBER_COLOR.equals(property) ||
+                       // PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) ||
+                       // PREFERENCE_COLOR_BACKGROUND.equals(property))) {
+                       //
+                       // initializeLineNumberRulerColumn(fLineNumberRulerColumn);
+                       // }
+
+                       if (isJavaEditorHoverProperty(property))
+                               updateHoverBehavior();
+
+                       if (BROWSER_LIKE_LINKS.equals(property)) {
+                               if (isBrowserLikeLinks())
+                                       enableBrowserLikeLinks();
+                               else
+                                       disableBrowserLikeLinks();
+                               return;
+                       }
+
+                       if (PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE
+                                       .equals(property)) {
+                               if (event.getNewValue() instanceof Boolean) {
+                                       Boolean disable = (Boolean) event.getNewValue();
+                                       enableOverwriteMode(!disable.booleanValue());
+                               }
+                               return;
+                       }
+
+                       boolean newBooleanValue = false;
+                       Object newValue = event.getNewValue();
+                       if (newValue != null)
+                               newBooleanValue = Boolean.valueOf(newValue.toString())
+                                               .booleanValue();
+
+                       if (PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE
+                                       .equals(property)) {
+                               if (newBooleanValue)
+                                       selectionChanged();
+                               return;
+                       }
+
+                       if (PreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) {
+                               if (newBooleanValue != fMarkOccurrenceAnnotations) {
+                                       fMarkOccurrenceAnnotations = newBooleanValue;
+                                       if (!fMarkOccurrenceAnnotations)
+                                               uninstallOccurrencesFinder();
+                                       else
+                                               installOccurrencesFinder();
+                               }
+                               return;
+                       }
+
+                       if (PreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property)) {
+                               fStickyOccurrenceAnnotations = newBooleanValue;
+                               return;
+                       }
+                       // }
+                       // }
+                       // if
+                       // (PreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property))
+                       // {
+                       // if (event.getNewValue() instanceof Boolean) {
+                       // boolean stickyOccurrenceAnnotations=
+                       // ((Boolean)event.getNewValue()).booleanValue();
+                       // if (stickyOccurrenceAnnotations != fStickyOccurrenceAnnotations)
+                       // {
+
+                       ((PHPSourceViewerConfiguration) getSourceViewerConfiguration())
+                                       .handlePropertyChangeEvent(event);
+
+                       // if (affectsOverrideIndicatorAnnotations(event)) {
+                       // if (isShowingOverrideIndicators()) {
+                       // if (fOverrideIndicatorManager == null)
+                       // installOverrideIndicator(true);
+                       // } else {
+                       // if (fOverrideIndicatorManager != null)
+                       // uninstallOverrideIndicator();
+                       // }
+                       // return;
+                       // }
+
+                       if (PreferenceConstants.EDITOR_FOLDING_PROVIDER.equals(property)) {
+                               if (sourceViewer instanceof ProjectionViewer) {
+                                       ProjectionViewer projectionViewer = (ProjectionViewer) sourceViewer;
+                                       if (fProjectionModelUpdater != null)
+                                               fProjectionModelUpdater.uninstall();
+                                       // either freshly enabled or provider changed
+                                       fProjectionModelUpdater = WebUI.getDefault()
+                                                       .getFoldingStructureProviderRegistry()
+                                                       .getCurrentFoldingProvider();
+                                       if (fProjectionModelUpdater != null) {
+                                               fProjectionModelUpdater.install(this, projectionViewer);
+                                       }
+                               }
+                               return;
+                       }
+               } finally {
+                       super.handlePreferenceStoreChanged(event);
+               }
+       }
+
+       // /*
+       // * @see
+       // AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
+       // */
+       // protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+       //
+       // try {
+       //
+       // ISourceViewer sourceViewer = getSourceViewer();
+       // if (sourceViewer == null)
+       // return;
+       //
+       // String property = event.getProperty();
+       //
+       // // if
+       // (JavaSourceViewerConfiguration.PREFERENCE_TAB_WIDTH.equals(property)) {
+       // // Object value= event.getNewValue();
+       // // if (value instanceof Integer) {
+       // // sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
+       // // } else if (value instanceof String) {
+       // // sourceViewer.getTextWidget().setTabs(Integer.parseInt((String)
+       // value));
+       // // }
+       // // return;
+       // // }
+       //
+       // if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) {
+       // if (isLineNumberRulerVisible())
+       // showLineNumberRuler();
+       // else
+       // hideLineNumberRuler();
+       // return;
+       // }
+       //
+       // if (fLineNumberRulerColumn != null
+       // && (IPreferenceConstants.LINE_NUMBER_COLOR.equals(property)
+       // || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property)
+       // || PREFERENCE_COLOR_BACKGROUND.equals(property))) {
+       //
+       // initializeLineNumberRulerColumn(fLineNumberRulerColumn);
+       // }
+       //
+       // } finally {
+       // super.handlePreferenceStoreChanged(event);
+       // }
+       // }
+
+       // private boolean isJavaEditorHoverProperty(String property) {
+       // return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property)
+       // || PreferenceConstants.EDITOR_NONE_HOVER.equals(property)
+       // || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property)
+       // || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property)
+       // || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property)
+       // || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property)
+       // || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property)
+       // || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property);
+       // }
+
+       /**
+        * Shows the line number ruler column.
+        */
+       // private void showLineNumberRuler() {
+       // IVerticalRuler v = getVerticalRuler();
+       // if (v instanceof CompositeRuler) {
+       // CompositeRuler c = (CompositeRuler) v;
+       // c.addDecorator(1, createLineNumberRulerColumn());
+       // }
+       // }
+       private boolean isJavaEditorHoverProperty(String property) {
+               return PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property);
+       }
+
+       /**
+        * Return whether the browser like links should be enabled according to the
+        * preference store settings.
+        * 
+        * @return <code>true</code> if the browser like links should be enabled
+        */
+       private boolean isBrowserLikeLinks() {
+               IPreferenceStore store = getPreferenceStore();
+               return store.getBoolean(BROWSER_LIKE_LINKS);
+       }
+
+       /**
+        * Enables browser like links.
+        */
+       private void enableBrowserLikeLinks() {
+               if (fMouseListener == null) {
+                       fMouseListener = new MouseClickListener();
+                       fMouseListener.install();
+               }
+       }
+
+       /**
+        * Disables browser like links.
+        */
+       private void disableBrowserLikeLinks() {
+               if (fMouseListener != null) {
+                       fMouseListener.uninstall();
+                       fMouseListener = null;
+               }
+       }
+
+       /**
+        * Handles a property change event describing a change of the java core's
+        * preferences and updates the preference related editor properties.
+        * 
+        * @param event
+        *            the property change event
+        */
+       protected void handlePreferencePropertyChanged(
+                       org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+               if (COMPILER_TASK_TAGS.equals(event.getProperty())) {
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       if (sourceViewer != null
+                                       && affectsTextPresentation(new PropertyChangeEvent(event
+                                                       .getSource(), event.getProperty(), event
+                                                       .getOldValue(), event.getNewValue())))
+                               sourceViewer.invalidateTextPresentation();
+               }
+               if (PreferenceConstants.EDITOR_WRAP_WORDS.equals(event.getProperty())) {
+                       setWordWrap();
+               }
+       }
+
+       /**
+        * Return whether the line number ruler column should be visible according
+        * to the preference store settings.
+        * 
+        * @return <code>true</code> if the line numbers should be visible
+        */
+       // protected boolean isLineNumberRulerVisible() {
+       // IPreferenceStore store = getPreferenceStore();
+       // return store.getBoolean(LINE_NUMBER_RULER);
+       // }
+       /**
+        * Hides the line number ruler column.
+        */
+       // private void hideLineNumberRuler() {
+       // IVerticalRuler v = getVerticalRuler();
+       // if (v instanceof CompositeRuler) {
+       // CompositeRuler c = (CompositeRuler) v;
+       // try {
+       // c.removeDecorator(1);
+       // } catch (Throwable e) {
+       // }
+       // }
+       // }
+       /*
+        * @see AbstractTextEditor#handleCursorPositionChanged()
+        */
+       // protected void handleCursorPositionChanged() {
+       // super.handleCursorPositionChanged();
+       // if (!isEditingScriptRunning() && fUpdater != null)
+       // fUpdater.post();
+       // }
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleElementContentReplaced()
+        */
+       protected void handleElementContentReplaced() {
+               super.handleElementContentReplaced();
+               if (fProjectionModelUpdater != null)
+                       fProjectionModelUpdater.initialize();
+       }
+
+       /**
+        * Initializes the given line number ruler column from the preference store.
+        * 
+        * @param rulerColumn
+        *            the ruler column to be initialized
+        */
+       // protected void initializeLineNumberRulerColumn(LineNumberRulerColumn
+       // rulerColumn) {
+       // JavaTextTools textTools =
+       // PHPeclipsePlugin.getDefault().getJavaTextTools();
+       // IColorManager manager = textTools.getColorManager();
+       //
+       // IPreferenceStore store = getPreferenceStore();
+       // if (store != null) {
+       //
+       // RGB rgb = null;
+       // // foreground color
+       // if (store.contains(LINE_NUMBER_COLOR)) {
+       // if (store.isDefault(LINE_NUMBER_COLOR))
+       // rgb = PreferenceConverter.getDefaultColor(store, LINE_NUMBER_COLOR);
+       // else
+       // rgb = PreferenceConverter.getColor(store, LINE_NUMBER_COLOR);
+       // }
+       // rulerColumn.setForeground(manager.getColor(rgb));
+       //
+       // rgb = null;
+       // // background color
+       // if (!store.getBoolean(PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+       // if (store.contains(PREFERENCE_COLOR_BACKGROUND)) {
+       // if (store.isDefault(PREFERENCE_COLOR_BACKGROUND))
+       // rgb = PreferenceConverter.getDefaultColor(store,
+       // PREFERENCE_COLOR_BACKGROUND);
+       // else
+       // rgb = PreferenceConverter.getColor(store, PREFERENCE_COLOR_BACKGROUND);
+       // }
+       // }
+       // rulerColumn.setBackground(manager.getColor(rgb));
+       // }
+       // }
+       /**
+        * Creates a new line number ruler column that is appropriately initialized.
+        */
+       // protected IVerticalRulerColumn createLineNumberRulerColumn() {
+       // fLineNumberRulerColumn = new LineNumberRulerColumn();
+       // initializeLineNumberRulerColumn(fLineNumberRulerColumn);
+       // return fLineNumberRulerColumn;
+       // }
+       /*
+        * @see AbstractTextEditor#createVerticalRuler()
+        */
+       // protected IVerticalRuler createVerticalRuler() {
+       // CompositeRuler ruler = new CompositeRuler();
+       // ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH));
+       // if (isLineNumberRulerVisible())
+       // ruler.addDecorator(1, createLineNumberRulerColumn());
+       // return ruler;
+       // }
+       // private static IRegion getSignedSelection(ITextViewer viewer) {
+       //
+       // StyledText text = viewer.getTextWidget();
+       // int caretOffset = text.getCaretOffset();
+       // Point selection = text.getSelection();
+       //
+       // // caret left
+       // int offset, length;
+       // if (caretOffset == selection.x) {
+       // offset = selection.y;
+       // length = selection.x - selection.y;
+       //
+       // // caret right
+       // } else {
+       // offset = selection.x;
+       // length = selection.y - selection.x;
+       // }
+       //
+       // return new Region(offset, length);
+       // }
+       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);
+       }
+
+       /** 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;
+
+       /** Preference key for highlighting current line */
+       // protected final static String CURRENT_LINE =
+       // PreferenceConstants.EDITOR_CURRENT_LINE;
+       /** Preference key for highlight color of current line */
+       // protected final static String CURRENT_LINE_COLOR =
+       // PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
+       /** Preference key for showing print marging ruler */
+       // protected final static String PRINT_MARGIN =
+       // PreferenceConstants.EDITOR_PRINT_MARGIN;
+       /** Preference key for print margin ruler color */
+       // protected final static String PRINT_MARGIN_COLOR =
+       // PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
+       /** Preference key for print margin ruler column */
+       // protected final static String PRINT_MARGIN_COLUMN =
+       // PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
+       /** Preference key for error indication */
+       // protected final static String ERROR_INDICATION =
+       // PreferenceConstants.EDITOR_PROBLEM_INDICATION;
+       /** Preference key for error color */
+       // protected final static String ERROR_INDICATION_COLOR =
+       // PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
+       /** Preference key for warning indication */
+       // protected final static String WARNING_INDICATION =
+       // PreferenceConstants.EDITOR_WARNING_INDICATION;
+       /** Preference key for warning color */
+       // protected final static String WARNING_INDICATION_COLOR =
+       // PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
+       /** Preference key for task indication */
+       protected final static String TASK_INDICATION = PreferenceConstants.EDITOR_TASK_INDICATION;
+
+       /** Preference key for task color */
+       protected final static String TASK_INDICATION_COLOR = PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
+
+       /** Preference key for bookmark indication */
+       protected final static String BOOKMARK_INDICATION = PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
+
+       /** Preference key for bookmark color */
+       protected final static String BOOKMARK_INDICATION_COLOR = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
+
+       /** Preference key for search result indication */
+       protected final static String SEARCH_RESULT_INDICATION = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
+
+       /** Preference key for search result color */
+       protected final static String SEARCH_RESULT_INDICATION_COLOR = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
+
+       /** Preference key for unknown annotation indication */
+       protected final static String UNKNOWN_INDICATION = PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
+
+       /** Preference key for unknown annotation color */
+       protected final static String UNKNOWN_INDICATION_COLOR = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
+
+       /** Preference key for shwoing the overview ruler */
+       protected final static String OVERVIEW_RULER = PreferenceConstants.EDITOR_OVERVIEW_RULER;
+
+       /** Preference key for error indication in overview ruler */
+       protected final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for warning indication in overview ruler */
+       protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for task indication in overview ruler */
+       protected final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for bookmark indication in overview ruler */
+       protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for search result indication in overview ruler */
+       protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for unknown annotation indication in overview ruler */
+       protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
+
+       // /** Preference key for compiler task tags */
+       // private final static String COMPILER_TASK_TAGS=
+       // JavaCore.COMPILER_TASK_TAGS;
+       /** Preference key for browser like links */
+       private final static String BROWSER_LIKE_LINKS = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS;
+
+       /** Preference key for key modifier of browser like links */
+       private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER;
+
+       /**
+        * Preference key for key modifier mask of browser like links. The value is
+        * only used if the value of <code>EDITOR_BROWSER_LIKE_LINKS</code> cannot
+        * be resolved to valid SWT modifier bits.
+        * 
+        * @since 2.1.1
+        */
+       private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK;
+
+       private final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };
+
+       private static boolean isBracket(char character) {
+               for (int i = 0; i != BRACKETS.length; ++i)
+                       if (character == BRACKETS[i])
+                               return true;
+               return false;
+       }
+
+       private static 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;
+               }
+       }
+
+       // protected void configureSourceViewerDecorationSupport() {
+       //
+       // fSourceViewerDecorationSupport.setCharacterPairMatcher(fBracketMatcher);
+       //
+       // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+       // AnnotationType.UNKNOWN,
+       // UNKNOWN_INDICATION_COLOR,
+       // UNKNOWN_INDICATION,
+       // UNKNOWN_INDICATION_IN_OVERVIEW_RULER,
+       // 0);
+       // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+       // AnnotationType.BOOKMARK,
+       // BOOKMARK_INDICATION_COLOR,
+       // BOOKMARK_INDICATION,
+       // BOOKMARK_INDICATION_IN_OVERVIEW_RULER,
+       // 1);
+       // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+       // AnnotationType.TASK,
+       // TASK_INDICATION_COLOR,
+       // TASK_INDICATION,
+       // TASK_INDICATION_IN_OVERVIEW_RULER,
+       // 2);
+       // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+       // AnnotationType.SEARCH,
+       // SEARCH_RESULT_INDICATION_COLOR,
+       // SEARCH_RESULT_INDICATION,
+       // SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER,
+       // 3);
+       // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+       // AnnotationType.WARNING,
+       // WARNING_INDICATION_COLOR,
+       // WARNING_INDICATION,
+       // WARNING_INDICATION_IN_OVERVIEW_RULER,
+       // 4);
+       // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+       // AnnotationType.ERROR,
+       // ERROR_INDICATION_COLOR,
+       // ERROR_INDICATION,
+       // ERROR_INDICATION_IN_OVERVIEW_RULER,
+       // 5);
+       //
+       // fSourceViewerDecorationSupport.setCursorLinePainterPreferenceKeys(CURRENT_LINE,
+       // CURRENT_LINE_COLOR);
+       // fSourceViewerDecorationSupport.setMarginPainterPreferenceKeys(PRINT_MARGIN,
+       // PRINT_MARGIN_COLOR, PRINT_MARGIN_COLUMN);
+       // fSourceViewerDecorationSupport.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS,
+       // MATCHING_BRACKETS_COLOR);
+       //
+       // fSourceViewerDecorationSupport.setSymbolicFontName(getFontPropertyPreferenceKey());
+       //
+       // }
+       /**
+        * Returns the Java element wrapped by this editors input.
+        * 
+        * @return the Java element wrapped by this editors input.
+        * @since 3.0
+        */
+       abstract protected IJavaElement getInputJavaElement();
+
+       protected void updateStatusLine() {
+               ITextSelection selection = (ITextSelection) getSelectionProvider()
+                               .getSelection();
+               Annotation annotation = getAnnotation(selection.getOffset(), selection
+                               .getLength());
+               setStatusLineErrorMessage(null);
+               setStatusLineMessage(null);
+               if (annotation != null) {
+                       try {
+                               fIsUpdatingAnnotationViews = true;
+                               updateAnnotationViews(annotation);
+                       } finally {
+                               fIsUpdatingAnnotationViews = false;
+                       }
+                       if (annotation instanceof IJavaAnnotation
+                                       && ((IJavaAnnotation) annotation).isProblem())
+                               setStatusLineMessage(annotation.getText());
+               }
+       }
+
+       /**
+        * Jumps to the matching bracket.
+        */
+       public void gotoMatchingBracket() {
+
+               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(PHPEditorMessages
+                                       .getString("GotoMatchingBracket.error.invalidSelection")); //$NON-NLS-1$
+                       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(PHPEditorMessages
+                                       .getString("GotoMatchingBracket.error.noMatchingBracket")); //$NON-NLS-1$
+                       sourceViewer.getTextWidget().getDisplay().beep();
+                       return;
+               }
+
+               int offset = region.getOffset();
+               int length = region.getLength();
+
+               if (length < 1)
+                       return;
+
+               int anchor = fBracketMatcher.getAnchor();
+               int targetOffset = (PHPPairMatcher.RIGHT == anchor) ? offset : offset
+                               + length - 1;
+
+               boolean visible = false;
+               if (sourceViewer instanceof ITextViewerExtension5) {
+                       ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer;
+                       visible = (extension.modelOffset2WidgetOffset(targetOffset) > -1);
+               } else {
+                       IRegion visibleRegion = sourceViewer.getVisibleRegion();
+                       visible = (targetOffset >= visibleRegion.getOffset() && targetOffset < visibleRegion
+                                       .getOffset()
+                                       + visibleRegion.getLength());
+               }
+
+               if (!visible) {
+                       setStatusLineErrorMessage(PHPEditorMessages
+                                       .getString("GotoMatchingBracket.error.bracketOutsideSelectedElement")); //$NON-NLS-1$
+                       sourceViewer.getTextWidget().getDisplay().beep();
+                       return;
+               }
+
+               if (selection.getLength() < 0)
+                       targetOffset -= selection.getLength();
+
+               sourceViewer.setSelectedRange(targetOffset, selection.getLength());
+               sourceViewer.revealRange(targetOffset, selection.getLength());
+       }
+
+       /**
+        * Ses 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);
+       }
+
+       /**
+        * 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());
+               Iterator e = new JavaAnnotationIterator(model, true, true);
+               while (e.hasNext()) {
+                       Annotation a = (Annotation) e.next();
+                       if ((a instanceof IJavaAnnotation)
+                                       && ((IJavaAnnotation) a).hasOverlay()
+                                       || !isNavigationTarget(a))
+                               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;
+       }
+
+       /**
+        * Returns the annotation overlapping with the given range or
+        * <code>null</code>.
+        * 
+        * @param offset
+        *            the region offset
+        * @param length
+        *            the region length
+        * @return the found annotation or <code>null</code>
+        * @since 3.0
+        */
+       private Annotation getAnnotation(int offset, int length) {
+               IAnnotationModel model = getDocumentProvider().getAnnotationModel(
+                               getEditorInput());
+               Iterator e = new JavaAnnotationIterator(model, true, true);
+               while (e.hasNext()) {
+                       Annotation a = (Annotation) e.next();
+                       if (!isNavigationTarget(a))
+                               continue;
+
+                       Position p = model.getPosition(a);
+                       if (p != null && p.overlapsWith(offset, length))
+                               return a;
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns whether the given annotation is configured as a target for the
+        * "Go to Next/Previous Annotation" actions
+        * 
+        * @param annotation
+        *            the annotation
+        * @return <code>true</code> if this is a target, <code>false</code>
+        *         otherwise
+        * @since 3.0
+        */
+       protected boolean isNavigationTarget(Annotation annotation) {
+               Preferences preferences = EditorsUI.getPluginPreferences();
+               AnnotationPreference preference = getAnnotationPreferenceLookup()
+                               .getAnnotationPreference(annotation);
+               // See bug 41689
+               // String key= forward ? preference.getIsGoToNextNavigationTargetKey() :
+               // preference.getIsGoToPreviousNavigationTargetKey();
+               String key = preference == null ? null : preference
+                               .getIsGoToNextNavigationTargetKey();
+               return (key != null && preferences.getBoolean(key));
+       }
+
+       /**
+        * Returns a segmentation of the line of the given document appropriate for
+        * bidi rendering. The default implementation returns only the string
+        * literals of a php code line as segments.
+        * 
+        * @param document
+        *            the document
+        * @param lineOffset
+        *            the offset of the line
+        * @return the line's bidi segmentation
+        * @throws BadLocationException
+        *             in case lineOffset is not valid in document
+        */
+       public static int[] getBidiLineSegments(IDocument document, int lineOffset)
+                       throws BadLocationException {
+
+               IRegion line = document.getLineInformationOfOffset(lineOffset);
+               ITypedRegion[] linePartitioning = document.computePartitioning(
+                               lineOffset, line.getLength());
+
+               List segmentation = new ArrayList();
+               for (int i = 0; i < linePartitioning.length; i++) {
+                       if (IPHPPartitions.PHP_STRING_DQ.equals(linePartitioning[i]
+                                       .getType())) {
+                               segmentation.add(linePartitioning[i]);
+                       } else if (IPHPPartitions.PHP_STRING_HEREDOC
+                                       .equals(linePartitioning[i].getType())) {
+                               segmentation.add(linePartitioning[i]);
+                       }
+               }
+
+               if (segmentation.size() == 0)
+                       return null;
+
+               int size = segmentation.size();
+               int[] segments = new int[size * 2 + 1];
+
+               int j = 0;
+               for (int i = 0; i < size; i++) {
+                       ITypedRegion segment = (ITypedRegion) segmentation.get(i);
+
+                       if (i == 0)
+                               segments[j++] = 0;
+
+                       int offset = segment.getOffset() - lineOffset;
+                       if (offset > segments[j - 1])
+                               segments[j++] = offset;
+
+                       if (offset + segment.getLength() >= line.getLength())
+                               break;
+
+                       segments[j++] = offset + segment.getLength();
+               }
+
+               if (j < segments.length) {
+                       int[] result = new int[j];
+                       System.arraycopy(segments, 0, result, 0, j);
+                       segments = result;
+               }
+
+               return segments;
+       }
+
+       /**
+        * Returns a segmentation of the given line appropriate for bidi rendering.
+        * The default implementation returns only the string literals of a php code
+        * line as segments.
+        * 
+        * @param lineOffset
+        *            the offset of the line
+        * @param line
+        *            the content of the line
+        * @return the line's bidi segmentation
+        */
+       protected int[] getBidiLineSegments(int lineOffset, String line) {
+               IDocumentProvider provider = getDocumentProvider();
+               if (provider != null && line != null && line.length() > 0) {
+                       IDocument document = provider.getDocument(getEditorInput());
+                       if (document != null)
+                               try {
+                                       return getBidiLineSegments(document, lineOffset);
+                               } catch (BadLocationException x) {
+                                       // ignore
+                               }
+               }
+               return null;
+       }
+
+       /*
+        * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler,
+        *      int)
+        */
+       // protected final ISourceViewer createSourceViewer(
+       // Composite parent,
+       // IVerticalRuler ruler,
+       // int styles) {
+       // ISourceViewer viewer = createJavaSourceViewer(parent, ruler, styles);
+       // StyledText text = viewer.getTextWidget();
+       // text.addBidiSegmentListener(new BidiSegmentListener() {
+       // public void lineGetSegments(BidiSegmentEvent event) {
+       // event.segments = getBidiLineSegments(event.lineOffset, event.lineText);
+       // }
+       // });
+       // // JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
+       // return viewer;
+       // }
+       public final ISourceViewer getViewer() {
+               return getSourceViewer();
+       }
+
+       // protected void showOverviewRuler() {
+       // if (fOverviewRuler != null) {
+       // if (getSourceViewer() instanceof ISourceViewerExtension) {
+       // ((ISourceViewerExtension)
+       // getSourceViewer()).showAnnotationsOverview(true);
+       // fSourceViewerDecorationSupport.updateOverviewDecorations();
+       // }
+       // }
+       // }
+       //
+       // protected void hideOverviewRuler() {
+       // if (getSourceViewer() instanceof ISourceViewerExtension) {
+       // fSourceViewerDecorationSupport.hideAnnotationOverview();
+       // ((ISourceViewerExtension)
+       // getSourceViewer()).showAnnotationsOverview(false);
+       // }
+       // }
+
+       // protected boolean isOverviewRulerVisible() {
+       // IPreferenceStore store = getPreferenceStore();
+       // return store.getBoolean(OVERVIEW_RULER);
+       // }
+       /*
+        * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler,
+        *      int)
+        */
+       // protected ISourceViewer createJavaSourceViewer(
+       // Composite parent,
+       // IVerticalRuler ruler,
+       // IOverviewRuler overviewRuler,
+       // boolean isOverviewRulerVisible,
+       // int styles) {
+       // return new SourceViewer(parent, ruler, overviewRuler,
+       // isOverviewRulerVisible(), styles);
+       // }
+       /*
+        * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler,
+        *      int)
+        */
+       protected ISourceViewer createJavaSourceViewer(Composite parent,
+                       IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
+                       boolean isOverviewRulerVisible, int styles, IPreferenceStore store) {
+               return new JavaSourceViewer(parent, verticalRuler, getOverviewRuler(),
+                               isOverviewRulerVisible(), styles, store);
+       }
+
+       /*
+        * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler,
+        *      int)
+        */
+       protected final ISourceViewer createSourceViewer(Composite parent,
+                       IVerticalRuler verticalRuler, int styles) {
+
+               ISourceViewer viewer = createJavaSourceViewer(parent, verticalRuler,
+                               getOverviewRuler(), isOverviewRulerVisible(), styles,
+                               getPreferenceStore());
+
+               StyledText text = viewer.getTextWidget();
+               text.addBidiSegmentListener(new BidiSegmentListener() {
+                       public void lineGetSegments(BidiSegmentEvent event) {
+                               event.segments = getBidiLineSegments(event.lineOffset,
+                                               event.lineText);
+                       }
+               });
+
+               // JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
+
+               // ensure source viewer decoration support has been created and
+               // configured
+               getSourceViewerDecorationSupport(viewer);
+
+               return viewer;
+       }
+
+       /*
+        * @see AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
+        */
+       protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+               return ((PHPSourceViewerConfiguration) getSourceViewerConfiguration())
+                               .affectsTextPresentation(event)
+                               || super.affectsTextPresentation(event);
+       }
+
+       //
+       // protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+       // JavaTextTools textTools =
+       // PHPeclipsePlugin.getDefault().getJavaTextTools();
+       // return textTools.affectsBehavior(event);
+       // }
+       /**
+        * Creates and returns the preference store for this Java editor with the
+        * given input.
+        * 
+        * @param input
+        *            The editor input for which to create the preference store
+        * @return the preference store for this editor
+        * 
+        * @since 3.0
+        */
+       private IPreferenceStore createCombinedPreferenceStore(IEditorInput input) {
+               List stores = new ArrayList(3);
+
+               IJavaProject project = EditorUtility.getJavaProject(input);
+               if (project != null)
+                       stores.add(new OptionsAdapter(project.getOptions(false),
+                                       WebUI.getDefault().getMockupPreferenceStore(),
+                                       new OptionsAdapter.IPropertyChangeEventFilter() {
+
+                                               public boolean isFiltered(PropertyChangeEvent event) {
+                                                       IJavaElement inputJavaElement = getInputJavaElement();
+                                                       IJavaProject javaProject = inputJavaElement != null ? inputJavaElement
+                                                                       .getJavaProject()
+                                                                       : null;
+                                                       if (javaProject == null)
+                                                               return true;
+
+                                                       return !javaProject.getProject().equals(
+                                                                       event.getSource());
+                                               }
+
+                                       }));
+
+               stores.add(WebUI.getDefault().getPreferenceStore());
+               stores.add(new PreferencesAdapter(JavaCore.getPlugin()
+                               .getPluginPreferences()));
+               stores.add(EditorsUI.getPreferenceStore());
+
+               return new ChainedPreferenceStore((IPreferenceStore[]) stores
+                               .toArray(new IPreferenceStore[stores.size()]));
+       }
+
+       /**
+        * Jumps to the error next according to the given direction.
+        */
+       public void gotoError(boolean forward) {
+
+               ISelectionProvider provider = getSelectionProvider();
+
+               ITextSelection s = (ITextSelection) provider.getSelection();
+               Position errorPosition = new Position(0, 0);
+               IJavaAnnotation nextError = getNextError(s.getOffset(), forward,
+                               errorPosition);
+
+               if (nextError != null) {
+
+                       IMarker marker = null;
+                       if (nextError instanceof MarkerAnnotation)
+                               marker = ((MarkerAnnotation) nextError).getMarker();
+                       else {
+                               Iterator e = nextError.getOverlaidIterator();
+                               if (e != null) {
+                                       while (e.hasNext()) {
+                                               Object o = e.next();
+                                               if (o instanceof MarkerAnnotation) {
+                                                       marker = ((MarkerAnnotation) o).getMarker();
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+
+                       if (marker != null) {
+                               IWorkbenchPage page = getSite().getPage();
+                               IViewPart view = view = page
+                                               .findView("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$
+                               if (view instanceof TaskList) {
+                                       StructuredSelection ss = new StructuredSelection(marker);
+                                       ((TaskList) view).setSelection(ss, true);
+                               }
+                       }
+
+                       selectAndReveal(errorPosition.getOffset(), errorPosition
+                                       .getLength());
+                       // setStatusLineErrorMessage(nextError.getMessage());
+
+               } else {
+
+                       setStatusLineErrorMessage(null);
+
+               }
+       }
+
+       private IJavaAnnotation getNextError(int offset, boolean forward,
+                       Position errorPosition) {
+
+               IJavaAnnotation nextError = null;
+               Position nextErrorPosition = null;
+
+               IDocument document = getDocumentProvider()
+                               .getDocument(getEditorInput());
+               int endOfDocument = document.getLength();
+               int distance = 0;
+
+               IAnnotationModel model = getDocumentProvider().getAnnotationModel(
+                               getEditorInput());
+               Iterator e = new JavaAnnotationIterator(model, false);
+               while (e.hasNext()) {
+
+                       IJavaAnnotation a = (IJavaAnnotation) e.next();
+                       if (a.hasOverlay() || !a.isProblem())
+                               continue;
+
+                       Position p = model.getPosition((Annotation) a);
+                       if (!p.includes(offset)) {
+
+                               int currentDistance = 0;
+
+                               if (forward) {
+                                       currentDistance = p.getOffset() - offset;
+                                       if (currentDistance < 0)
+                                               currentDistance = endOfDocument - offset
+                                                               + p.getOffset();
+                               } else {
+                                       currentDistance = offset - p.getOffset();
+                                       if (currentDistance < 0)
+                                               currentDistance = offset + endOfDocument
+                                                               - p.getOffset();
+                               }
+
+                               if (nextError == null || currentDistance < distance) {
+                                       distance = currentDistance;
+                                       nextError = a;
+                                       nextErrorPosition = p;
+                               }
+                       }
+               }
+
+               if (nextErrorPosition != null) {
+                       errorPosition.setOffset(nextErrorPosition.getOffset());
+                       errorPosition.setLength(nextErrorPosition.getLength());
+               }
+
+               return nextError;
+       }
+
+       protected void uninstallOverrideIndicator() {
+               // if (fOverrideIndicatorManager != null) {
+               // fOverrideIndicatorManager.removeAnnotations();
+               // fOverrideIndicatorManager= null;
+               // }
+       }
+
+       protected void installOverrideIndicator(boolean waitForReconcilation) {
+               uninstallOverrideIndicator();
+               IAnnotationModel model = getDocumentProvider().getAnnotationModel(
+                               getEditorInput());
+               final IJavaElement inputElement = getInputJavaElement();
+
+               if (model == null || inputElement == null)
+                       return;
+
+               // fOverrideIndicatorManager= new OverrideIndicatorManager(model,
+               // inputElement, null);
+               //
+               // if (provideAST) {
+               // Job job= new
+               // Job(JavaEditorMessages.getString("OverrideIndicatorManager.intallJob"))
+               // {
+               // //$NON-NLS-1$
+               // /*
+               // * @see
+               // org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+               // * @since 3.0
+               // */
+               // protected IStatus run(IProgressMonitor monitor) {
+               // CompilationUnit ast=
+               // JavaPlugin.getDefault().getASTProvider().getAST(inputElement, true,
+               // null);
+               // if (fOverrideIndicatorManager != null) // editor might have been
+               // closed
+               // in the meanwhile
+               // fOverrideIndicatorManager.reconciled(ast, true, monitor);
+               // return Status.OK_STATUS;
+               // }
+               // };
+               // job.setPriority(Job.DECORATE);
+               // job.setSystem(true);
+               // job.schedule();
+               // }
+       }
+
+       /**
+        * Tells whether override indicators are shown.
+        * 
+        * @return <code>true</code> if the override indicators are shown
+        * @since 3.0
+        */
+       // protected boolean isShowingOverrideIndicators() {
+       // AnnotationPreference preference=
+       // getAnnotationPreferenceLookup().getAnnotationPreference(OverrideIndicatorManager.ANNOTATION_TYPE);
+       // IPreferenceStore store= getPreferenceStore();
+       // return getBoolean(store, preference.getHighlightPreferenceKey())
+       // || getBoolean(store, preference.getVerticalRulerPreferenceKey())
+       // || getBoolean(store, preference.getOverviewRulerPreferenceKey())
+       // || getBoolean(store, preference.getTextPreferenceKey());
+       // }
+       /**
+        * Returns the boolean preference for the given key.
+        * 
+        * @param store
+        *            the preference store
+        * @param key
+        *            the preference key
+        * @return <code>true</code> if the key exists in the store and its value
+        *         is <code>true</code>
+        * @since 3.0
+        */
+       private boolean getBoolean(IPreferenceStore store, String key) {
+               return key != null && store.getBoolean(key);
+       }
+
+       protected boolean isPrefQuickDiffAlwaysOn() {
+               return false; // never show change ruler for the non-editable java
+                                               // editor.
+               // Overridden in subclasses like PHPUnitEditor
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#createNavigationActions()
+        */
+       protected void createNavigationActions() {
+               super.createNavigationActions();
+
+               final StyledText textWidget = getSourceViewer().getTextWidget();
+
+               IAction action = new SmartLineStartAction(textWidget, false);
+               action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_START);
+               setAction(ITextEditorActionDefinitionIds.LINE_START, action);
+
+               action = new SmartLineStartAction(textWidget, true);
+               action
+                               .setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_LINE_START);
+               setAction(ITextEditorActionDefinitionIds.SELECT_LINE_START, action);
+
+               action = new NavigatePreviousSubWordAction();
+               action
+                               .setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_PREVIOUS);
+               setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, action);
+               textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_LEFT, SWT.NULL);
+
+               action = new NavigateNextSubWordAction();
+               action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_NEXT);
+               setAction(ITextEditorActionDefinitionIds.WORD_NEXT, action);
+               textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_RIGHT, SWT.NULL);
+
+               action = new SelectPreviousSubWordAction();
+               action
+                               .setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS);
+               setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, action);
+               textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_LEFT,
+                               SWT.NULL);
+
+               action = new SelectNextSubWordAction();
+               action
+                               .setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT);
+               setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, action);
+               textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_RIGHT,
+                               SWT.NULL);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createCompositeRuler()
+        */
+       // protected CompositeRuler createCompositeRuler() {
+       // if
+       // (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
+       // return super.createCompositeRuler();
+       //
+       // CompositeRuler ruler = new CompositeRuler();
+       // AnnotationRulerColumn column = new
+       // AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess());
+       // column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(), new
+       // IDoubleClickListener() {
+       //
+       // public void doubleClick(DoubleClickEvent event) {
+       // // for now: just invoke ruler double click action
+       // triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK);
+       // }
+       //
+       // private void triggerAction(String actionID) {
+       // IAction action = getAction(actionID);
+       // if (action != null) {
+       // if (action instanceof IUpdate)
+       // ((IUpdate) action).update();
+       // // hack to propagate line change
+       // if (action instanceof ISelectionListener) {
+       // ((ISelectionListener) action).selectionChanged(null, null);
+       // }
+       // if (action.isEnabled())
+       // action.run();
+       // }
+       // }
+       //
+       // }));
+       // ruler.addDecorator(0, column);
+       //
+       // if (isLineNumberRulerVisible())
+       // ruler.addDecorator(1, createLineNumberRulerColumn());
+       // else if (isPrefQuickDiffAlwaysOn())
+       // ruler.addDecorator(1, createChangeRulerColumn());
+       //
+       // return ruler;
+       // }
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createAnnotationRulerColumn(org.eclipse.jface.text.source.CompositeRuler)
+        * @since 3.2
+        */
+       protected IVerticalRulerColumn createAnnotationRulerColumn(
+                       CompositeRuler ruler) {
+               if (!getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
+                       return super.createAnnotationRulerColumn(ruler);
+
+               AnnotationRulerColumn column = new AnnotationRulerColumn(
+                               VERTICAL_RULER_WIDTH, getAnnotationAccess());
+               column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(),
+                               new IDoubleClickListener() {
+
+                                       public void doubleClick(DoubleClickEvent event) {
+                                               // for now: just invoke ruler double click action
+                                               triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK);
+                                       }
+
+                                       private void triggerAction(String actionID) {
+                                               IAction action = getAction(actionID);
+                                               if (action != null) {
+                                                       if (action instanceof IUpdate)
+                                                               ((IUpdate) action).update();
+                                                       // hack to propagate line change
+                                                       if (action instanceof ISelectionListener) {
+                                                               ((ISelectionListener) action).selectionChanged(
+                                                                               null, null);
+                                                       }
+                                                       if (action.isEnabled())
+                                                               action.run();
+                                               }
+                                       }
+
+                               }));
+
+               return column;
+       }
+
+       /**
+        * Returns the folding action group, or <code>null</code> if there is
+        * none.
+        * 
+        * @return the folding action group, or <code>null</code> if there is none
+        * @since 3.0
+        */
+       protected FoldingActionGroup getFoldingActionGroup() {
+               return fFoldingGroup;
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert()
+        */
+       protected void performRevert() {
+               ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
+               projectionViewer.setRedraw(false);
+               try {
+
+                       boolean projectionMode = projectionViewer.isProjectionMode();
+                       if (projectionMode) {
+                               projectionViewer.disableProjection();
+                               if (fProjectionModelUpdater != null)
+                                       fProjectionModelUpdater.uninstall();
+                       }
+
+                       super.performRevert();
+
+                       if (projectionMode) {
+                               if (fProjectionModelUpdater != null)
+                                       fProjectionModelUpdater.install(this, projectionViewer);
+                               projectionViewer.enableProjection();
+                       }
+
+               } finally {
+                       projectionViewer.setRedraw(true);
+               }
+       }
+
+       /**
+        * React to changed selection.
+        * 
+        * @since 3.0
+        */
+       protected void selectionChanged() {
+               if (getSelectionProvider() == null)
+                       return;
+               ISourceReference element = computeHighlightRangeSourceReference();
+               if (getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
+                       synchronizeOutlinePage(element);
+               setSelection(element, false);
+               updateStatusLine();
+       }
+
+       private boolean isJavaOutlinePageActive() {
+               IWorkbenchPart part = getActivePart();
+               return part instanceof ContentOutline
+                               && ((ContentOutline) part).getCurrentPage() == fOutlinePage;
+       }
+
+       private IWorkbenchPart getActivePart() {
+               IWorkbenchWindow window = getSite().getWorkbenchWindow();
+               IPartService service = window.getPartService();
+               IWorkbenchPart part = service.getActivePart();
+               return part;
+       }
+
+       /**
+        * Computes and returns the source reference that includes the caret and
+        * serves as provider for the outline page selection and the editor range
+        * indication.
+        * 
+        * @return the computed source reference
+        * @since 3.0
+        */
+       protected ISourceReference computeHighlightRangeSourceReference() {
+               ISourceViewer sourceViewer = getSourceViewer();
+               if (sourceViewer == null)
+                       return null;
+
+               StyledText styledText = sourceViewer.getTextWidget();
+               if (styledText == null)
+                       return null;
+
+               int caret = 0;
+               if (sourceViewer instanceof ITextViewerExtension5) {
+                       ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer;
+                       caret = extension.widgetOffset2ModelOffset(styledText
+                                       .getCaretOffset());
+               } else {
+                       int offset = sourceViewer.getVisibleRegion().getOffset();
+                       caret = offset + styledText.getCaretOffset();
+               }
+
+               IJavaElement element = getElementAt(caret, false);
+
+               if (!(element instanceof ISourceReference))
+                       return null;
+
+               if (element.getElementType() == IJavaElement.IMPORT_DECLARATION) {
+
+                       IImportDeclaration declaration = (IImportDeclaration) element;
+                       IImportContainer container = (IImportContainer) declaration
+                                       .getParent();
+                       ISourceRange srcRange = null;
+
+                       try {
+                               srcRange = container.getSourceRange();
+                       } catch (JavaModelException e) {
+                       }
+
+                       if (srcRange != null && srcRange.getOffset() == caret)
+                               return container;
+               }
+
+               return (ISourceReference) element;
+       }
+
+       /**
+        * Returns the most narrow java element including the given offset.
+        * 
+        * @param offset
+        *            the offset inside of the requested element
+        * @param reconcile
+        *            <code>true</code> if editor input should be reconciled in
+        *            advance
+        * @return the most narrow java element
+        * @since 3.0
+        */
+       protected IJavaElement getElementAt(int offset, boolean reconcile) {
+               return getElementAt(offset);
+       }
+
+       public ShowInContext getShowInContext() {
+               IFile file = null;
+               if(getEditorInput() instanceof FileStoreEditorInput){
+                       FileStoreEditorInput fei = (FileStoreEditorInput) getEditorInput();
+                       file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fei.getURI().getPath()));
+               } else if (getEditorInput() instanceof FileEditorInput) {
+                       FileEditorInput fei = (FileEditorInput) getEditorInput();
+                       // added to fix ticket 637
+                       file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fei.getURI().getPath()));
+               } else if (getEditorInput() instanceof ExternalEditorInput) {
+                       ExternalEditorInput fei = (ExternalEditorInput) getEditorInput();
+                       file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fei.getFullPath()/* .getURI().getPath()*/));
+               }
+
+               ShowInContext context = BrowserUtil.getShowInContext(file,
+                               false, "");
+               if (context != null) {
+                       return context;
+               }
+               return new ShowInContext(file, null);
+       }
+
+       public String[] getShowInTargetIds() {
+               return new String[] { BrowserView.ID_BROWSER };
+       }
+
+       /**
+        * Updates the occurrences annotations based on the current selection.
+        * 
+        * @param selection
+        *            the text selection
+        * @param astRoot
+        *            the compilation unit AST
+        * @since 3.0
+        */
+       protected void updateOccurrenceAnnotations(ITextSelection selection) {// ,
+               // CompilationUnit
+               // astRoot)
+               // {
+
+               if (fOccurrencesFinderJob != null)
+                       fOccurrencesFinderJob.cancel();
+
+               if (!fMarkOccurrenceAnnotations)
+                       return;
+
+               // if (astRoot == null || selection == null)
+               if (selection == null)
+                       return;
+
+               IDocument document = getSourceViewer().getDocument();
+               if (document == null)
+                       return;
+
+               fMarkOccurrenceTargetRegion = null;
+               if (document instanceof IDocumentExtension4) {
+                       int offset = selection.getOffset();
+                       long currentModificationStamp = ((IDocumentExtension4) document)
+                                       .getModificationStamp();
+                       if (fMarkOccurrenceTargetRegion != null
+                                       && currentModificationStamp == fMarkOccurrenceModificationStamp) {
+                               if (fMarkOccurrenceTargetRegion.getOffset() <= offset
+                                               && offset <= fMarkOccurrenceTargetRegion.getOffset()
+                                                               + fMarkOccurrenceTargetRegion.getLength())
+                                       return;
+                       }
+                       fMarkOccurrenceTargetRegion = JavaWordFinder.findWord(document,
+                                       offset);
+                       fMarkOccurrenceModificationStamp = currentModificationStamp;
+               }
+
+               if (fMarkOccurrenceTargetRegion == null
+                               || fMarkOccurrenceTargetRegion.getLength() == 0) {
+                       return;
+               }
+
+               List matches = null;
+
+               if (matches == null) {
+                       try {
+                               matches = new ArrayList();
+
+                               Scanner fScanner = new Scanner();
+                               fScanner.setSource(document.get().toCharArray());
+                               fScanner.setPHPMode(false);
+                               String wordStr;
+                               char[] word;
+
+                               wordStr = document.get(fMarkOccurrenceTargetRegion.getOffset(),
+                                               fMarkOccurrenceTargetRegion.getLength());
+                               if (wordStr != null) {
+                                       word = wordStr.toCharArray();
+                                       int fToken = ITerminalSymbols.TokenNameEOF;
+                                       try {
+                                               fToken = fScanner.getNextToken();
+                                               while (fToken != ITerminalSymbols.TokenNameEOF) { // &&
+                                                                                                                                                       // fToken
+                                                                                                                                                       // !=
+                                                       // TokenNameERROR) {
+                                                       if (fToken == ITerminalSymbols.TokenNameVariable
+                                                                       || fToken == ITerminalSymbols.TokenNameIdentifier) {
+                                                               // global variable
+                                                               if (fScanner.equalsCurrentTokenSource(word)) {
+                                                                       matches
+                                                                                       .add(new Region(
+                                                                                                       fScanner
+                                                                                                                       .getCurrentTokenStartPosition(),
+                                                                                                       fScanner
+                                                                                                                       .getCurrentTokenEndPosition()
+                                                                                                                       - fScanner
+                                                                                                                                       .getCurrentTokenStartPosition()
+                                                                                                                       + 1));
+                                                               }
+                                                       }
+                                                       fToken = fScanner.getNextToken();
+                                               }
+                                       } catch (InvalidInputException e) {
+                                               // ignore errors
+                                       } catch (SyntaxError e) {
+                                               // ignore errors
+                                       }
+                               }
+                       } catch (BadLocationException e1) {
+                               // ignore errors
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                               // ignore errors
+                       }
+
+               }
+
+               if (matches == null || matches.size() == 0) {
+                       if (!fStickyOccurrenceAnnotations)
+                               removeOccurrenceAnnotations();
+                       return;
+               }
+
+               Position[] positions = new Position[matches.size()];
+               int i = 0;
+               for (Iterator each = matches.iterator(); each.hasNext();) {
+                       IRegion currentNode = (IRegion) each.next();
+                       positions[i++] = new Position(currentNode.getOffset(), currentNode
+                                       .getLength());
+               }
+
+               fOccurrencesFinderJob = new OccurrencesFinderJob(document, positions,
+                               selection);
+               // fOccurrencesFinderJob.setPriority(Job.DECORATE);
+               // fOccurrencesFinderJob.setSystem(true);
+               // fOccurrencesFinderJob.schedule();
+               fOccurrencesFinderJob.run(new NullProgressMonitor());
+       }
+
+       protected void installOccurrencesFinder() {
+               fMarkOccurrenceAnnotations = true;
+
+               fPostSelectionListenerWithAST = new ISelectionListenerWithAST() {
+                       public void selectionChanged(IEditorPart part,
+                                       ITextSelection selection) { // ,
+                               // CompilationUnit
+                               // astRoot)
+                               // {
+                               updateOccurrenceAnnotations(selection);// , astRoot);
+                       }
+               };
+               SelectionListenerWithASTManager.getDefault().addListener(this,
+                               fPostSelectionListenerWithAST);
+               if (getSelectionProvider() != null) {
+                       fForcedMarkOccurrencesSelection = getSelectionProvider()
+                                       .getSelection();
+                       SelectionListenerWithASTManager.getDefault().forceSelectionChange(
+                                       this, (ITextSelection) fForcedMarkOccurrencesSelection);
+               }
+
+               if (fOccurrencesFinderJobCanceler == null) {
+                       fOccurrencesFinderJobCanceler = new OccurrencesFinderJobCanceler();
+                       fOccurrencesFinderJobCanceler.install();
+               }
+       }
+
+       protected void uninstallOccurrencesFinder() {
+               fMarkOccurrenceAnnotations = false;
+
+               if (fOccurrencesFinderJob != null) {
+                       fOccurrencesFinderJob.cancel();
+                       fOccurrencesFinderJob = null;
+               }
+
+               if (fOccurrencesFinderJobCanceler != null) {
+                       fOccurrencesFinderJobCanceler.uninstall();
+                       fOccurrencesFinderJobCanceler = null;
+               }
+
+               if (fPostSelectionListenerWithAST != null) {
+                       SelectionListenerWithASTManager.getDefault().removeListener(this,
+                                       fPostSelectionListenerWithAST);
+                       fPostSelectionListenerWithAST = null;
+               }
+
+               removeOccurrenceAnnotations();
+       }
+
+       protected boolean isMarkingOccurrences() {
+               return fMarkOccurrenceAnnotations;
+       }
+
+       void removeOccurrenceAnnotations() {
+               fMarkOccurrenceModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+               fMarkOccurrenceTargetRegion = null;
+
+               IDocumentProvider documentProvider = getDocumentProvider();
+               if (documentProvider == null)
+                       return;
+
+               IAnnotationModel annotationModel = documentProvider
+                               .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;
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java
new file mode 100644 (file)
index 0000000..e5569e9
--- /dev/null
@@ -0,0 +1,84 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+
+public interface PHPEditorActionDefinitionIds extends
+               ITextEditorActionDefinitionIds {
+       /**
+        * Action definition ID of the edit -> go to matching bracket action (value
+        * <code>"org.phpeclipse.phpdt.ui.edit.text.php.goto.matching.bracket"</code>).
+        * 
+        * @since 2.1
+        */
+       public static final String GOTO_MATCHING_BRACKET = "net.sourceforge.phpeclipse.ui.edit.text.php.goto.matching.bracket"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the edit -> go to next member action (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.goto.next.member"</code>).
+        * 
+        * @since 2.1
+        */
+       public static final String GOTO_NEXT_MEMBER = "net.sourceforge.phpeclipse.ui.edit.text.php.goto.next.member"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the edit -> go to previous member action (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.goto.previous.member"</code>).
+        * 
+        * @since 2.1
+        */
+       public static final String GOTO_PREVIOUS_MEMBER = "net.sourceforge.phpeclipse.ui.edit.text.php.goto.previous.member"; //$NON-NLS-1$
+
+       /**
+        * Value: net.sourceforge.phpeclipse.phpeditor.comment
+        */
+       public static final String COMMENT = "net.sourceforge.phpeclipse.phpeditor.comment";
+
+       /**
+        * Value: net.sourceforge.phpeclipse.phpeditor.uncomment
+        */
+       public static final String UNCOMMENT = "net.sourceforge.phpeclipse.phpeditor.uncomment";
+
+       /**
+        * Action definition ID of the source -> toggle comment action (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.toggle.comment"</code>).
+        * 
+        * @since 3.0
+        */
+       public static final String TOGGLE_COMMENT = "net.sourceforge.phpeclipse.phpeditor.toggle.comment"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the source -> add block comment action (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.add.block.comment"</code>).
+        * 
+        * @since 3.0
+        */
+       public static final String ADD_BLOCK_COMMENT = "net.sourceforge.phpeclipse.phpeditor.add.block.comment"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the source -> remove block comment action (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.remove.block.comment"</code>).
+        * 
+        * @since 3.0
+        */
+       public static final String REMOVE_BLOCK_COMMENT = "net.sourceforge.phpeclipse.phpeditor.remove.block.comment"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the source -> indent action (value
+        * <code>"net.sourceforge.phpdt.ui.edit.text.java.indent"</code>).
+        */
+       public static final String INDENT = "net.sourceforge.phpeclipse.phpeditor.indent"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the source -> format action
+        */
+       public static final String FORMAT = "net.sourceforge.phpeclipse.phpeditor.format"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the edit -> content assist proposal action (value
+        * <code>"org.phpeclipse.phpdt.ui.edit.text.php.content.assist. proposals"
+        * </code>).
+        */
+       // public static final String CONTENT_ASSIST_PROPOSALS =
+       // "net.sourceforge.phpeclipse.ui.edit.text.php.content.assist.proposals";
+       // //$NON-NLS-1$
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.java
new file mode 100644 (file)
index 0000000..41536b9
--- /dev/null
@@ -0,0 +1,48 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class PHPEditorMessages {
+
+       private static final String RESOURCE_BUNDLE = "net.sourceforge.phpeclipse.phpeditor.PHPEditorMessages";//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       public static String JavaEditor_markOccurrences_job_name = "JavaEditor.markOccurrences.job.name";
+
+       private PHPEditorMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+
+       public static ResourceBundle getResourceBundle() {
+               return fgResourceBundle;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties
new file mode 100644 (file)
index 0000000..82cec7c
--- /dev/null
@@ -0,0 +1,147 @@
+#############################################################
+#
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+#
+#############################################################
+
+## Actions ##
+
+ContentAssistProposal.label=Content Assist@Ctrl+SPACE
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist
+
+ContentAssistTip.label=Content Tip@Ctrl+SHIFT+SPACE
+ContentAssistTip.tooltip=Content Tip
+ContentAssistTip.image=
+ContentAssistTip.description=Content Tip
+
+Format.label=F&ormat
+Format.tooltip=Format the Selected Text
+Format.description=Format the selected text
+
+Comment.label=Comment
+Comment.tooltip=Comment selected lines
+
+Uncomment.label=Uncomment
+Uncomment.tooltip=Uncomment selected lines
+
+TogglePresentation.label=Change Presentation
+TogglePresentation.tooltip=Enable/Disable Segmented Source Viewer
+TogglePresentation.image=togglepresentation.gif
+TogglePresentation.description=Enable/Disable Segmented Source Viewer
+
+ToggleComment.label=Togg&le Comment
+ToggleComment.tooltip=Toggle Comment For the Selected Lines
+ToggleComment.description=Toggle comment for the selected lines
+
+ToggleComment.error.title=Toggle Comment
+ToggleComment.error.message=An error occurred while toggling comments.
+
+AddBlockComment.label=Add &Block Comment
+AddBlockComment.tooltip=Enclose the Selection in a Block Comment
+AddBlockComment.description=Encloses the selection with block comment markers
+
+RemoveBlockComment.label=Remove Bloc&k Comment
+RemoveBlockComment.tooltip=Remove Block Comment Markers Enclosing the Caret
+RemoveBlockComment.description=Removes any block comment markers enclosing the caret
+
+
+OutlinePage.segment.title_pattern=position {0}
+
+AutoIndent.error.bad_location_1=JavaAutoIndentStrategy.getAutoIndentString: BadLocationException
+AutoIndent.error.bad_location_2=JavaAutoIndentStrategy.calcShiftBackReplace: BadLocationException
+
+CompletionProcessor.ContextInfo.display.pattern=proposal {0} at position {1}
+CompletionProcessor.ContextInfo.value.pattern=proposal {0} valid from {1} to {2}
+CompletionProcessor.Proposal.ContextInfo.pattern={0} valid 5 characters around insertion point
+CompletionProcessor.Proposal.hoverinfo.pattern=Java keyword: {0}
+
+ParserAction.label=Parse the PHP file
+ParserAction.tooltip=Parse the current PHP file
+ParserAction.image=java.gif
+ParserAction.description=Parse the current PHP file
+
+GotoMatchingBracket.label=Matching &Bracket
+GotoMatchingBracket.tooltip=Go to Matching Bracket
+GotoMatchingBracket.description=Go to Matching Bracket
+GotoMatchingBracket.error.invalidSelection=No bracket selected
+GotoMatchingBracket.error.noMatchingBracket=No matching bracket found
+GotoMatchingBracket.error.bracketOutsideSelectedElement=Matching bracket is outside of selected element
+
+GotoNextMember.label=N&ext Member
+GotoNextMember.tooltip=Go to N&ext Member
+GotoNextMember.description=Go to N&ext Member
+
+GotoPreviousMember.label=Previ&ous Member
+GotoPreviousMember.tooltip=Go to Previ&ous Member
+GotoPreviousMember.description=Go to Previ&ous Member
+
+AddTask.label=&Task...
+AddTask.tooltip=Add Task
+AddTask.image=
+AddTask.description=Add Task
+AddTask.dialog.title=Add Task
+AddTask.dialog.message=Enter Task description
+AddTask.error.dialog.title=Add Task
+AddTask.error.dialog.message=Problems adding new task
+
+ShowJavaDoc.label=Show &Tooltip Description
+ShowJavaDoc.tooltip=Shows Tooltip Description for Element at Cursor
+ShowJavaDoc.description=Shows the tooltip description for the element at the cursor
+
+EditorUtility.concatModifierStrings= {0} + {1}
+
+
+PHPUnitEditor.error.saving.message1=File has been deleted.
+PHPUnitEditor.error.saving.message2=Could not save file.
+PHPUnitEditor.error.saving.message3=Could not save file.
+PHPUnitEditor.error.saving.title1=Cannot Save
+PHPUnitEditor.error.saving.title2=Save Problems
+PHPUnitEditor.error.saving.title3=Save Problems
+PHPUnitEditor.warning.save.delete=The original file ''{0}'' has been deleted.
+
+PHPUnitEditor.warning.save.nonWorkbenchEncoding.title= Save Resource In Non-Workbench Encoding
+PHPUnitEditor.warning.save.nonWorkbenchEncoding.message1= {0} will be saved in \" {1} \" encoding which is not the current workbench encoding. This can result in conflicts with other tools. Continue anyway?
+PHPUnitEditor.warning.save.nonWorkbenchEncoding.message2= The resource will be saved in \" {0} \" encoding which is not the current platform encoding. This can result in conflicts with other tools. Continue anyway?
+
+JavaOutlinePage.ContextMenu.refactoring.label=&Refactor
+JavaOutlinePage.HideFields.description.checked=Shows Fields
+JavaOutlinePage.HideFields.description.unchecked=Hides Fields
+JavaOutlinePage.HideFields.label=Hide Fields
+JavaOutlinePage.HideFields.tooltip.checked=Show Fields
+JavaOutlinePage.HideFields.tooltip.unchecked=Hide Fields
+JavaOutlinePage.HideNonePublicMembers.description.checked=Shows non-public members
+JavaOutlinePage.HideNonePublicMembers.description.unchecked=Hides non-public members
+JavaOutlinePage.HideNonePublicMembers.label=Show Public Members Only
+JavaOutlinePage.HideNonePublicMembers.tooltip.checked=Show Non-Public Members
+JavaOutlinePage.HideNonePublicMembers.tooltip.unchecked=Hide Non-Public Members
+JavaOutlinePage.HideStaticMembers.description.checked=Shows static members
+JavaOutlinePage.HideStaticMembers.description.unchecked=Hides static members
+JavaOutlinePage.HideStaticMembers.label=Hide Static Members
+JavaOutlinePage.HideStaticMembers.tooltip.checked=Show Static Members
+JavaOutlinePage.HideStaticMembers.tooltip.unchecked=Hide Static Members
+JavaOutlinePage.Sort.label=Sort
+JavaOutlinePage.Sort.tooltip=Sort
+JavaOutlinePage.Sort.description=Enable Sorting
+JavaOutlinePage.GoIntoTopLevelType.label=Go Into Top Level Type
+JavaOutlinePage.GoIntoTopLevelType.tooltip=Go Into Top Level Type
+JavaOutlinePage.GoIntoTopLevelType.description=Show children of top level type only
+JavaOutlinePage.error.ChildrenProvider.getChildren.message1=JavaOutlinePage.ChildrenProvider.getChildren
+JavaOutlinePage.error.ChildrenProvider.hasChildren.message1=JavaOutlinePage.ChildrenProvider.hasChildren
+JavaOutlinePage.error.NoTopLevelType=Top level type not defined
+
+JavaEditor.markOccurrences.job.name= Occurrences Marker
+
+NextAnnotation.label= Ne&xt Annotation
+NextAnnotation.tooltip= Next Annotation
+NextAnnotation.description= Next Annotation
+
+PreviousAnnotation.label= Pre&vious Annotation
+PreviousAnnotation.tooltip= Previous Annotation
+PreviousAnnotation.description= Previous Annotation
+
+Indent.label=Correct &Indentation
+Indent.tooltip=&Indent Current Line to Correct Indentation
+Indent.description=&Indents the current line or selection depending on surrounding source code
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxRdr.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxRdr.java
new file mode 100644 (file)
index 0000000..01c578e
--- /dev/null
@@ -0,0 +1,349 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPConstant;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPElement;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPFunction;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPKeyword;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPType;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * <code>PHPSyntaxRdr</code> reads PHP specifics from an XML file (eg.
+ * keywords)
+ */
+
+public class PHPSyntaxRdr {
+       // private static final String PHPDEFAULT_FILE = "default-syntax.xml";
+       // //$NON-NLS-1$
+       private static final String PHPSYNTAX_FILE = "syntax.xml"; //$NON-NLS-1$
+       // private static final String USERSYNTAX_FILE = "usersyntax.xml";
+       // //$NON-NLS-1$
+       // private static final String USERDEFAULT_FILE = "default-usersyntax.xml";
+       // //$NON-NLS-1$
+
+       private static final String PHPSYNTAX_TAG = "s"; //$NON-NLS-1$
+
+       private static final String KEYWORD_ATTR = "k"; //$NON-NLS-1$
+
+       private static final String TYPE_ATTR = "t"; //$NON-NLS-1$
+
+       private static final String CONSTANT_ATTR = "c"; //$NON-NLS-1$
+
+       private static final String FN_ATTR = "f"; //$NON-NLS-1$
+
+       private static final String USAGE_ATTR = "u"; //$NON-NLS-1$
+       // private static final String TOKENVAL_ATTR = "tokenval"; //$NON-NLS-1$
+
+       private static IPreferenceStore store;
+
+       //private static boolean hasXMLFileBeenRead = true;
+
+       // The following variable is used to hold the syntax from
+       // the suers custom file - if that file should be changed,
+       // then all entries in this variable should be removed from
+       // the word list, reread from the file and then reinserted.
+       private static ArrayList userdefsyntaxdata;
+
+       private static ArrayList syntaxdata;
+
+       public PHPSyntaxRdr() {
+               // see getSyntaxData()
+               syntaxdata = null;
+               store = WebUI.getDefault().getPreferenceStore();
+       }
+
+       public static void readInSyntax() {
+               try {
+//                     hasXMLFileBeenRead = true;
+                       /*
+                        * Attempt to read the syntax file from the metadata if this does
+                        * not work, create metadata from default
+                        */
+                       /*File syntaxFile = getSyntaxFile();
+                       if (syntaxFile.exists()) {
+                               readFromFile(syntaxFile);
+                       } else {*/
+                               readFromStream(PHPSyntaxRdr.class
+                                               .getResourceAsStream(PHPSYNTAX_FILE));
+                               //saveToFile(syntaxFile);
+                       /*}*/
+                       /* Read the user-defined syntax file if it exists */
+                       // String buffer = new
+                       // String(store.getString(PHPeclipsePlugin.PHP_USERDEF_XMLFILE));
+                       /*if (store == null)
+                               store = PHPeclipsePlugin.getDefault().getPreferenceStore();
+                       String buffer = new String(store
+                                       .getString(IPreferenceConstants.PHP_USERDEF_XMLFILE));
+                       if (!(buffer.equals("") || buffer == null)) {
+                               readFromFile(buffer);
+                       }*/
+               } catch (CoreException ce) {
+                       ce.printStackTrace();
+               }
+       }
+
+       public static void readFromFile(String filename) {
+               try {
+                       readFromFile(new File(filename));
+               } catch (CoreException e) {
+               }
+       }
+
+       public static void readFromFile(File file) throws CoreException {
+               InputStream stream = null;
+
+               if (file.exists()) {
+                       try {
+                               stream = new FileInputStream(file);
+                               readFromStream(stream);
+                       } catch (IOException e) {
+                               throwReadException(e);
+                       } finally {
+                               try {
+                                       if (stream != null) {
+                                               stream.close();
+                                       }
+                               } catch (IOException e) {
+                               }
+                       }
+               }
+       }
+
+       public static void readFromStream(InputStream stream) throws CoreException {
+               try {
+                       DocumentBuilderFactory factory = DocumentBuilderFactory
+                                       .newInstance();
+                       DocumentBuilder parser = factory.newDocumentBuilder();
+                       Document document = parser.parse(new InputSource(stream));
+                       // Read in the Standard PHPSyntax "stuff"
+                       NodeList elements = document.getElementsByTagName(PHPSYNTAX_TAG);
+
+                       int count = elements.getLength();
+                       for (int i = 0; i != count; i++) {
+                               Node node = elements.item(i);
+                               NamedNodeMap attributes = node.getAttributes();
+
+                               if (attributes == null)
+                                       continue;
+
+                               String Keyword = getAttributeValue(attributes, KEYWORD_ATTR);
+                               String Type = getAttributeValue(attributes, TYPE_ATTR);
+                               String Function = getAttributeValue(attributes, FN_ATTR);
+                               String Constant = getAttributeValue(attributes, CONSTANT_ATTR);
+                               String usage = getAttributeValue(attributes, USAGE_ATTR);
+                               // String Tokenval = getAttributeValue(attributes,
+                               // TOKENVAL_ATTR);
+
+                               StringBuffer buffer = new StringBuffer();
+                               NodeList children = node.getChildNodes();
+                               for (int j = 0; j != children.getLength(); j++) {
+                                       String value = children.item(j).getNodeValue();
+                                       if (value != null)
+                                               buffer.append(value);
+                               }
+                               String description = buffer.toString().trim();
+
+                               if (Keyword == null && Type == null && Function == null
+                                               && Constant == null) {
+                                       // ignore as it is not a valid phpsyntax tag
+                               } else {
+                                       if (Keyword != null) {
+                                               // syntaxdata.add(new PHPKeyword(Keyword, usage,
+                                               // Tokenval));
+                                               syntaxdata.add(new PHPKeyword(Keyword, usage));
+                                       } else if (Type != null) {
+                                               syntaxdata.add(new PHPType(Type, usage));
+                                       } else if (Function != null) {
+                                               syntaxdata.add(new PHPFunction(Function, usage,
+                                                               description));
+                                       } else if (Constant != null) {
+                                               syntaxdata.add(new PHPConstant(Constant, null,
+                                                               description));
+                                       }
+                               }
+                       }
+               } catch (ParserConfigurationException e) {
+                       throwReadException(e);
+               } catch (IOException e) {
+                       throwReadException(e);
+               } catch (SAXParseException e) {
+                       System.out.println("SAXParseException in line:" + e.getLineNumber()
+                                       + " column:" + e.getColumnNumber());
+                       throwReadException(e);
+               } catch (SAXException e) {
+                       throwReadException(e);
+               }
+       }
+
+       public static ArrayList getSyntaxData() {
+               if (syntaxdata == null) {
+                       syntaxdata = new ArrayList();
+                       readInSyntax();
+               }
+               return syntaxdata;
+       }
+
+       public static void replaceUserDefFile() {
+               /* Replace the user-defined syntax file if it exists */
+               String buffer = new String(store
+                               .getString(IPreferenceConstants.PHP_USERDEF_XMLFILE));
+               if (!buffer.equals("") || buffer == null) {
+                       readFromFile(buffer);
+               }
+       }
+
+       public static ArrayList getUserSyntaxData() {
+               return userdefsyntaxdata;
+       }
+
+       private static File getSyntaxFile() {
+               IPath path = PHPeclipsePlugin.getDefault().getStateLocation();
+               path = path.append(PHPSYNTAX_FILE);
+               return path.toFile();
+       }
+
+       private static String getAttributeValue(NamedNodeMap attributes, String name) {
+               Node node = attributes.getNamedItem(name);
+               return node == null ? null : node.getNodeValue();
+       }
+
+       public static void saveToFile(File file) throws CoreException {
+               OutputStream stream = null;
+               try {
+                       stream = new FileOutputStream(file);
+                       saveToStream(stream);
+               } catch (IOException e) {
+                       throwWriteException(e);
+               } finally {
+                       try {
+                               if (stream != null)
+                                       stream.close();
+                       } catch (IOException e) {
+                       }
+               }
+       }
+
+       public static void saveToStream(OutputStream stream) throws CoreException {
+               try {
+                       DocumentBuilderFactory factory = DocumentBuilderFactory
+                                       .newInstance();
+                       DocumentBuilder builder = factory.newDocumentBuilder();
+                       Document document = builder.newDocument();
+                       Node root = document.createElement("PHPStandardSyntax"); // $NON-NLS-1$
+                                                                                                                                               // //$NON-NLS-1$
+                       document.appendChild(root);
+                       for (int i = 0; i != syntaxdata.size(); i++) {
+                               Object bufferobj = (Object) syntaxdata.get(i);
+                               Attr name = null;
+                               Node node = document.createElement(PHPSYNTAX_TAG); // $NON-NLS-1$
+                                                                                                                                       // //$NON-NLS-1$
+                               root.appendChild(node);
+                               NamedNodeMap attributes = node.getAttributes();
+                               if (bufferobj instanceof PHPType)
+                                       name = document.createAttribute(TYPE_ATTR);
+                               if (bufferobj instanceof PHPKeyword)
+                                       name = document.createAttribute(KEYWORD_ATTR);
+                               if (bufferobj instanceof PHPFunction)
+                                       name = document.createAttribute(FN_ATTR);
+                               if (bufferobj instanceof PHPConstant)
+                                       name = document.createAttribute(CONSTANT_ATTR);
+                               name.setValue(((PHPElement) bufferobj).getName());
+                               attributes.setNamedItem(name);
+                               Attr description = document.createAttribute(USAGE_ATTR);
+                               description.setValue(((PHPElement) bufferobj).getUsage());
+                               attributes.setNamedItem(description);
+                               // if (bufferobj instanceof PHPKeyword) {
+                               // Attr tokenval = document.createAttribute(TOKENVAL_ATTR);
+                               // tokenval.setValue((new Integer(((PHPKeyword)
+                               // bufferobj).gettokenval())).toString());
+                               // attributes.setNamedItem(tokenval);
+                               // }
+                               if (bufferobj instanceof PHPFunction) {
+                                       // Attr usage = document.createAttribute(USAGE_ATTR);
+                                       Text usage = document
+                                                       .createTextNode(((PHPFunction) bufferobj)
+                                                                       .getDescription());
+                                       node.appendChild(usage);
+                               }
+                               if (bufferobj instanceof PHPConstant) {
+                                       // Attr usage = document.createAttribute(USAGE_ATTR);
+                                       Text usage = document
+                                                       .createTextNode(((PHPConstant) bufferobj)
+                                                                       .getDescription());
+                                       node.appendChild(usage);
+                               }
+                       }
+                       Transformer transformer = TransformerFactory.newInstance()
+                                       .newTransformer();
+                       transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+                       transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+                       DOMSource source = new DOMSource(document);
+                       StreamResult result = new StreamResult(stream);
+
+                       transformer.transform(source, result);
+
+               } catch (ParserConfigurationException e) {
+                       throwWriteException(e);
+               } catch (TransformerException e) {
+                       throwWriteException(e);
+               }
+               // OutputFormat format = new OutputFormat();
+               // format.setPreserveSpace(true);
+               // try {
+               // Serializer serializer =
+               // SerializerFactory.getSerializerFactory("xml").makeSerializer(stream,
+               // format);
+               // serializer.asDOMSerializer().serialize(document);
+               // } catch (UnsupportedEncodingException e) {
+               // } catch (IOException e) {
+               // } //$NON-NLS-1$
+               // // Serializer serializer =
+               // SerializerFactory.getSerializer().makeSerializer(stream, format);
+               // //$NON-NLS-1$
+               // } catch (ParserConfigurationException e) {
+               // throwWriteException(e);
+               // }
+       }
+
+       private static void throwReadException(Throwable t) throws CoreException {
+               PHPeclipsePlugin.log(t);
+       }
+
+       private static void throwWriteException(Throwable t) throws CoreException {
+               PHPeclipsePlugin.log(t);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java
new file mode 100644 (file)
index 0000000..9b2a03d
--- /dev/null
@@ -0,0 +1,152 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.corext.phpdoc.PHPDocUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPElement;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPFunction;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IProject;
+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.swt.graphics.Point;
+
+/**
+ * Implementation for an <code>ITextHover</code> which hovers over PHP code.
+ */
+public class PHPTextHover implements ITextHover {
+       private static HashMap functionDescriptions = null;
+
+       private static HashMap identDescriptions = null;
+
+       /**
+        * The current project; maybe <code>null</code> for preference pages
+        */
+       private IProject fProject;
+
+       public PHPTextHover(IProject project) {
+               fProject = project;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ITextHover
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+               if (hoverRegion != null) {
+                       try {
+                               if (hoverRegion.getLength() > -1) {
+                                       String word = textViewer.getDocument().get(
+                                                       hoverRegion.getOffset(), hoverRegion.getLength());
+                                       if (functionDescriptions == null) {
+                                               functionDescriptions = new HashMap();
+                                               identDescriptions = new HashMap();
+                                               ArrayList syntaxbuffer = PHPSyntaxRdr.getSyntaxData();
+                                               PHPElement elbuffer = null;
+                                               if (syntaxbuffer != null) {
+                                                       for (int i = 0; i < syntaxbuffer.size(); i++) {
+                                                               elbuffer = (PHPElement) syntaxbuffer.get(i);
+                                                               if (elbuffer instanceof PHPFunction) {
+                                                                       functionDescriptions.put(
+                                                                                       elbuffer.getName(), elbuffer
+                                                                                                       .getHoverText());
+                                                               } else {
+                                                                       identDescriptions.put(elbuffer.getName(),
+                                                                                       elbuffer.getHoverText());
+                                                               }
+                                                       }
+                                               }
+                                               //
+                                               // while ((syntaxbuffer != null)
+                                               // && (!syntaxbuffer.isEmpty() && ((elbuffer =
+                                               // (PHPElement)
+                                               // syntaxbuffer.remove(0)) != null))) {
+                                               // functionDescriptions.put(elbuffer.getName(),
+                                               // elbuffer.getHoverText());
+                                               // }
+                                       }
+                                       String hoverInfo = (String) identDescriptions.get(word);
+                                       if (hoverInfo == null & word.length() > 0) {
+                                               hoverInfo = (String) functionDescriptions.get(word
+                                                               .toLowerCase());
+                                       }
+                                       if (hoverInfo == null && fProject != null) {
+                                               // get the possible PHPDoc information from the index
+                                               // file
+                                               IdentifierIndexManager indexManager = WebUI
+                                                               .getDefault().getIndexManager(fProject);
+                                               List list = indexManager.getLocations(word);
+                                               if (list.size() > 0) {
+                                                       try {
+                                                               PHPIdentifierLocation location;
+                                                               String filename;
+                                                               StringBuffer hoverInfoBuffer = new StringBuffer();
+                                                               String workspaceLocation;
+                                                               if (fProject != null) {
+                                                                       workspaceLocation = fProject.getLocation()
+                                                                                       .toString() + '/';
+                                                               } else {
+                                                                       // should never happen?
+                                                                       workspaceLocation = PHPeclipsePlugin
+                                                                                       .getWorkspace().getRoot()
+                                                                                       .getLocation().toString();
+                                                               }
+                                                               // boolean foundPHPdoc = false;
+                                                               for (int i = 0; i < list.size(); i++) {
+                                                                       location = (PHPIdentifierLocation) list
+                                                                                       .get(i);
+                                                                       filename = workspaceLocation
+                                                                                       + location.getFilename();
+                                                                       PHPDocUtil.appendPHPDoc(hoverInfoBuffer,
+                                                                                       filename, location);
+                                                               }
+                                                               hoverInfo = hoverInfoBuffer.toString();
+                                                       } catch (Throwable e) {
+                                                               // ignore exceptions
+                                                               // e.printStackTrace();
+                                                       }
+                                               }
+                                       }
+                                       return hoverInfo;
+                               }
+                               // } catch (BadLocationException x) {
+                       } catch (Exception x) {
+                       }
+               }
+               return null;
+               // don't show this annoying text
+               // return "empty selection";
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ITextHover
+        */
+       public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+               Point selection = PHPWordExtractor.findWord(textViewer.getDocument(),
+                               offset);
+               // show the extracted word as a tooltip
+               if (selection != null && selection.x <= offset
+                               && offset < selection.x + selection.y)
+                       return new Region(selection.x, selection.y);
+               return new Region(offset, 0);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java
new file mode 100644 (file)
index 0000000..e0e5151
--- /dev/null
@@ -0,0 +1,2766 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.dom.CompilationUnit;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+import net.sourceforge.phpdt.internal.ui.actions.AddBlockCommentAction;
+import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
+import net.sourceforge.phpdt.internal.ui.actions.IndentAction;
+import net.sourceforge.phpdt.internal.ui.actions.RemoveBlockCommentAction;
+import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner;
+import net.sourceforge.phpdt.internal.ui.text.JavaIndenter;
+import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
+import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager;
+import net.sourceforge.phpdt.internal.ui.text.SmartSemicolonAutoEditStrategy;
+import net.sourceforge.phpdt.internal.ui.text.comment.CommentFormattingContext;
+import net.sourceforge.phpdt.internal.ui.text.java.IJavaReconcilingListener;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI.ExitFlags;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.actions.GenerateActionGroup;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.actions.RTrimAction;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.editor.ShowExternalPreviewAction;
+
+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.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.IWidgetTokenKeeper;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.formatter.FormattingContextProperties;
+import org.eclipse.jface.text.formatter.IFormattingContext;
+import org.eclipse.jface.text.source.IOverviewRuler;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.editors.text.IStorageDocumentProvider;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+/*******************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Common Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: IBM Corporation - Initial implementation
+ * www.phpeclipse.de
+ ******************************************************************************/
+/**
+ * PHP specific text editor.
+ */
+public class PHPUnitEditor extends PHPEditor { // implements
+       // IJavaReconcilingListener {
+       interface ITextConverter {
+               void customizeDocumentCommand(IDocument document,
+                               DocumentCommand command);
+       };
+
+       // class AdaptedSourceViewer extends JavaSourceViewer {
+       // private List fTextConverters;
+       //
+       // private boolean fIgnoreTextConverters = false;
+       //
+       // // private JavaCorrectionAssistant fCorrectionAssistant;
+       // public AdaptedSourceViewer(Composite parent, IVerticalRuler
+       // verticalRuler,
+       // IOverviewRuler overviewRuler, boolean showAnnotationsOverview,
+       // int styles, IPreferenceStore store) {
+       // super(parent, verticalRuler, overviewRuler, showAnnotationsOverview,
+       // styles, store);
+       // }
+       //
+       // // public AdaptedSourceViewer(Composite parent,
+       // // IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
+       // // boolean showAnnotationsOverview, int styles) {
+       // // super(parent, verticalRuler, overviewRuler,
+       // // showAnnotationsOverview, styles);
+       // // }
+       // public IContentAssistant getContentAssistant() {
+       // return fContentAssistant;
+       // }
+       //
+       // /*
+       // * @see ITextOperationTarget#doOperation(int)
+       // */
+       // public void doOperation(int operation) {
+       // if (getTextWidget() == null)
+       // return;
+       // switch (operation) {
+       // case CONTENTASSIST_PROPOSALS:
+       // String msg = fContentAssistant.showPossibleCompletions();
+       // setStatusLineErrorMessage(msg);
+       // return;
+       // // case CORRECTIONASSIST_PROPOSALS:
+       // // fCorrectionAssistant.showPossibleCompletions();
+       // // return;
+       // case UNDO:
+       // fIgnoreTextConverters = true;
+       // break;
+       // case REDO:
+       // fIgnoreTextConverters = true;
+       // break;
+       // }
+       // super.doOperation(operation);
+       // }
+       //
+       // /*
+       // * @see ITextOperationTarget#canDoOperation(int)
+       // */
+       // public boolean canDoOperation(int operation) {
+       // // if (operation == CORRECTIONASSIST_PROPOSALS)
+       // // return isEditable();
+       // return super.canDoOperation(operation);
+       // }
+       //
+       // /*
+       // * @see TextViewer#handleDispose()
+       // */
+       // protected void handleDispose() {
+       // // if (fCorrectionAssistant != null) {
+       // // fCorrectionAssistant.uninstall();
+       // // fCorrectionAssistant= null;
+       // // }
+       // super.handleDispose();
+       // }
+       //
+       // public void insertTextConverter(ITextConverter textConverter, int index)
+       // {
+       // throw new UnsupportedOperationException();
+       // }
+       //
+       // public void addTextConverter(ITextConverter textConverter) {
+       // if (fTextConverters == null) {
+       // fTextConverters = new ArrayList(1);
+       // fTextConverters.add(textConverter);
+       // } else if (!fTextConverters.contains(textConverter))
+       // fTextConverters.add(textConverter);
+       // }
+       //
+       // public void removeTextConverter(ITextConverter textConverter) {
+       // if (fTextConverters != null) {
+       // fTextConverters.remove(textConverter);
+       // if (fTextConverters.size() == 0)
+       // fTextConverters = null;
+       // }
+       // }
+       //
+       // /*
+       // * @see TextViewer#customizeDocumentCommand(DocumentCommand)
+       // */
+       // protected void customizeDocumentCommand(DocumentCommand command) {
+       // super.customizeDocumentCommand(command);
+       // if (!fIgnoreTextConverters && fTextConverters != null) {
+       // for (Iterator e = fTextConverters.iterator(); e.hasNext();)
+       // ((ITextConverter) e.next()).customizeDocumentCommand(getDocument(),
+       // command);
+       // }
+       // fIgnoreTextConverters = false;
+       // }
+       //
+       // // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
+       // public void updateIndentationPrefixes() {
+       // SourceViewerConfiguration configuration = getSourceViewerConfiguration();
+       // String[] types = configuration.getConfiguredContentTypes(this);
+       // for (int i = 0; i < types.length; i++) {
+       // String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
+       // if (prefixes != null && prefixes.length > 0)
+       // setIndentPrefixes(prefixes, types[i]);
+       // }
+       // }
+       //
+       // /*
+       // * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
+       // */
+       // public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
+       // if (WorkbenchHelp.isContextHelpDisplayed())
+       // return false;
+       // return super.requestWidgetToken(requester);
+       // }
+       //
+       // // /*
+       // // * @see
+       // org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
+       // // */
+       // // public void configure(SourceViewerConfiguration configuration) {
+       // // super.configure(configuration);
+       // // // fCorrectionAssistant= new
+       // // // JavaCorrectionAssistant(CompilationUnitEditor.this);
+       // // // fCorrectionAssistant.install(this);
+       // // //TODO install SmartBracesAutoEditStrategy
+       // // // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this),
+       // // // IDocument.DEFAULT_CONTENT_TYPE);
+       // // }
+       // public void configure(SourceViewerConfiguration configuration) {
+       // super.configure(configuration);
+       // // fCorrectionAssistant= new
+       // JavaCorrectionAssistant(CompilationUnitEditor.this);
+       // // fCorrectionAssistant.install(this);
+       // IAutoEditStrategy smartSemi= new
+       // SmartSemicolonAutoEditStrategy(IPHPPartitions.PHP_PARTITIONING);
+       // prependAutoEditStrategy(smartSemi, IDocument.DEFAULT_CONTENT_TYPE);
+       // prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_DQ);
+       // prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_SQ);
+       // // prependAutoEditStrategy(smartSemi, IPHPPartitions.JAVA_CHARACTER);
+       // }
+       // };
+       class AdaptedSourceViewer extends JavaSourceViewer {
+
+               private List fTextConverters;
+
+               private boolean fIgnoreTextConverters = false;
+
+               // private JavaCorrectionAssistant fCorrectionAssistant;
+
+               public AdaptedSourceViewer(Composite parent,
+                               IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
+                               boolean showAnnotationsOverview, int styles,
+                               IPreferenceStore store) {
+                       super(parent, verticalRuler, overviewRuler,
+                                       showAnnotationsOverview, styles, store);
+               }
+
+               public IContentAssistant getContentAssistant() {
+                       return fContentAssistant;
+               }
+
+               /*
+                * @see ITextOperationTarget#doOperation(int)
+                */
+               public void doOperation(int operation) {
+
+                       if (getTextWidget() == null)
+                               return;
+
+                       switch (operation) {
+                       case CONTENTASSIST_PROPOSALS:
+                               String msg = fContentAssistant.showPossibleCompletions();
+                               setStatusLineErrorMessage(msg);
+                               return;
+                               // case CORRECTIONASSIST_PROPOSALS:
+                               // msg = fCorrectionAssistant.showPossibleCompletions();
+                               // setStatusLineErrorMessage(msg);
+                               // return;
+                       case UNDO:
+                               fIgnoreTextConverters = true;
+                               super.doOperation(operation);
+                               fIgnoreTextConverters = false;
+                               return;
+                       case REDO:
+                               fIgnoreTextConverters = true;
+                               super.doOperation(operation);
+                               fIgnoreTextConverters = false;
+                               return;
+                       }
+
+                       super.doOperation(operation);
+               }
+
+               /*
+                * @see ITextOperationTarget#canDoOperation(int)
+                */
+               public boolean canDoOperation(int operation) {
+                       // if (operation == CORRECTIONASSIST_PROPOSALS)
+                       // return isEditable();
+
+                       return super.canDoOperation(operation);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.ISourceViewerExtension2#unconfigure()
+                * @since 3.0
+                */
+               public void unconfigure() {
+                       // if (fCorrectionAssistant != null) {
+                       // fCorrectionAssistant.uninstall();
+                       // fCorrectionAssistant = null;
+                       // }
+                       super.unconfigure();
+               }
+
+               public void insertTextConverter(ITextConverter textConverter, int index) {
+                       throw new UnsupportedOperationException();
+               }
+
+               public void addTextConverter(ITextConverter textConverter) {
+                       if (fTextConverters == null) {
+                               fTextConverters = new ArrayList(1);
+                               fTextConverters.add(textConverter);
+                       } else if (!fTextConverters.contains(textConverter))
+                               fTextConverters.add(textConverter);
+               }
+
+               public void removeTextConverter(ITextConverter textConverter) {
+                       if (fTextConverters != null) {
+                               fTextConverters.remove(textConverter);
+                               if (fTextConverters.size() == 0)
+                                       fTextConverters = null;
+                       }
+               }
+
+               /*
+                * @see TextViewer#customizeDocumentCommand(DocumentCommand)
+                */
+               protected void customizeDocumentCommand(DocumentCommand command) {
+                       super.customizeDocumentCommand(command);
+                       if (!fIgnoreTextConverters && fTextConverters != null) {
+                               for (Iterator e = fTextConverters.iterator(); e.hasNext();)
+                                       ((ITextConverter) e.next()).customizeDocumentCommand(
+                                                       getDocument(), command);
+                       }
+               }
+
+               // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
+               public void updateIndentationPrefixes() {
+                       SourceViewerConfiguration configuration = getSourceViewerConfiguration();
+                       String[] types = configuration.getConfiguredContentTypes(this);
+                       for (int i = 0; i < types.length; i++) {
+                               String[] prefixes = configuration.getIndentPrefixes(this,
+                                               types[i]);
+                               if (prefixes != null && prefixes.length > 0)
+                                       setIndentPrefixes(prefixes, types[i]);
+                       }
+               }
+
+               /*
+                * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
+                */
+               public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
+                       if (PlatformUI.getWorkbench().getHelpSystem()
+                                       .isContextHelpDisplayed())
+                               return false;
+                       return super.requestWidgetToken(requester);
+               }
+
+               /*
+                * @see IWidgetTokenOwnerExtension#requestWidgetToken(IWidgetTokenKeeper,
+                *      int)
+                * @since 3.0
+                */
+               public boolean requestWidgetToken(IWidgetTokenKeeper requester,
+                               int priority) {
+                       if (PlatformUI.getWorkbench().getHelpSystem()
+                                       .isContextHelpDisplayed())
+                               return false;
+                       return super.requestWidgetToken(requester, priority);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
+                */
+               public void configure(SourceViewerConfiguration configuration) {
+                       super.configure(configuration);
+                       // fCorrectionAssistant = new
+                       // JavaCorrectionAssistant(CompilationUnitEditor.this);
+                       // fCorrectionAssistant.install(this);
+                       IAutoEditStrategy smartSemi = new SmartSemicolonAutoEditStrategy(
+                                       IPHPPartitions.PHP_PARTITIONING);
+                       prependAutoEditStrategy(smartSemi, IDocument.DEFAULT_CONTENT_TYPE);
+                       prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_DQ);
+                       prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_SQ);
+                       prependAutoEditStrategy(smartSemi,
+                                       IPHPPartitions.PHP_STRING_HEREDOC);
+               }
+
+               /*
+                * @see org.eclipse.jface.text.source.SourceViewer#createFormattingContext()
+                * @since 3.0
+                */
+               public IFormattingContext createFormattingContext() {
+                       IFormattingContext context = new CommentFormattingContext();
+
+                       Map preferences;
+                       IJavaElement inputJavaElement = getInputJavaElement();
+                       IJavaProject javaProject = inputJavaElement != null ? inputJavaElement
+                                       .getJavaProject()
+                                       : null;
+                       if (javaProject == null)
+                               preferences = new HashMap(JavaCore.getOptions());
+                       else
+                               preferences = new HashMap(javaProject.getOptions(true));
+
+                       context.storeToMap(PreferenceConstants.getPreferenceStore(),
+                                       preferences, false);
+                       context.setProperty(
+                                       FormattingContextProperties.CONTEXT_PREFERENCES,
+                                       preferences);
+
+                       return context;
+               }
+       }
+
+       /**
+        * Remembers data related to the current selection to be able to restore it
+        * later.
+        * 
+        * @since 3.0
+        */
+       private class RememberedSelection {
+               /** The remembered selection start. */
+               private RememberedOffset fStartOffset = new RememberedOffset();
+
+               /** The remembered selection end. */
+               private RememberedOffset fEndOffset = new RememberedOffset();
+
+               /**
+                * Remember current selection.
+                */
+               public void remember() {
+                       /*
+                        * https://bugs.eclipse.org/bugs/show_bug.cgi?id=52257 This method
+                        * may be called inside an async call posted to the UI thread, so
+                        * protect against intermediate disposal of the editor.
+                        */
+                       ISourceViewer viewer = getSourceViewer();
+                       if (viewer != null) {
+                               IRegion selection = getSignedSelection(viewer);
+                               int startOffset = selection.getOffset();
+                               int endOffset = startOffset + selection.getLength();
+
+                               fStartOffset.setOffset(startOffset);
+                               fEndOffset.setOffset(endOffset);
+                       }
+               }
+
+               /**
+                * Restore remembered selection.
+                */
+               public void restore() {
+                       /*
+                        * https://bugs.eclipse.org/bugs/show_bug.cgi?id=52257 This method
+                        * may be called inside an async call posted to the UI thread, so
+                        * protect against intermediate disposal of the editor.
+                        */
+                       if (getSourceViewer() == null)
+                               return;
+
+                       try {
+
+                               int startOffset, endOffset;
+                               int revealStartOffset, revealEndOffset;
+                               if (showsHighlightRangeOnly()) {
+                                       IJavaElement newStartElement = fStartOffset.getElement();
+                                       startOffset = fStartOffset
+                                                       .getRememberedOffset(newStartElement);
+                                       revealStartOffset = fStartOffset.getRevealOffset(
+                                                       newStartElement, startOffset);
+                                       if (revealStartOffset == -1)
+                                               startOffset = -1;
+
+                                       IJavaElement newEndElement = fEndOffset.getElement();
+                                       endOffset = fEndOffset.getRememberedOffset(newEndElement);
+                                       revealEndOffset = fEndOffset.getRevealOffset(newEndElement,
+                                                       endOffset);
+                                       if (revealEndOffset == -1)
+                                               endOffset = -1;
+                               } else {
+                                       startOffset = fStartOffset.getOffset();
+                                       revealStartOffset = startOffset;
+                                       endOffset = fEndOffset.getOffset();
+                                       revealEndOffset = endOffset;
+                               }
+
+                               if (startOffset == -1) {
+                                       startOffset = endOffset; // fallback to caret offset
+                                       revealStartOffset = revealEndOffset;
+                               }
+
+                               if (endOffset == -1) {
+                                       endOffset = startOffset; // fallback to other offset
+                                       revealEndOffset = revealStartOffset;
+                               }
+
+                               IJavaElement element;
+                               if (endOffset == -1) {
+                                       // fallback to element selection
+                                       element = fEndOffset.getElement();
+                                       if (element == null)
+                                               element = fStartOffset.getElement();
+                                       if (element != null)
+                                               setSelection(element);
+                                       return;
+                               }
+
+                               if (isValidSelection(revealStartOffset, revealEndOffset
+                                               - revealStartOffset)
+                                               && isValidSelection(startOffset, endOffset
+                                                               - startOffset))
+                                       selectAndReveal(startOffset, endOffset - startOffset,
+                                                       revealStartOffset, revealEndOffset
+                                                                       - revealStartOffset);
+                       } finally {
+                               fStartOffset.clear();
+                               fEndOffset.clear();
+                       }
+               }
+
+               private boolean isValidSelection(int offset, int length) {
+                       IDocumentProvider provider = getDocumentProvider();
+                       if (provider != null) {
+                               IDocument document = provider.getDocument(getEditorInput());
+                               if (document != null) {
+                                       int end = offset + length;
+                                       int documentLength = document.getLength();
+                                       return 0 <= offset && offset <= documentLength && 0 <= end
+                                                       && end <= documentLength;
+                               }
+                       }
+                       return false;
+               }
+
+       }
+
+       /**
+        * Remembers additional data for a given offset to be able restore it later.
+        * 
+        * @since 3.0
+        */
+       private class RememberedOffset {
+               /** Remembered line for the given offset */
+               private int fLine;
+
+               /** Remembered column for the given offset */
+               private int fColumn;
+
+               /** Remembered Java element for the given offset */
+               private IJavaElement fElement;
+
+               /** Remembered Java element line for the given offset */
+               private int fElementLine;
+
+               /**
+                * Store visual properties of the given offset.
+                * 
+                * @param offset
+                *            Offset in the document
+                */
+               public void setOffset(int offset) {
+                       try {
+                               IDocument document = getSourceViewer().getDocument();
+                               fLine = document.getLineOfOffset(offset);
+                               fColumn = offset - document.getLineOffset(fLine);
+                               fElement = getElementAt(offset, true);
+
+                               fElementLine = -1;
+                               if (fElement instanceof IMember) {
+                                       ISourceRange range = ((IMember) fElement).getNameRange();
+                                       if (range != null)
+                                               fElementLine = document.getLineOfOffset(range
+                                                               .getOffset());
+                               }
+                               if (fElementLine == -1)
+                                       fElementLine = document
+                                                       .getLineOfOffset(getOffset(fElement));
+                       } catch (BadLocationException e) {
+                               // should not happen
+                               PHPeclipsePlugin.log(e);
+                               clear();
+                       } catch (JavaModelException e) {
+                               // should not happen
+                               PHPeclipsePlugin.log(e.getStatus());
+                               clear();
+                       }
+               }
+
+               /**
+                * Return offset recomputed from stored visual properties.
+                * 
+                * @return Offset in the document
+                */
+               public int getOffset() {
+                       IJavaElement newElement = getElement();
+
+                       int offset = getRememberedOffset(newElement);
+
+                       if (offset != -1 && !containsOffset(newElement, offset)
+                                       && (offset == 0 || !containsOffset(newElement, offset - 1)))
+                               return -1;
+
+                       return offset;
+               }
+
+               /**
+                * Return offset recomputed from stored visual properties.
+                * 
+                * @param newElement
+                *            Enclosing element
+                * @return Offset in the document
+                */
+               public int getRememberedOffset(IJavaElement newElement) {
+                       try {
+                               if (newElement == null)
+                                       return -1;
+
+                               IDocument document = getSourceViewer().getDocument();
+                               int newElementLine = -1;
+                               if (newElement instanceof IMember) {
+                                       ISourceRange range = ((IMember) newElement).getNameRange();
+                                       if (range != null)
+                                               newElementLine = document.getLineOfOffset(range
+                                                               .getOffset());
+                               }
+                               if (newElementLine == -1)
+                                       newElementLine = document
+                                                       .getLineOfOffset(getOffset(newElement));
+                               if (newElementLine == -1)
+                                       return -1;
+
+                               int newLine = fLine + newElementLine - fElementLine;
+                               if (newLine < 0 || newLine >= document.getNumberOfLines())
+                                       return -1;
+                               int maxColumn = document.getLineLength(newLine);
+                               String lineDelimiter = document.getLineDelimiter(newLine);
+                               if (lineDelimiter != null)
+                                       maxColumn = maxColumn - lineDelimiter.length();
+                               int offset;
+                               if (fColumn > maxColumn)
+                                       offset = document.getLineOffset(newLine) + maxColumn;
+                               else
+                                       offset = document.getLineOffset(newLine) + fColumn;
+
+                               return offset;
+                       } catch (BadLocationException e) {
+                               // should not happen
+                               PHPeclipsePlugin.log(e);
+                               return -1;
+                       } catch (JavaModelException e) {
+                               // should not happen
+                               PHPeclipsePlugin.log(e.getStatus());
+                               return -1;
+                       }
+               }
+
+               /**
+                * Returns the offset used to reveal the given element based on the
+                * given selection offset.
+                * 
+                * @param element
+                *            the element
+                * @param offset
+                *            the selection offset
+                * @return the offset to reveal the given element based on the given
+                *         selection offset
+                */
+               public int getRevealOffset(IJavaElement element, int offset) {
+                       if (element == null || offset == -1)
+                               return -1;
+
+                       if (containsOffset(element, offset)) {
+                               if (offset > 0) {
+                                       IJavaElement alternateElement = getElementAt(offset, false);
+                                       if (element.getHandleIdentifier().equals(
+                                                       alternateElement.getParent().getHandleIdentifier()))
+                                               return offset - 1; // Solves test case 2 from
+                                                                                       // https://bugs.eclipse.org/bugs/show_bug.cgi?id=47727#c3
+                               }
+                               return offset;
+                       } else if (offset > 0 && containsOffset(element, offset - 1))
+                               return offset - 1; // Solves test case 1 from
+                                                                       // https://bugs.eclipse.org/bugs/show_bug.cgi?id=47727#c3
+
+                       return -1;
+               }
+
+               /**
+                * Return Java element recomputed from stored visual properties.
+                * 
+                * @return Java element
+                */
+               public IJavaElement getElement() {
+                       if (fElement == null)
+                               return null;
+
+                       return findElement(fElement);
+               }
+
+               /**
+                * Clears the stored position
+                */
+               public void clear() {
+                       fLine = -1;
+                       fColumn = -1;
+                       fElement = null;
+                       fElementLine = -1;
+               }
+
+               /**
+                * Does the given Java element contain the given offset?
+                * 
+                * @param element
+                *            Java element
+                * @param offset
+                *            Offset
+                * @return <code>true</code> iff the Java element contains the offset
+                */
+               private boolean containsOffset(IJavaElement element, int offset) {
+                       int elementOffset = getOffset(element);
+                       int elementLength = getLength(element);
+                       return (elementOffset > -1 && elementLength > -1) ? (offset >= elementOffset && offset < elementOffset
+                                       + elementLength)
+                                       : false;
+               }
+
+               /**
+                * Returns the offset of the given Java element.
+                * 
+                * @param element
+                *            Java element
+                * @return Offset of the given Java element
+                */
+               private int getOffset(IJavaElement element) {
+                       if (element instanceof ISourceReference) {
+                               ISourceReference sr = (ISourceReference) element;
+                               try {
+                                       ISourceRange srcRange = sr.getSourceRange();
+                                       if (srcRange != null)
+                                               return srcRange.getOffset();
+                               } catch (JavaModelException e) {
+                               }
+                       }
+                       return -1;
+               }
+
+               /**
+                * Returns the length of the given Java element.
+                * 
+                * @param element
+                *            Java element
+                * @return Length of the given Java element
+                */
+               private int getLength(IJavaElement element) {
+                       if (element instanceof ISourceReference) {
+                               ISourceReference sr = (ISourceReference) element;
+                               try {
+                                       ISourceRange srcRange = sr.getSourceRange();
+                                       if (srcRange != null)
+                                               return srcRange.getLength();
+                               } catch (JavaModelException e) {
+                               }
+                       }
+                       return -1;
+               }
+
+               /**
+                * Returns the updated java element for the old java element.
+                * 
+                * @param element
+                *            Old Java element
+                * @return Updated Java element
+                */
+               private IJavaElement findElement(IJavaElement element) {
+
+                       if (element == null)
+                               return null;
+
+                       IWorkingCopyManager manager = WebUI.getDefault()
+                                       .getWorkingCopyManager();
+                       ICompilationUnit unit = manager.getWorkingCopy(getEditorInput());
+
+                       if (unit != null) {
+                               try {
+
+                                       synchronized (unit) {
+                                               // unit.reconcile(ICompilationUnit.NO_AST, false, null,
+                                               // null);
+                                               unit.reconcile();
+                                       }
+                                       IJavaElement[] findings = unit.findElements(element);
+                                       if (findings != null && findings.length > 0)
+                                               return findings[0];
+
+                               } catch (JavaModelException x) {
+                                       PHPeclipsePlugin.log(x.getStatus());
+                                       // nothing found, be tolerant and go on
+                               }
+                       }
+
+                       return null;
+               }
+
+       }
+
+       static class TabConverter implements ITextConverter {
+               private int fTabRatio;
+
+               private ILineTracker fLineTracker;
+
+               public TabConverter() {
+               }
+
+               public void setNumberOfSpacesPerTab(int ratio) {
+                       fTabRatio = ratio;
+               }
+
+               public void setLineTracker(ILineTracker lineTracker) {
+                       fLineTracker = lineTracker;
+               }
+
+               private int insertTabString(StringBuffer buffer, int offsetInLine) {
+                       if (fTabRatio == 0)
+                               return 0;
+                       int remainder = offsetInLine % fTabRatio;
+                       remainder = fTabRatio - remainder;
+                       for (int i = 0; i < remainder; i++)
+                               buffer.append(' ');
+                       return remainder;
+               }
+
+               public void customizeDocumentCommand(IDocument document,
+                               DocumentCommand command) {
+                       String text = command.text;
+                       if (text == null)
+                               return;
+                       int index = text.indexOf('\t');
+                       if (index > -1) {
+                               StringBuffer buffer = new StringBuffer();
+                               fLineTracker.set(command.text);
+                               int lines = fLineTracker.getNumberOfLines();
+                               try {
+                                       for (int i = 0; i < lines; i++) {
+                                               int offset = fLineTracker.getLineOffset(i);
+                                               int endOffset = offset + fLineTracker.getLineLength(i);
+                                               String line = text.substring(offset, endOffset);
+                                               int position = 0;
+                                               if (i == 0) {
+                                                       IRegion firstLine = document
+                                                                       .getLineInformationOfOffset(command.offset);
+                                                       position = command.offset - firstLine.getOffset();
+                                               }
+                                               int length = line.length();
+                                               for (int j = 0; j < length; j++) {
+                                                       char c = line.charAt(j);
+                                                       if (c == '\t') {
+                                                               position += insertTabString(buffer, position);
+                                                       } else {
+                                                               buffer.append(c);
+                                                               ++position;
+                                                       }
+                                               }
+                                       }
+                                       command.text = buffer.toString();
+                               } catch (BadLocationException x) {
+                               }
+                       }
+               }
+       };
+
+       private static class ExitPolicy implements LinkedPositionUI.ExitPolicy {
+               final char fExitCharacter;
+
+               public ExitPolicy(char exitCharacter) {
+                       fExitCharacter = exitCharacter;
+               }
+
+               /*
+                * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitPolicy#doExit(org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionManager,
+                *      org.eclipse.swt.events.VerifyEvent, int, int)
+                */
+               public ExitFlags doExit(LinkedPositionManager manager,
+                               VerifyEvent event, int offset, int length) {
+                       if (event.character == fExitCharacter) {
+                               if (manager.anyPositionIncludes(offset, length))
+                                       return new ExitFlags(LinkedPositionUI.COMMIT
+                                                       | LinkedPositionUI.UPDATE_CARET, false);
+                               else
+                                       return new ExitFlags(LinkedPositionUI.COMMIT, true);
+                       }
+                       // Fix for #1380415 (toshihiro) start 
+                   switch (event.keyCode) {
+                   case SWT.ARROW_UP:
+                   case SWT.ARROW_DOWN:
+                     return new ExitFlags(LinkedPositionUI.COMMIT, true);
+                   case SWT.ARROW_LEFT:
+                   case SWT.ARROW_RIGHT:
+                      if (!manager.anyPositionIncludes(offset, length))
+                        return new ExitFlags(LinkedPositionUI.COMMIT, true);
+                      break;
+                   }
+                   // #1380415 end 
+                       switch (event.character) {
+                       case '\b':
+                               if (manager.getFirstPosition().length == 0)
+                                       return new ExitFlags(0, false);
+                               else
+                                       return null;
+                       case '\n':
+                       case '\r':
+                               return new ExitFlags(LinkedPositionUI.COMMIT, true);
+                       default:
+                               return null;
+                       }
+               }
+       }
+
+       private static class BracketLevel {
+               int fOffset;
+
+               int fLength;
+
+               LinkedPositionManager fManager;
+
+               LinkedPositionUI fEditor;
+       };
+
+       private class BracketInserter implements VerifyKeyListener,
+                       LinkedPositionUI.ExitListener {
+               private boolean fCloseBracketsPHP = true;
+
+               private boolean fCloseStringsPHPDQ = true;
+
+               private boolean fCloseStringsPHPSQ = true;
+
+               private int fOffset;
+
+               private int fLength;
+
+               public void setCloseBracketsPHPEnabled(boolean enabled) {
+                       fCloseBracketsPHP = enabled;
+               }
+
+               public void setCloseStringsPHPDQEnabled(boolean enabled) {
+                       fCloseStringsPHPDQ = enabled;
+               }
+
+               public void setCloseStringsPHPSQEnabled(boolean enabled) {
+                       fCloseStringsPHPSQ = enabled;
+               }
+
+               private boolean hasIdentifierToTheRight(IDocument document, int offset) {
+                       try {
+                               int end = offset;
+                               IRegion endLine = document.getLineInformationOfOffset(end);
+                               int maxEnd = endLine.getOffset() + endLine.getLength();
+                               while (end != maxEnd
+                                               && Character.isWhitespace(document.getChar(end)))
+                                       ++end;
+                               return end != maxEnd
+                                               && Scanner.isPHPIdentifierPart(document.getChar(end));
+                       } catch (BadLocationException e) {
+                               // be conservative
+                               return true;
+                       }
+               }
+
+               private boolean hasIdentifierToTheLeft(IDocument document, int offset) {
+                       try {
+                               int start = offset;
+                               IRegion startLine = document.getLineInformationOfOffset(start);
+                               int minStart = startLine.getOffset();
+                               while (start != minStart
+                                               && Character.isWhitespace(document.getChar(start - 1)))
+                                       --start;
+                               return start != minStart
+                                               && Scanner.isPHPIdentifierPart(document
+                                                               .getChar(start - 1));
+                       } catch (BadLocationException e) {
+                               return true;
+                       }
+               }
+
+               private boolean hasCharacterToTheLeft(IDocument document, int offset,
+                               char character) {
+                       try {
+                               int start = offset;
+                               IRegion startLine = document.getLineInformationOfOffset(start);
+                               int minStart = startLine.getOffset();
+                               while (start != minStart
+                                               && Character.isWhitespace(document.getChar(start - 1)))
+                                       --start;
+                               return start != minStart
+                                               && document.getChar(start - 1) == character;
+                       } catch (BadLocationException e) {
+                               return false;
+                       }
+               }
+
+               private boolean hasCharacterToTheRight(IDocument document, int offset,
+                               char character) {
+                       try {
+                               int end = offset;
+                               IRegion endLine = document.getLineInformationOfOffset(end);
+                               int maxEnd = endLine.getOffset() + endLine.getLength();
+                               while (end != maxEnd
+                                               && Character.isWhitespace(document.getChar(end)))
+                                       ++end;
+                               return end != maxEnd && document.getChar(end) == character;
+                       } catch (BadLocationException e) {
+                               // be conservative
+                               return true;
+                       }
+               }
+
+               /*
+                * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
+                */
+               public void verifyKey(VerifyEvent event) {
+                       if (!event.doit)
+                               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 {
+                               ITypedRegion partition = document.getPartition(offset);
+                               String type = partition.getType();
+                               if (type.equals(IPHPPartitions.PHP_PARTITIONING)
+                                               || type.equals(IDocument.DEFAULT_CONTENT_TYPE)) {
+                                       // you will get IDocument.DEFAULT_CONTENT_TYPE for both PHP
+                                       // and HTML area
+                                       switch (event.character) {
+                                       case '(':
+                                               if (hasCharacterToTheRight(document, offset + length,
+                                                               '('))
+                                                       return;
+                                               // fall through
+                                       case '[':
+                                               if (!fCloseBracketsPHP)
+                                                       return;
+                                               if (hasIdentifierToTheRight(document, offset + length))
+                                                       return;
+                                               // fall through
+                                       case '{':
+                                               if (!fCloseBracketsPHP)
+                                                       return;
+                                               if (hasIdentifierToTheRight(document, offset + length))
+                                                       return;
+                                               // fall through
+                                       case '"':
+                                               if (event.character == '"') {
+                                                       if (!fCloseStringsPHPDQ)
+                                                               return;
+                                                       // changed for statements like echo "" print ""
+                                                       // if (hasIdentifierToTheLeft(document, offset)
+                                                       // ||
+                                                       // hasIdentifierToTheRight(document, offset +
+                                                       // length))
+                                                       if (hasIdentifierToTheRight(document, offset
+                                                                       + length))
+                                                               return;
+                                               }
+                                               // ITypedRegion partition=
+                                               // document.getPartition(offset);
+                                               // if (!
+                                               // IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())
+                                               // &&
+                                               // (partition.getOffset() != offset))
+                                               // return;
+                                               final char characterDQ = event.character;
+                                               final char closingCharacterDQ = getPeerCharacter(characterDQ);
+                                               final StringBuffer bufferDQ = new StringBuffer();
+                                               bufferDQ.append(characterDQ);
+                                               bufferDQ.append(closingCharacterDQ);
+                                               document.replace(offset, length, bufferDQ.toString());
+                                               LinkedPositionManager managerDQ = new LinkedPositionManager(
+                                                               document);
+                                               managerDQ.addPosition(offset + 1, 0);
+                                               fOffset = offset;
+                                               fLength = 2;
+                                               LinkedPositionUI editorDQ = new LinkedPositionUI(
+                                                               sourceViewer, managerDQ);
+                                               editorDQ.setCancelListener(this);
+                                               editorDQ.setExitPolicy(new ExitPolicy(
+                                                               closingCharacterDQ));
+                                               editorDQ.setFinalCaretOffset(offset + 2);
+                                               editorDQ.enter();
+                                               IRegion newSelectionDQ = editorDQ.getSelectedRegion();
+                                               sourceViewer.setSelectedRange(newSelectionDQ
+                                                               .getOffset(), newSelectionDQ.getLength());
+                                               event.doit = false;
+                                               break;
+                                       case '\'':
+                                               if (event.character == '\'') {
+                                                       if (!fCloseStringsPHPSQ)
+                                                               return;
+                                                       // changed for statements like echo "" print ""
+                                                       // if (hasIdentifierToTheLeft(document, offset)
+                                                       // ||
+                                                       // hasIdentifierToTheRight(document, offset +
+                                                       // length))
+                                                       if (hasIdentifierToTheRight(document, offset
+                                                                       + length))
+                                                               return;
+                                               }
+                                               // ITypedRegion partition=
+                                               // document.getPartition(offset);
+                                               // if (!
+                                               // IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())
+                                               // &&
+                                               // (partition.getOffset() != offset))
+                                               // return;
+                                               final char characterSQ = event.character;
+                                               final char closingCharacterSQ = getPeerCharacter(characterSQ);
+                                               final StringBuffer bufferSQ = new StringBuffer();
+                                               bufferSQ.append(characterSQ);
+                                               bufferSQ.append(closingCharacterSQ);
+                                               document.replace(offset, length, bufferSQ.toString());
+                                               LinkedPositionManager managerSQ = new LinkedPositionManager(
+                                                               document);
+                                               managerSQ.addPosition(offset + 1, 0);
+                                               fOffset = offset;
+                                               fLength = 2;
+                                               LinkedPositionUI editorSQ = new LinkedPositionUI(
+                                                               sourceViewer, managerSQ);
+                                               editorSQ.setCancelListener(this);
+                                               editorSQ.setExitPolicy(new ExitPolicy(
+                                                               closingCharacterSQ));
+                                               editorSQ.setFinalCaretOffset(offset + 2);
+                                               editorSQ.enter();
+                                               IRegion newSelectionSQ = editorSQ.getSelectedRegion();
+                                               sourceViewer.setSelectedRange(newSelectionSQ
+                                                               .getOffset(), newSelectionSQ.getLength());
+                                               event.doit = false;
+                                       case '\r': { // insert linebreaks and new closing brace
+                                                                       // after brace and return
+                                               if (!fCloseBracketsPHP) {
+                                                       return;
+                                               }
+                                               if (hasCharacterToTheLeft(document, offset, '{')
+                                                               && hasCharacterToTheRight(document, offset, '}')) {
+                                                       String lineDelimiter = StubUtility
+                                                                       .getLineDelimiterFor(document);
+                                                       int caretPos = sourceViewer.getTextWidget()
+                                                                       .getCaretOffset();
+                                                       final StringBuffer buffer = new StringBuffer(
+                                                                       lineDelimiter);
+                                                       // get indentation
+                                                       IRegion line = document
+                                                                       .getLineInformationOfOffset(offset);
+                                                       String currentLine = document.get(line.getOffset(),
+                                                                       line.getLength());
+                                                       int index = 0;
+                                                       int max = currentLine.length();
+                                                       StringBuffer indent = new StringBuffer();
+                                                       while (index < max
+                                                                       && Character.isWhitespace(currentLine
+                                                                                       .charAt(index))) {
+                                                               indent.append(currentLine.charAt(index));
+                                                               index++;
+                                                       }
+                                                       buffer.append(indent);
+                                                       JavaHeuristicScanner scanner = new JavaHeuristicScanner(
+                                                                       document);
+                                                       JavaIndenter indenter = new JavaIndenter(document,
+                                                                       scanner);
+                                                       buffer.append(indenter.createIndent(1));
+                                                       int cursorPos = buffer.length();
+                                                       buffer.append(lineDelimiter);
+                                                       buffer.append(indent);
+                                                       document.replace(offset, length, buffer.toString());
+                                                       sourceViewer.getTextWidget().setCaretOffset(
+                                                                       caretPos + cursorPos);
+                                                       event.doit = false;
+                                               }
+                                       }
+                                       }
+                               }
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               /*
+                * @see org.phpeclipse.phpdt.internal.ui.text.link.LinkedPositionUI.ExitListener#exit(boolean)
+                */
+               public void exit(boolean accept) {
+                       if (accept)
+                               return;
+                       // remove brackets
+                       try {
+                               final ISourceViewer sourceViewer = getSourceViewer();
+                               IDocument document = sourceViewer.getDocument();
+                               document.replace(fOffset, fLength, null);
+                       } catch (BadLocationException e) {
+                       }
+               }
+       }
+
+       /** The editor's save policy */
+       protected ISavePolicy fSavePolicy;
+
+       /**
+        * Listener to annotation model changes that updates the error tick in the
+        * tab image
+        */
+       private JavaEditorErrorTickUpdater fJavaEditorErrorTickUpdater;
+
+       /** The editor's paint manager */
+       // private PaintManager fPaintManager;
+       /** The editor's bracket painter */
+       // private BracketPainter fBracketPainter;
+       /** The editor's bracket matcher */
+       private PHPPairMatcher fBracketMatcher;
+
+       /** The editor's line painter */
+       // private LinePainter fLinePainter;
+       /** The editor's print margin ruler painter */
+       // private PrintMarginPainter fPrintMarginPainter;
+       /** The editor's problem painter */
+       // private ProblemPainter fProblemPainter;
+       /** The editor's tab converter */
+       private TabConverter fTabConverter;
+
+       /** History for structure select action */
+       // private SelectionHistory fSelectionHistory;
+       /** The preference property change listener for php core. */
+       // private IPropertyChangeListener fPropertyChangeListener = new
+       // PropertyChangeListener();
+       /** The remembered java element */
+       private IJavaElement fRememberedElement;
+
+       /**
+        * The remembered selection.
+        * 
+        * @since 3.0
+        */
+       private RememberedSelection fRememberedSelection = new RememberedSelection();
+
+       /** The remembered php element offset */
+       private int fRememberedElementOffset;
+
+       /** The bracket inserter. */
+       private BracketInserter fBracketInserter = new BracketInserter();
+
+       /** The standard action groups added to the menu */
+       private GenerateActionGroup fGenerateActionGroup;
+
+       private CompositeActionGroup fContextMenuGroup;
+
+       // private class PropertyChangeListener implements IPropertyChangeListener {
+       // /*
+       // * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+       // */
+       // public void
+       // propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent
+       // event) {
+       // handlePreferencePropertyChanged(event);
+       // }
+       // }
+       /* Preference key for code formatter tab size */
+       private final static String CODE_FORMATTER_TAB_SIZE = JavaCore.FORMATTER_TAB_SIZE;
+
+       /** Preference key for matching brackets */
+       // private final static String MATCHING_BRACKETS =
+       // PreferenceConstants.EDITOR_MATCHING_BRACKETS;
+       /** Preference key for matching brackets color */
+       // private final static String MATCHING_BRACKETS_COLOR =
+       // PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
+       /** Preference key for highlighting current line */
+       // private final static String CURRENT_LINE =
+       // PreferenceConstants.EDITOR_CURRENT_LINE;
+       /** Preference key for highlight color of current line */
+       // private final static String CURRENT_LINE_COLOR =
+       // PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
+       /** Preference key for showing print marging ruler */
+       // private final static String PRINT_MARGIN =
+       // PreferenceConstants.EDITOR_PRINT_MARGIN;
+       /** Preference key for print margin ruler color */
+       // private final static String PRINT_MARGIN_COLOR =
+       // PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
+       /** Preference key for print margin ruler column */
+       // private final static String PRINT_MARGIN_COLUMN =
+       // PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
+       /** Preference key for inserting spaces rather than tabs */
+       private final static String SPACES_FOR_TABS = PreferenceConstants.EDITOR_SPACES_FOR_TABS;
+
+       /** Preference key for error indication */
+       // private final static String ERROR_INDICATION =
+       // PreferenceConstants.EDITOR_PROBLEM_INDICATION;
+       /** Preference key for error color */
+       // private final static String ERROR_INDICATION_COLOR =
+       // PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
+       /** Preference key for warning indication */
+       // private final static String WARNING_INDICATION =
+       // PreferenceConstants.EDITOR_WARNING_INDICATION;
+       /** Preference key for warning color */
+       // private final static String WARNING_INDICATION_COLOR =
+       // PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
+       /** Preference key for task indication */
+       private final static String TASK_INDICATION = PreferenceConstants.EDITOR_TASK_INDICATION;
+
+       /** Preference key for task color */
+       private final static String TASK_INDICATION_COLOR = PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
+
+       /** Preference key for bookmark indication */
+       private final static String BOOKMARK_INDICATION = PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
+
+       /** Preference key for bookmark color */
+       private final static String BOOKMARK_INDICATION_COLOR = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
+
+       /** Preference key for search result indication */
+       private final static String SEARCH_RESULT_INDICATION = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
+
+       /** Preference key for search result color */
+       private final static String SEARCH_RESULT_INDICATION_COLOR = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
+
+       /** Preference key for unknown annotation indication */
+       private final static String UNKNOWN_INDICATION = PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
+
+       /** Preference key for unknown annotation color */
+       private final static String UNKNOWN_INDICATION_COLOR = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
+
+       /** Preference key for linked position color */
+       private final static String LINKED_POSITION_COLOR = PreferenceConstants.EDITOR_LINKED_POSITION_COLOR;
+
+       /** Preference key for shwoing the overview ruler */
+       private final static String OVERVIEW_RULER = PreferenceConstants.EDITOR_OVERVIEW_RULER;
+
+       /** Preference key for error indication in overview ruler */
+       private final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for warning indication in overview ruler */
+       private final static String WARNING_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for task indication in overview ruler */
+       private final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for bookmark indication in overview ruler */
+       private final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for search result indication in overview ruler */
+       private final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for unknown annotation indication in overview ruler */
+       private final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
+
+       /** Preference key for automatically closing double quoted strings */
+       private final static String CLOSE_STRINGS_DQ_PHP = PreferenceConstants.EDITOR_CLOSE_STRINGS_DQ_PHP;
+
+       /** Preference key for automatically closing single quoted strings */
+       private final static String CLOSE_STRINGS_SQ_PHP = PreferenceConstants.EDITOR_CLOSE_STRINGS_SQ_PHP;
+
+       /** Preference key for automatically wrapping Java strings */
+       // private final static String WRAP_STRINGS =
+       // PreferenceConstants.EDITOR_WRAP_STRINGS_DQ;
+       /** Preference key for automatically closing brackets and parenthesis */
+       private final static String CLOSE_BRACKETS_PHP = PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP;
+
+       /** Preference key for automatically closing phpdocs and comments */
+       private final static String CLOSE_JAVADOCS = PreferenceConstants.EDITOR_CLOSE_JAVADOCS;
+
+       /** Preference key for automatically adding phpdoc tags */
+       private final static String ADD_JAVADOC_TAGS = PreferenceConstants.EDITOR_ADD_JAVADOC_TAGS;
+
+       /** Preference key for automatically formatting phpdocs */
+       // private final static String FORMAT_JAVADOCS =
+       // PreferenceConstants.EDITOR_FORMAT_JAVADOCS;
+       /** Preference key for automatically closing strings */
+       private final static String CLOSE_STRINGS_HTML = PreferenceConstants.EDITOR_CLOSE_STRINGS_HTML;
+
+       /** Preference key for automatically closing brackets and parenthesis */
+       private final static String CLOSE_BRACKETS_HTML = PreferenceConstants.EDITOR_CLOSE_BRACKETS_HTML;
+
+       /** Preference key for smart paste */
+       private final static String SMART_PASTE = PreferenceConstants.EDITOR_SMART_PASTE;
+
+       // private final static class AnnotationInfo {
+       // public String fColorPreference;
+       // public String fOverviewRulerPreference;
+       // public String fEditorPreference;
+       // };
+       // private final static Map ANNOTATION_MAP;
+       // static {
+       //
+       // AnnotationInfo info;
+       // ANNOTATION_MAP = new HashMap();
+       //
+       // info = new AnnotationInfo();
+       // info.fColorPreference = TASK_INDICATION_COLOR;
+       // info.fOverviewRulerPreference = TASK_INDICATION_IN_OVERVIEW_RULER;
+       // info.fEditorPreference = TASK_INDICATION;
+       // ANNOTATION_MAP.put(AnnotationType.TASK, info);
+       //
+       // info = new AnnotationInfo();
+       // info.fColorPreference = ERROR_INDICATION_COLOR;
+       // info.fOverviewRulerPreference = ERROR_INDICATION_IN_OVERVIEW_RULER;
+       // info.fEditorPreference = ERROR_INDICATION;
+       // ANNOTATION_MAP.put(AnnotationType.ERROR, info);
+       //
+       // info = new AnnotationInfo();
+       // info.fColorPreference = WARNING_INDICATION_COLOR;
+       // info.fOverviewRulerPreference = WARNING_INDICATION_IN_OVERVIEW_RULER;
+       // info.fEditorPreference = WARNING_INDICATION;
+       // ANNOTATION_MAP.put(AnnotationType.WARNING, info);
+       //
+       // info = new AnnotationInfo();
+       // info.fColorPreference = BOOKMARK_INDICATION_COLOR;
+       // info.fOverviewRulerPreference = BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
+       // info.fEditorPreference = BOOKMARK_INDICATION;
+       // ANNOTATION_MAP.put(AnnotationType.BOOKMARK, info);
+       //
+       // info = new AnnotationInfo();
+       // info.fColorPreference = SEARCH_RESULT_INDICATION_COLOR;
+       // info.fOverviewRulerPreference =
+       // SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
+       // info.fEditorPreference = SEARCH_RESULT_INDICATION;
+       // ANNOTATION_MAP.put(AnnotationType.SEARCH, info);
+       //
+       // info = new AnnotationInfo();
+       // info.fColorPreference = UNKNOWN_INDICATION_COLOR;
+       // info.fOverviewRulerPreference = UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
+       // info.fEditorPreference = UNKNOWN_INDICATION;
+       // ANNOTATION_MAP.put(AnnotationType.UNKNOWN, info);
+       // };
+       //
+       // private final static AnnotationType[] ANNOTATION_LAYERS =
+       // new AnnotationType[] {
+       // AnnotationType.UNKNOWN,
+       // AnnotationType.BOOKMARK,
+       // AnnotationType.TASK,
+       // AnnotationType.SEARCH,
+       // AnnotationType.WARNING,
+       // AnnotationType.ERROR };
+       /**
+        * Creates a new php unit editor.
+        */
+
+       /**
+        * Reconciling listeners.
+        * 
+        * @since 3.0
+        */
+       private ListenerList fReconcilingListeners = new ListenerList();
+
+       /**
+        * Mutex for the reconciler. See
+        * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898 for a description of
+        * the problem.
+        * <p>
+        * TODO remove once the underlying problem is solved.
+        * </p>
+        */
+       private final Object fReconcilerLock = new Object();
+
+       public PHPUnitEditor() {
+               super();
+               setDocumentProvider(WebUI.getDefault()
+                               .getCompilationUnitDocumentProvider());
+               setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
+               setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
+               setOutlinerContextMenuId("#PHPOutlinerContext"); //$NON-NLS-1$
+               // don't set help contextId, we install our own help context
+               fSavePolicy = null;
+               fJavaEditorErrorTickUpdater = new JavaEditorErrorTickUpdater(this);
+       }
+
+       /*
+        * @see AbstractTextEditor#createActions()
+        */
+       protected void createActions() {
+               super.createActions();
+               Action action;
+               // Action action= new
+               // TextOperationAction(PHPEditorMessages.getResourceBundle(),
+               // "CorrectionAssistProposal.", this, CORRECTIONASSIST_PROPOSALS);
+               // //$NON-NLS-1$
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.CORRECTION_ASSIST_PROPOSALS);
+               // setAction("CorrectionAssistProposal", action); //$NON-NLS-1$
+               // markAsStateDependentAction("CorrectionAssistProposal", true);
+               // //$NON-NLS-1$
+               // // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.QUICK_FIX_ACTION);
+               action = new ContentAssistAction(PHPEditorMessages.getResourceBundle(),
+                               "ContentAssistProposal.", this); //$NON-NLS-1$
+               action
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+               setAction("ContentAssistProposal", action); //$NON-NLS-1$
+               markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.CONTENT_ASSIST_ACTION);
+               // action = new
+               // TextOperationAction(PHPEditorMessages.getResourceBundle(),
+               // "ContentAssistContextInformation.", this,
+               // ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); //$NON-NLS-1$
+               // action
+               // .setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
+               // setAction("ContentAssistContextInformation", action); //$NON-NLS-1$
+               // markAsStateDependentAction("ContentAssistContextInformation", true);
+               // //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.PARAMETER_HINTS_ACTION);
+               // action= new
+               // TextOperationAction(PHPEditorMessages.getResourceBundle(),
+               // "ContentAssistCompletePrefix.", this, CONTENTASSIST_COMPLETE_PREFIX);
+               // //$NON-NLS-1$
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_COMPLETE_PREFIX);
+               // setAction("ContentAssistCompletePrefix", action); //$NON-NLS-1$
+               // markAsStateDependentAction("ContentAssistCompletePrefix", true);
+               // //$NON-NLS-1$
+               // // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.PARAMETER_HINTS_ACTION);
+               action = new TextOperationAction(PHPEditorMessages.getResourceBundle(),
+                               "Comment.", this, ITextOperationTarget.PREFIX); //$NON-NLS-1$
+               action.setActionDefinitionId(PHPEditorActionDefinitionIds.COMMENT);
+               setAction("Comment", action); //$NON-NLS-1$
+               markAsStateDependentAction("Comment", true); //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.COMMENT_ACTION);
+               action = new TextOperationAction(PHPEditorMessages.getResourceBundle(),
+                               "Uncomment.", this, ITextOperationTarget.STRIP_PREFIX); //$NON-NLS-1$
+               action.setActionDefinitionId(PHPEditorActionDefinitionIds.UNCOMMENT);
+               setAction("Uncomment", action); //$NON-NLS-1$
+               markAsStateDependentAction("Uncomment", true); //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.UNCOMMENT_ACTION);
+
+               action = new ToggleCommentAction(PHPEditorMessages.getResourceBundle(),
+                               "ToggleComment.", this); //$NON-NLS-1$
+               action
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.TOGGLE_COMMENT);
+               setAction("ToggleComment", action); //$NON-NLS-1$
+               markAsStateDependentAction("ToggleComment", true); //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.TOGGLE_COMMENT_ACTION);
+               configureToggleCommentAction();
+
+               action = new TextOperationAction(PHPEditorMessages.getResourceBundle(),
+                               "Format.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
+               action.setActionDefinitionId(PHPEditorActionDefinitionIds.FORMAT);
+               setAction("Format", action); //$NON-NLS-1$
+               markAsStateDependentAction("Format", true); //$NON-NLS-1$
+               markAsSelectionDependentAction("Format", true); //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.FORMAT_ACTION);
+
+               // action = new
+               // AddBlockCommentAction(PHPEditorMessages.getResourceBundle(),
+               // "AddBlockComment.", this); //$NON-NLS-1$
+               // action
+               // .setActionDefinitionId(PHPEditorActionDefinitionIds.ADD_BLOCK_COMMENT);
+               // setAction("AddBlockComment", action); //$NON-NLS-1$
+               // markAsStateDependentAction("AddBlockComment", true); //$NON-NLS-1$
+               // markAsSelectionDependentAction("AddBlockComment", true);
+               // //$NON-NLS-1$
+               // // WorkbenchHelp.setHelp(action,
+               // // IJavaHelpContextIds.ADD_BLOCK_COMMENT_ACTION);
+               // action = new RemoveBlockCommentAction(
+               // PHPEditorMessages.getResourceBundle(), "RemoveBlockComment.", this);
+               // //$NON-NLS-1$
+               // action
+               // .setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_BLOCK_COMMENT);
+               // setAction("RemoveBlockComment", action); //$NON-NLS-1$
+               // markAsStateDependentAction("RemoveBlockComment", true); //$NON-NLS-1$
+               // markAsSelectionDependentAction("RemoveBlockComment", true);
+               // //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.ADD_BLOCK_COMMENT_ACTION);
+               action = new IndentAction(PHPEditorMessages.getResourceBundle(),
+                               "Indent.", this, false); //$NON-NLS-1$
+               action.setActionDefinitionId(PHPEditorActionDefinitionIds.INDENT);
+               setAction("Indent", action); //$NON-NLS-1$
+               markAsStateDependentAction("Indent", true); //$NON-NLS-1$
+               markAsSelectionDependentAction("Indent", true); //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.INDENT_ACTION);
+               //
+               // action= new IndentAction(PHPEditorMessages.getResourceBundle(),
+               // "Indent.", this, true); //$NON-NLS-1$
+               // setAction("IndentOnTab", action); //$NON-NLS-1$
+               // markAsStateDependentAction("IndentOnTab", true); //$NON-NLS-1$
+               // markAsSelectionDependentAction("IndentOnTab", true); //$NON-NLS-1$
+               //
+
+               action = new AddBlockCommentAction(PHPEditorMessages
+                               .getResourceBundle(), "AddBlockComment.", this); //$NON-NLS-1$
+               action
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.ADD_BLOCK_COMMENT);
+               setAction("AddBlockComment", action); //$NON-NLS-1$
+               markAsStateDependentAction("AddBlockComment", true); //$NON-NLS-1$
+               markAsSelectionDependentAction("AddBlockComment", true); //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.ADD_BLOCK_COMMENT_ACTION);
+
+               action = new RemoveBlockCommentAction(PHPEditorMessages
+                               .getResourceBundle(), "RemoveBlockComment.", this); //$NON-NLS-1$
+               action
+                               .setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_BLOCK_COMMENT);
+               setAction("RemoveBlockComment", action); //$NON-NLS-1$
+               markAsStateDependentAction("RemoveBlockComment", true); //$NON-NLS-1$
+               markAsSelectionDependentAction("RemoveBlockComment", true); //$NON-NLS-1$
+               // WorkbenchHelp.setHelp(action,
+               // IJavaHelpContextIds.REMOVE_BLOCK_COMMENT_ACTION);
+
+               // action= new IndentAction(PHPEditorMessages.getResourceBundle(),
+               // "Indent.", this, false); //$NON-NLS-1$
+               // action.setActionDefinitionId(PHPEditorActionDefinitionIds.INDENT);
+               // setAction("Indent", action); //$NON-NLS-1$
+               // markAsStateDependentAction("Indent", true); //$NON-NLS-1$
+               // markAsSelectionDependentAction("Indent", true); //$NON-NLS-1$
+               // // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.INDENT_ACTION);
+               //
+               action = new IndentAction(PHPEditorMessages.getResourceBundle(),
+                               "Indent.", this, true); //$NON-NLS-1$
+               setAction("IndentOnTab", action); //$NON-NLS-1$
+               markAsStateDependentAction("IndentOnTab", true); //$NON-NLS-1$
+               markAsSelectionDependentAction("IndentOnTab", true); //$NON-NLS-1$
+
+               if (getPreferenceStore().getBoolean(
+                               PreferenceConstants.EDITOR_SMART_TAB)) {
+                       // don't replace Shift Right - have to make sure their enablement is
+                       // mutually exclusive
+                       // removeActionActivationCode(ITextEditorActionConstants.SHIFT_RIGHT);
+                       setActionActivationCode("IndentOnTab", '\t', -1, SWT.NONE); //$NON-NLS-1$
+               }
+               fGenerateActionGroup = new GenerateActionGroup(this,
+                               ITextEditorActionConstants.GROUP_EDIT);
+               // ActionGroup rg= new RefactorActionGroup(this,
+               // ITextEditorActionConstants.GROUP_EDIT);
+
+               // fActionGroups.addGroup(rg);
+               fActionGroups.addGroup(fGenerateActionGroup);
+
+               // We have to keep the context menu group separate to have better
+               // control over positioning
+               fContextMenuGroup = new CompositeActionGroup(
+                               new ActionGroup[] { fGenerateActionGroup
+                               // rg,
+                               // new LocalHistoryActionGroup(this,
+                               // ITextEditorActionConstants.GROUP_EDIT)
+                               });
+
+       }
+
+       /*
+        * @see JavaEditor#getElementAt(int)
+        */
+       protected IJavaElement getElementAt(int offset) {
+               return getElementAt(offset, true);
+       }
+
+       /**
+        * Returns the most narrow element including the given offset. If
+        * <code>reconcile</code> is <code>true</code> the editor's input
+        * element is reconciled in advance. If it is <code>false</code> this
+        * method only returns a result if the editor's input element does not need
+        * to be reconciled.
+        * 
+        * @param offset
+        *            the offset included by the retrieved element
+        * @param reconcile
+        *            <code>true</code> if working copy should be reconciled
+        */
+       protected IJavaElement getElementAt(int offset, boolean reconcile) {
+               IWorkingCopyManager manager = WebUI.getDefault()
+                               .getWorkingCopyManager();
+               ICompilationUnit unit = manager.getWorkingCopy(getEditorInput());
+               if (unit != null) {
+                       try {
+                               if (reconcile) {
+                                       synchronized (unit) {
+                                               unit.reconcile();
+                                       }
+                                       return unit.getElementAt(offset);
+                               } else if (unit.isConsistent())
+                                       return unit.getElementAt(offset);
+                       } catch (JavaModelException x) {
+                               PHPeclipsePlugin.log(x.getStatus());
+                               // nothing found, be tolerant and go on
+                       }
+               }
+               return null;
+       }
+
+       /*
+        * @see JavaEditor#getCorrespondingElement(IJavaElement)
+        */
+       protected IJavaElement getCorrespondingElement(IJavaElement element) {
+               try {
+                       return EditorUtility.getWorkingCopy(element, true);
+               } catch (JavaModelException x) {
+                       PHPeclipsePlugin.log(x.getStatus());
+                       // nothing found, be tolerant and go on
+               }
+               return null;
+       }
+
+       public void createPartControl(Composite parent) {
+               super.createPartControl(parent);
+               // fPaintManager = new PaintManager(getSourceViewer());
+               LinePainter linePainter;
+               linePainter = new LinePainter(getSourceViewer());
+               linePainter.setHighlightColor(new Color(Display.getCurrent(), 225, 235,
+                               224));
+               // fPaintManager.addPainter(linePainter);
+               // if (isBracketHighlightingEnabled())
+               // startBracketHighlighting();
+               // if (isLineHighlightingEnabled())
+               // startLineHighlighting();
+               // if (isPrintMarginVisible())
+               // showPrintMargin();
+               // Iterator e = ANNOTATION_MAP.keySet().iterator();
+               // while (e.hasNext()) {
+               // AnnotationType type = (AnnotationType) e.next();
+               // if (isAnnotationIndicationEnabled(type))
+               // startAnnotationIndication(type);
+               // }
+               if (isTabConversionEnabled())
+                       startTabConversion();
+               // if (isOverviewRulerVisible())
+               // showOverviewRuler();
+               //
+               // Preferences preferences =
+               // PHPeclipsePlugin.getDefault().getPluginPreferences();
+               // preferences.addPropertyChangeListener(fPropertyChangeListener);
+               IPreferenceStore preferenceStore = getPreferenceStore();
+               boolean closeBracketsPHP = preferenceStore
+                               .getBoolean(CLOSE_BRACKETS_PHP);
+               boolean closeStringsPHPDQ = preferenceStore
+                               .getBoolean(CLOSE_STRINGS_DQ_PHP);
+               boolean closeStringsPHPSQ = preferenceStore
+                               .getBoolean(CLOSE_STRINGS_SQ_PHP);
+               fBracketInserter.setCloseBracketsPHPEnabled(closeBracketsPHP);
+               fBracketInserter.setCloseStringsPHPDQEnabled(closeStringsPHPDQ);
+               fBracketInserter.setCloseStringsPHPSQEnabled(closeStringsPHPSQ);
+               ISourceViewer sourceViewer = getSourceViewer();
+               if (sourceViewer instanceof ITextViewerExtension)
+                       ((ITextViewerExtension) sourceViewer)
+                                       .prependVerifyKeyListener(fBracketInserter);
+       }
+
+       private static char getPeerCharacter(char character) {
+               switch (character) {
+               case '(':
+                       return ')';
+               case ')':
+                       return '(';
+               case '[':
+                       return ']';
+               case ']':
+                       return '[';
+               case '"':
+                       return character;
+               case '\'':
+                       return character;
+               case '{':
+                       return '}';
+               default:
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       // private void startBracketHighlighting() {
+       // if (fBracketPainter == null) {
+       // ISourceViewer sourceViewer = getSourceViewer();
+       // fBracketPainter = new BracketPainter(sourceViewer);
+       // fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
+       // // fPaintManager.addPainter(fBracketPainter);
+       // }
+       // }
+       //
+       // private void stopBracketHighlighting() {
+       // if (fBracketPainter != null) {
+       // // fPaintManager.removePainter(fBracketPainter);
+       // fBracketPainter.deactivate(true);
+       // fBracketPainter.dispose();
+       // fBracketPainter = null;
+       // }
+       // }
+
+       // private boolean isBracketHighlightingEnabled() {
+       // IPreferenceStore store = getPreferenceStore();
+       // return store.getBoolean(MATCHING_BRACKETS);
+       // }
+
+       // private void startLineHighlighting() {
+       // if (fLinePainter == null) {
+       // ISourceViewer sourceViewer = getSourceViewer();
+       // fLinePainter = new LinePainter(sourceViewer);
+       // fLinePainter.setHighlightColor(getColor(CURRENT_LINE_COLOR));
+       // // fPaintManager.addPainter(fLinePainter);
+       // }
+       // }
+
+       // private void stopLineHighlighting() {
+       // if (fLinePainter != null) {
+       // // fPaintManager.removePainter(fLinePainter);
+       // fLinePainter.deactivate(true);
+       // fLinePainter.dispose();
+       // fLinePainter = null;
+       // }
+       // }
+
+       // private boolean isLineHighlightingEnabled() {
+       // IPreferenceStore store = getPreferenceStore();
+       // return store.getBoolean(CURRENT_LINE);
+       // }
+
+       // private void showPrintMargin() {
+       // if (fPrintMarginPainter == null) {
+       // fPrintMarginPainter = new PrintMarginPainter(getSourceViewer());
+       // fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
+       // fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
+       // // fPaintManager.addPainter(fPrintMarginPainter);
+       // }
+       // }
+
+       // private void hidePrintMargin() {
+       // if (fPrintMarginPainter != null) {
+       // // fPaintManager.removePainter(fPrintMarginPainter);
+       // fPrintMarginPainter.deactivate(true);
+       // fPrintMarginPainter.dispose();
+       // fPrintMarginPainter = null;
+       // }
+       // }
+
+       // private boolean isPrintMarginVisible() {
+       // IPreferenceStore store = getPreferenceStore();
+       // return store.getBoolean(PRINT_MARGIN);
+       // }
+
+       private int getTabSize() {
+               Preferences preferences = PHPeclipsePlugin.getDefault()
+                               .getPluginPreferences();
+               return preferences.getInt(CODE_FORMATTER_TAB_SIZE);
+       }
+
+       private boolean isTabConversionEnabled() {
+               IPreferenceStore store = getPreferenceStore();
+               return store.getBoolean(SPACES_FOR_TABS);
+       }
+
+       private Color getColor(String key) {
+               RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
+               return getColor(rgb);
+       }
+
+       private Color getColor(RGB rgb) {
+               JavaTextTools textTools = WebUI.getDefault()
+                               .getJavaTextTools();
+               return textTools.getColorManager().getColor(rgb);
+       }
+
+       // private Color getColor(AnnotationType annotationType) {
+       // AnnotationInfo info = (AnnotationInfo)
+       // ANNOTATION_MAP.get(annotationType);
+       // if (info != null)
+       // return getColor(info.fColorPreference);
+       // return null;
+       // }
+       public void dispose() {
+               ISourceViewer sourceViewer = getSourceViewer();
+               if (sourceViewer instanceof ITextViewerExtension)
+                       ((ITextViewerExtension) sourceViewer)
+                                       .removeVerifyKeyListener(fBracketInserter);
+               // if (fPropertyChangeListener != null) {
+               // Preferences preferences =
+               // PHPeclipsePlugin.getDefault().getPluginPreferences();
+               // preferences.removePropertyChangeListener(fPropertyChangeListener);
+               // fPropertyChangeListener = null;
+               // }
+               if (fJavaEditorErrorTickUpdater != null) {
+                       fJavaEditorErrorTickUpdater.dispose();
+                       fJavaEditorErrorTickUpdater = null;
+               }
+               // if (fSelectionHistory != null)
+               // fSelectionHistory.dispose();
+               // if (fPaintManager != null) {
+               // fPaintManager.dispose();
+               // fPaintManager = null;
+               // }
+               if (fActionGroups != null) {
+                       fActionGroups.dispose();
+                       fActionGroups = null;
+               }
+               super.dispose();
+       }
+
+       // protected AnnotationType getAnnotationType(String preferenceKey) {
+       // Iterator e = ANNOTATION_MAP.keySet().iterator();
+       // while (e.hasNext()) {
+       // AnnotationType type = (AnnotationType) e.next();
+       // AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(type);
+       // if (info != null) {
+       // if (preferenceKey.equals(info.fColorPreference)
+       // || preferenceKey.equals(info.fEditorPreference)
+       // || preferenceKey.equals(info.fOverviewRulerPreference))
+       // return type;
+       // }
+       // }
+       // return null;
+       // }
+       /*
+        * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
+        */
+       protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+               try {
+                       AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+                       if (asv != null) {
+                               String p = event.getProperty();
+                               if (CLOSE_BRACKETS_PHP.equals(p)) {
+                                       fBracketInserter
+                                                       .setCloseBracketsPHPEnabled(getPreferenceStore()
+                                                                       .getBoolean(p));
+                                       return;
+                               }
+                               if (CLOSE_STRINGS_DQ_PHP.equals(p)) {
+                                       fBracketInserter
+                                                       .setCloseStringsPHPDQEnabled(getPreferenceStore()
+                                                                       .getBoolean(p));
+                                       return;
+                               }
+                               if (CLOSE_STRINGS_SQ_PHP.equals(p)) {
+                                       fBracketInserter
+                                                       .setCloseStringsPHPSQEnabled(getPreferenceStore()
+                                                                       .getBoolean(p));
+                                       return;
+                               }
+                               if (SPACES_FOR_TABS.equals(p)) {
+                                       if (isTabConversionEnabled())
+                                               startTabConversion();
+                                       else
+                                               stopTabConversion();
+                                       return;
+                               }
+                               // if (MATCHING_BRACKETS.equals(p)) {
+                               // if (isBracketHighlightingEnabled())
+                               // startBracketHighlighting();
+                               // else
+                               // stopBracketHighlighting();
+                               // return;
+                               // }
+                               // if (MATCHING_BRACKETS_COLOR.equals(p)) {
+                               // if (fBracketPainter != null)
+                               // fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
+                               // return;
+                               // }
+                               // if (CURRENT_LINE.equals(p)) {
+                               // if (isLineHighlightingEnabled())
+                               // startLineHighlighting();
+                               // else
+                               // stopLineHighlighting();
+                               // return;
+                               // }
+                               // if (CURRENT_LINE_COLOR.equals(p)) {
+                               // if (fLinePainter != null) {
+                               // stopLineHighlighting();
+                               // startLineHighlighting();
+                               // }
+                               // return;
+                               // }
+                               // if (PRINT_MARGIN.equals(p)) {
+                               // if (isPrintMarginVisible())
+                               // showPrintMargin();
+                               // else
+                               // hidePrintMargin();
+                               // return;
+                               // }
+                               // if (PRINT_MARGIN_COLOR.equals(p)) {
+                               // if (fPrintMarginPainter != null)
+                               // fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
+                               // return;
+                               // }
+                               // if (PRINT_MARGIN_COLUMN.equals(p)) {
+                               // if (fPrintMarginPainter != null)
+                               // fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
+                               // return;
+                               // }
+                               // if (OVERVIEW_RULER.equals(p)) {
+                               // if (isOverviewRulerVisible())
+                               // showOverviewRuler();
+                               // else
+                               // hideOverviewRuler();
+                               // return;
+                               // }
+                               // AnnotationType type = getAnnotationType(p);
+                               // if (type != null) {
+                               //
+                               // AnnotationInfo info = (AnnotationInfo)
+                               // ANNOTATION_MAP.get(type);
+                               // if (info.fColorPreference.equals(p)) {
+                               // Color color = getColor(type);
+                               // if (fProblemPainter != null) {
+                               // fProblemPainter.setColor(type, color);
+                               // fProblemPainter.paint(IPainter.CONFIGURATION);
+                               // }
+                               // setColorInOverviewRuler(type, color);
+                               // return;
+                               // }
+                               //
+                               // if (info.fEditorPreference.equals(p)) {
+                               // if (isAnnotationIndicationEnabled(type))
+                               // startAnnotationIndication(type);
+                               // else
+                               // stopAnnotationIndication(type);
+                               // return;
+                               // }
+                               //
+                               // if (info.fOverviewRulerPreference.equals(p)) {
+                               // if (isAnnotationIndicationInOverviewRulerEnabled(type))
+                               // showAnnotationIndicationInOverviewRuler(type, true);
+                               // else
+                               // showAnnotationIndicationInOverviewRuler(type, false);
+                               // return;
+                               // }
+                               // }
+                               IContentAssistant c = asv.getContentAssistant();
+                               if (c instanceof ContentAssistant)
+                                       ContentAssistPreference.changeConfiguration(
+                                                       (ContentAssistant) c, getPreferenceStore(), event);
+                       }
+               } finally {
+                       super.handlePreferenceStoreChanged(event);
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor#handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
+        */
+       protected void handlePreferencePropertyChanged(
+                       org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+               AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+               if (asv != null) {
+                       String p = event.getProperty();
+                       if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
+                               asv.updateIndentationPrefixes();
+                               if (fTabConverter != null)
+                                       fTabConverter.setNumberOfSpacesPerTab(getTabSize());
+                       }
+               }
+               super.handlePreferencePropertyChanged(event);
+       }
+
+       /**
+        * Handles a property change event describing a change of the php core's
+        * preferences and updates the preference related editor properties.
+        * 
+        * @param event
+        *            the property change event
+        */
+       // protected void
+       // handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent
+       // event) {
+       // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+       // if (asv != null) {
+       // String p = event.getProperty();
+       // if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
+       // asv.updateIndentationPrefixes();
+       // if (fTabConverter != null)
+       // fTabConverter.setNumberOfSpacesPerTab(getTabSize());
+       // }
+       // }
+       // }
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor#createJavaSourceViewer(org.eclipse.swt.widgets.Composite,
+        *      org.eclipse.jface.text.source.IVerticalRuler,
+        *      org.eclipse.jface.text.source.IOverviewRuler, boolean, int)
+        */
+       protected ISourceViewer createJavaSourceViewer(Composite parent,
+                       IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
+                       boolean isOverviewRulerVisible, int styles, IPreferenceStore store) {
+               return new AdaptedSourceViewer(parent, verticalRuler, overviewRuler,
+                               isOverviewRulerVisible, styles, store);
+       }
+
+       // protected ISourceViewer createJavaSourceViewer(Composite parent,
+       // IVerticalRuler ruler, int styles) {
+       // return new AdaptedSourceViewer(parent, ruler, styles);
+       // }
+       private boolean isValidSelection(int offset, int length) {
+               IDocumentProvider provider = getDocumentProvider();
+               if (provider != null) {
+                       IDocument document = provider.getDocument(getEditorInput());
+                       if (document != null) {
+                               int end = offset + length;
+                               int documentLength = document.getLength();
+                               return 0 <= offset && offset <= documentLength && 0 <= end
+                                               && end <= documentLength;
+                       }
+               }
+               return false;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor#getInputElement()
+        */
+       protected IJavaElement getInputJavaElement() {
+               return WebUI.getDefault().getWorkingCopyManager()
+                               .getWorkingCopy(getEditorInput());
+       }
+
+       /*
+        * @see AbstractTextEditor#editorContextMenuAboutToShow(IMenuManager)
+        */
+       public void editorContextMenuAboutToShow(IMenuManager menu) {
+               super.editorContextMenuAboutToShow(menu);
+               ActionContext context = new ActionContext(getSelectionProvider()
+                               .getSelection());
+               fContextMenuGroup.setContext(context);
+               fContextMenuGroup.fillContextMenu(menu);
+               fContextMenuGroup.setContext(null);
+       }
+
+       /*
+        * @see JavaEditor#setOutlinePageInput(JavaOutlinePage, IEditorInput)
+        */
+       protected void setOutlinePageInput(JavaOutlinePage page, IEditorInput input) {
+               if (page != null) {
+                       IWorkingCopyManager manager = WebUI.getDefault()
+                                       .getWorkingCopyManager();
+                       page.setInput(manager.getWorkingCopy(input));
+               }
+       }
+
+       /*
+        * @see AbstractTextEditor#performSaveOperation(WorkspaceModifyOperation,
+        *      IProgressMonitor)
+        */
+       // protected void performSaveOperation(WorkspaceModifyOperation operation,
+       // IProgressMonitor progressMonitor) {
+       // IDocumentProvider p = getDocumentProvider();
+       // if (p instanceof PHPDocumentProvider) {
+       // PHPDocumentProvider cp = (PHPDocumentProvider) p;
+       // cp.setSavePolicy(fSavePolicy);
+       // }
+       //
+       // try {
+       // super.performSaveOperation(operation, progressMonitor);
+       // } finally {
+       // if (p instanceof PHPDocumentProvider) {
+       // PHPDocumentProvider cp = (PHPDocumentProvider) p;
+       // cp.setSavePolicy(null);
+       // }
+       // }
+       // }
+       /*
+        * @see AbstractTextEditor#doSave(IProgressMonitor)
+        */
+       public void doSave(IProgressMonitor progressMonitor) {
+
+               IDocumentProvider p = getDocumentProvider();
+               if (p == null) {
+                       // editor has been closed
+                       return;
+               }
+
+               if (p.isDeleted(getEditorInput())) {
+
+                       if (isSaveAsAllowed()) {
+
+                               /*
+                                * 1GEUSSR: ITPUI:ALL - User should never loose changes made in
+                                * the editors. Changed Behavior to make sure that if called
+                                * inside a regular save (because of deletion of input element)
+                                * there is a way to report back to the caller.
+                                */
+                               performSaveAs(progressMonitor);
+
+                       } else {
+
+                               /*
+                                * 1GF5YOX: ITPJUI:ALL - Save of delete file claims it's still
+                                * there Missing resources.
+                                */
+                               Shell shell = getSite().getShell();
+                               MessageDialog
+                                               .openError(
+                                                               shell,
+                                                               PHPEditorMessages
+                                                                               .getString("PHPUnitEditor.error.saving.title1"), PHPEditorMessages.getString("PHPUnitEditor.error.saving.message1")); //$NON-NLS-1$ //$NON-NLS-2$
+                       }
+
+               } else {
+                       if (getPreferenceStore().getBoolean(
+                                       PreferenceConstants.EDITOR_P_RTRIM_ON_SAVE)) {
+                               RTrimAction trimAction = new RTrimAction();
+                               trimAction.setActiveEditor(null, getSite().getPage()
+                                               .getActiveEditor());
+                               trimAction.run(null);
+                       }
+
+                       setStatusLineErrorMessage(null);
+
+                       updateState(getEditorInput());
+                       validateState(getEditorInput());
+
+                       IWorkingCopyManager manager = WebUI.getDefault()
+                                       .getWorkingCopyManager();
+                       ICompilationUnit unit = manager.getWorkingCopy(getEditorInput());
+
+                       if (unit != null) {
+                               synchronized (unit) {
+                                       performSave(false, progressMonitor);
+                               }
+                       } else
+                               performSave(false, progressMonitor);
+               }
+       }
+
+       public boolean isSaveAsAllowed() {
+               return true;
+       }
+
+       /**
+        * The compilation unit editor implementation of this
+        * <code>AbstractTextEditor</code> method asks the user for the workspace
+        * path of a file resource and saves the document there. See
+        * http://dev.eclipse.org/bugs/show_bug.cgi?id=6295
+        * 
+        * @param progressMonitor
+        *            the progress monitor
+        */
+       protected void performSaveAs(IProgressMonitor progressMonitor) {
+
+               Shell shell = getSite().getShell();
+               IEditorInput input = getEditorInput();
+
+               SaveAsDialog dialog = new SaveAsDialog(shell);
+
+               IFile original = (input instanceof IFileEditorInput) ? ((IFileEditorInput) input)
+                               .getFile()
+                               : null;
+               if (original != null)
+                       dialog.setOriginalFile(original);
+
+               dialog.create();
+
+               IDocumentProvider provider = getDocumentProvider();
+               if (provider == null) {
+                       // editor has been programmatically closed while the dialog was open
+                       return;
+               }
+
+               if (provider.isDeleted(input) && original != null) {
+                       String message = PHPEditorMessages
+                                       .getFormattedString(
+                                                       "CompilationUnitEditor.warning.save.delete", new Object[] { original.getName() }); //$NON-NLS-1$
+                       dialog.setErrorMessage(null);
+                       dialog.setMessage(message, IMessageProvider.WARNING);
+               }
+
+               if (dialog.open() == Window.CANCEL) {
+                       if (progressMonitor != null)
+                               progressMonitor.setCanceled(true);
+                       return;
+               }
+
+               IPath filePath = dialog.getResult();
+               if (filePath == null) {
+                       if (progressMonitor != null)
+                               progressMonitor.setCanceled(true);
+                       return;
+               }
+
+               IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+               IFile file = workspaceRoot.getFile(filePath);
+               final IEditorInput newInput = new FileEditorInput(file);
+
+               boolean success = false;
+               try {
+
+                       provider.aboutToChange(newInput);
+                       getDocumentProvider().saveDocument(progressMonitor, newInput,
+                                       getDocumentProvider().getDocument(getEditorInput()), true);
+                       success = true;
+
+               } catch (CoreException x) {
+                       IStatus status = x.getStatus();
+                       if (status == null || status.getSeverity() != IStatus.CANCEL)
+                               ErrorDialog
+                                               .openError(
+                                                               shell,
+                                                               PHPEditorMessages
+                                                                               .getString("CompilationUnitEditor.error.saving.title2"), PHPEditorMessages.getString("CompilationUnitEditor.error.saving.message2"), x.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$
+               } finally {
+                       provider.changed(newInput);
+                       if (success)
+                               setInput(newInput);
+               }
+
+               if (progressMonitor != null)
+                       progressMonitor.setCanceled(!success);
+       }
+
+       /*
+        * @see AbstractTextEditor#doSetInput(IEditorInput)
+        */
+       protected void doSetInput(IEditorInput input) throws CoreException {
+               super.doSetInput(input);
+               configureTabConverter();
+               configureToggleCommentAction();
+       }
+
+       // /*
+       // * @see
+       // net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor#installOverrideIndicator(boolean)
+       // * @since 3.0
+       // */
+       // protected void installOverrideIndicator(boolean waitForReconcilation) {
+       // IAnnotationModel model=
+       // getDocumentProvider().getAnnotationModel(getEditorInput());
+       // if (!waitForReconcilation)
+       // super.installOverrideIndicator(false);
+       // else {
+       // uninstallOverrideIndicator();
+       // IJavaElement inputElement= getInputJavaElement();
+       // if (model == null || inputElement == null)
+       // return;
+       //
+       // fOverrideIndicatorManager= new OverrideIndicatorManager(model,
+       // inputElement, null);
+       // addReconcileListener(fOverrideIndicatorManager);
+       // }
+       // }
+       //
+       // /*
+       // * @see
+       // net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor#uninstallOverrideIndicator()
+       // * @since 3.0
+       // */
+       // protected void uninstallOverrideIndicator() {
+       // if (fOverrideIndicatorManager != null)
+       // removeReconcileListener(fOverrideIndicatorManager);
+       // super.uninstallOverrideIndicator();
+       // }
+
+       /**
+        * Configures the toggle comment action
+        * 
+        * @since 3.0
+        */
+       private void configureToggleCommentAction() {
+               IAction action = getAction("ToggleComment"); //$NON-NLS-1$
+               if (action instanceof ToggleCommentAction) {
+                       ISourceViewer sourceViewer = getSourceViewer();
+                       SourceViewerConfiguration configuration = getSourceViewerConfiguration();
+                       ((ToggleCommentAction) action).configure(sourceViewer,
+                                       configuration);
+               }
+       }
+
+       // private void configureTabConverter() {
+       // if (fTabConverter != null) {
+       // IDocumentProvider provider = getDocumentProvider();
+       // if (provider instanceof PHPDocumentProvider) {
+       // PHPDocumentProvider cup = (PHPDocumentProvider) provider;
+       // fTabConverter.setLineTracker(cup.createLineTracker(getEditorInput()));
+       // }
+       // }
+       // }
+       private void configureTabConverter() {
+               if (fTabConverter != null) {
+                       IDocumentProvider provider = getDocumentProvider();
+                       if (provider instanceof ICompilationUnitDocumentProvider) {
+                               ICompilationUnitDocumentProvider cup = (ICompilationUnitDocumentProvider) provider;
+                               fTabConverter.setLineTracker(cup
+                                               .createLineTracker(getEditorInput()));
+                       }
+               }
+       }
+
+       private void startTabConversion() {
+               if (fTabConverter == null) {
+                       fTabConverter = new TabConverter();
+                       configureTabConverter();
+                       fTabConverter.setNumberOfSpacesPerTab(getTabSize());
+                       AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+                       asv.addTextConverter(fTabConverter);
+                       // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
+                       asv.updateIndentationPrefixes();
+               }
+       }
+
+       private void stopTabConversion() {
+               if (fTabConverter != null) {
+                       AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+                       asv.removeTextConverter(fTabConverter);
+                       // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
+                       asv.updateIndentationPrefixes();
+                       fTabConverter = null;
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#performSave(boolean,
+        *      org.eclipse.core.runtime.IProgressMonitor)
+        */
+       protected void performSave(boolean overwrite,
+                       IProgressMonitor progressMonitor) {
+               // IDocumentProvider p = getDocumentProvider();
+               // if (p instanceof PHPDocumentProvider) {
+               // PHPDocumentProvider cp = (PHPDocumentProvider) p;
+               // cp.setSavePolicy(fSavePolicy);
+               // }
+               // try {
+               // super.performSave(overwrite, progressMonitor);
+               // } finally {
+               // if (p instanceof PHPDocumentProvider) {
+               // PHPDocumentProvider cp = (PHPDocumentProvider) p;
+               // cp.setSavePolicy(null);
+               // }
+               // }
+
+               IDocumentProvider p = getDocumentProvider();
+               if (p instanceof ICompilationUnitDocumentProvider) {
+                       ICompilationUnitDocumentProvider cp = (ICompilationUnitDocumentProvider) p;
+                       cp.setSavePolicy(fSavePolicy);
+               }
+               try {
+                       super.performSave(overwrite, progressMonitor);
+               } finally {
+                       if (p instanceof ICompilationUnitDocumentProvider) {
+                               ICompilationUnitDocumentProvider cp = (ICompilationUnitDocumentProvider) p;
+                               cp.setSavePolicy(null);
+                       }
+               }
+       }
+
+       /*
+        * @see AbstractTextEditor#doSaveAs
+        */
+       public void doSaveAs() {
+               if (askIfNonWorkbenchEncodingIsOk()) {
+                       super.doSaveAs();
+               }
+       }
+
+       /**
+        * Asks the user if it is ok to store in non-workbench encoding.
+        * 
+        * @return <true>if the user wants to continue
+        */
+       private boolean askIfNonWorkbenchEncodingIsOk() {
+               IDocumentProvider provider = getDocumentProvider();
+               if (provider instanceof IStorageDocumentProvider) {
+                       IEditorInput input = getEditorInput();
+                       IStorageDocumentProvider storageProvider = (IStorageDocumentProvider) provider;
+                       String encoding = storageProvider.getEncoding(input);
+                       String defaultEncoding = storageProvider.getDefaultEncoding();
+                       if (encoding != null && !encoding.equals(defaultEncoding)) {
+                               Shell shell = getSite().getShell();
+                               String title = PHPEditorMessages
+                                               .getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.title"); //$NON-NLS-1$
+                               String msg;
+                               if (input != null)
+                                       msg = MessageFormat
+                                                       .format(
+                                                                       PHPEditorMessages
+                                                                                       .getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.message1"),
+                                                                       new String[] { input.getName(), encoding }); //$NON-NLS-1$
+                               else
+                                       msg = MessageFormat
+                                                       .format(
+                                                                       PHPEditorMessages
+                                                                                       .getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.message2"),
+                                                                       new String[] { encoding }); //$NON-NLS-1$
+                               return MessageDialog.openQuestion(shell, title, msg);
+                       }
+               }
+               return true;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.java.IJavaReconcilingListener#aboutToBeReconciled()
+        * @since 3.0
+        */
+       public void aboutToBeReconciled() {
+
+               // Notify AST provider
+               // PHPeclipsePlugin.getDefault().getASTProvider().aboutToBeReconciled(getInputJavaElement());
+
+               // Notify listeners
+               Object[] listeners = fReconcilingListeners.getListeners();
+               for (int i = 0, length = listeners.length; i < length; ++i)
+                       ((IJavaReconcilingListener) listeners[i]).aboutToBeReconciled();
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.text.java.IJavaReconcilingListener#reconciled(CompilationUnit,
+        *      boolean, IProgressMonitor)
+        * @since 3.0
+        */
+       public void reconciled(CompilationUnit ast, boolean forced,
+                       IProgressMonitor progressMonitor) {
+
+               // Always notify AST provider
+               // PHPeclipsePlugin.getDefault().getASTProvider().reconciled(ast,
+               // getInputJavaElement());
+
+               // Notify listeners
+               // Object[] listeners = fReconcilingListeners.getListeners();
+               // for (int i = 0, length= listeners.length; i < length; ++i)
+               // ((IJavaReconcilingListener)listeners[i]).reconciled(ast, forced,
+               // progressMonitor);
+
+               // Update Java Outline page selection
+               if (!forced && !progressMonitor.isCanceled()) {
+                       Shell shell = getSite().getShell();
+                       if (shell != null && !shell.isDisposed()) {
+                               shell.getDisplay().asyncExec(new Runnable() {
+                                       public void run() {
+                                               selectionChanged();
+                                       }
+                               });
+                       }
+               }
+       }
+
+       /**
+        * Returns the updated java element for the old java element.
+        */
+       private IJavaElement findElement(IJavaElement element) {
+               if (element == null)
+                       return null;
+               IWorkingCopyManager manager = WebUI.getDefault()
+                               .getWorkingCopyManager();
+               ICompilationUnit unit = manager.getWorkingCopy(getEditorInput());
+               if (unit != null) {
+                       try {
+                               synchronized (unit) {
+                                       unit.reconcile();
+                               }
+                               IJavaElement[] findings = unit.findElements(element);
+                               if (findings != null && findings.length > 0)
+                                       return findings[0];
+                       } catch (JavaModelException x) {
+                               PHPeclipsePlugin.log(x.getStatus());
+                               // nothing found, be tolerant and go on
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Returns the offset of the given Java element.
+        */
+       private int getOffset(IJavaElement element) {
+               if (element instanceof ISourceReference) {
+                       ISourceReference sr = (ISourceReference) element;
+                       try {
+                               ISourceRange srcRange = sr.getSourceRange();
+                               if (srcRange != null)
+                                       return srcRange.getOffset();
+                       } catch (JavaModelException e) {
+                       }
+               }
+               return -1;
+       }
+
+       /*
+        * @see AbstractTextEditor#restoreSelection()
+        */
+       // protected void restoreSelection() {
+       // try {
+       // if (getSourceViewer() == null || fRememberedSelection == null)
+       // return;
+       // IJavaElement newElement = findElement(fRememberedElement);
+       // int newOffset = getOffset(newElement);
+       // int delta = (newOffset > -1 && fRememberedElementOffset > -1) ? newOffset
+       // - fRememberedElementOffset : 0;
+       // if (isValidSelection(delta + fRememberedSelection.getOffset(),
+       // fRememberedSelection.getLength()))
+       // selectAndReveal(delta + fRememberedSelection.getOffset(),
+       // fRememberedSelection.getLength());
+       // } finally {
+       // fRememberedSelection = null;
+       // fRememberedElement = null;
+       // fRememberedElementOffset = -1;
+       // }
+       // }
+       /**
+        * Tells whether this is the active editor in the active page.
+        * 
+        * @return <code>true</code> if this is the active editor in the active
+        *         page
+        * @see IWorkbenchPage#getActiveEditor();
+        */
+       protected final boolean isActiveEditor() {
+               IWorkbenchWindow window = getSite().getWorkbenchWindow();
+               IWorkbenchPage page = window.getActivePage();
+               if (page == null)
+                       return false;
+               IEditorPart activeEditor = page.getActiveEditor();
+               return activeEditor != null && activeEditor.equals(this);
+       }
+
+       /**
+        * Adds the given listener. Has no effect if an identical listener was not
+        * already registered.
+        * 
+        * @param listener
+        *            The reconcile listener to be added
+        * @since 3.0
+        */
+       final void addReconcileListener(IJavaReconcilingListener listener) {
+               synchronized (fReconcilingListeners) {
+                       fReconcilingListeners.add(listener);
+               }
+       }
+
+       /**
+        * Removes the given listener. Has no effect if an identical listener was
+        * not already registered.
+        * 
+        * @param listener
+        *            the reconcile listener to be removed
+        * @since 3.0
+        */
+       final void removeReconcileListener(IJavaReconcilingListener listener) {
+               synchronized (fReconcilingListeners) {
+                       fReconcilingListeners.remove(listener);
+               }
+       }
+
+       protected void updateStateDependentActions() {
+               super.updateStateDependentActions();
+               fGenerateActionGroup.editorStateChanged();
+       }
+
+       /*
+        * @see AbstractTextEditor#rememberSelection()
+        */
+       protected void rememberSelection() {
+               fRememberedSelection.remember();
+       }
+
+       /*
+        * @see AbstractTextEditor#restoreSelection()
+        */
+       protected void restoreSelection() {
+               fRememberedSelection.restore();
+       }
+
+       /*
+        * @see AbstractTextEditor#canHandleMove(IEditorInput, IEditorInput)
+        */
+       protected boolean canHandleMove(IEditorInput originalElement,
+                       IEditorInput movedElement) {
+
+               String oldExtension = ""; //$NON-NLS-1$
+               if (originalElement instanceof IFileEditorInput) {
+                       IFile file = ((IFileEditorInput) originalElement).getFile();
+                       if (file != null) {
+                               String ext = file.getFileExtension();
+                               if (ext != null)
+                                       oldExtension = ext;
+                       }
+               }
+
+               String newExtension = ""; //$NON-NLS-1$
+               if (movedElement instanceof IFileEditorInput) {
+                       IFile file = ((IFileEditorInput) movedElement).getFile();
+                       if (file != null)
+                               newExtension = file.getFileExtension();
+               }
+
+               return oldExtension.equals(newExtension);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isPrefQuickDiffAlwaysOn()
+        */
+       protected boolean isPrefQuickDiffAlwaysOn() {
+               // reestablishes the behaviour from AbstractDecoratedTextEditor which
+               // was hacked by JavaEditor
+               // to disable the change bar for the class file (attached source) java
+               // editor.
+               IPreferenceStore store = getPreferenceStore();
+               return store
+                               .getBoolean(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor#getAdapter(java.lang.Class)
+        */
+       public Object getAdapter(Class required) {
+               if (SmartBackspaceManager.class.equals(required)) {
+                       if (getSourceViewer() instanceof JavaSourceViewer) {
+                               return ((JavaSourceViewer) getSourceViewer())
+                                               .getBackspaceManager();
+                       }
+               }
+
+               return super.getAdapter(required);
+       }
+
+       /**
+        * Returns the mutex for the reconciler. See
+        * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898 for a description of
+        * the problem.
+        * <p>
+        * TODO remove once the underlying problem is solved.
+        * </p>
+        * 
+        * @return the lock reconcilers may use to synchronize on
+        */
+       public Object getReconcilerLock() {
+               return fReconcilerLock;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorSaved()
+        */
+       protected void editorSaved() {
+               super.editorSaved();
+               ShowExternalPreviewAction a = ShowExternalPreviewAction.getInstance();
+               if (a != null) {
+                       //a.refresh(ShowExternalPreviewAction.PHP_TYPE);
+                       a.doRun(ShowExternalPreviewAction.PHP_TYPE);
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java
new file mode 100644 (file)
index 0000000..9e880b4
--- /dev/null
@@ -0,0 +1,290 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IPositionUpdater;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.TextEvent;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.widgets.Control;
+
+public final class PaintManager implements KeyListener, MouseListener,
+               ISelectionChangedListener, ITextListener, ITextInputListener {
+
+       static class PaintPositionUpdater extends DefaultPositionUpdater {
+
+               /**
+                * Creates the position updater.
+                */
+               protected PaintPositionUpdater(String category) {
+                       super(category);
+               }
+
+               /**
+                * If an insertion happens at a position's offset, the position is
+                * extended rather than shifted. Also, if something is added right
+                * behind the end of the position, the position is extended rather than
+                * kept stable.
+                */
+               protected void adaptToInsert() {
+
+                       int myStart = fPosition.offset;
+                       int myEnd = fPosition.offset + fPosition.length;
+                       myEnd = Math.max(myStart, myEnd);
+
+                       int yoursStart = fOffset;
+                       int yoursEnd = fOffset + fReplaceLength;// - 1;
+                       yoursEnd = Math.max(yoursStart, yoursEnd);
+
+                       if (myEnd < yoursStart)
+                               return;
+
+                       if (myStart <= yoursStart)
+                               fPosition.length += fReplaceLength;
+                       else
+                               fPosition.offset += fReplaceLength;
+               }
+       };
+
+       static class PositionManager implements IPositionManager {
+
+               private IDocument fDocument;
+
+               private IPositionUpdater fPositionUpdater;
+
+               private String fCategory;
+
+               public PositionManager() {
+                       fCategory = getClass().getName() + hashCode();
+                       fPositionUpdater = new PaintPositionUpdater(fCategory);
+               }
+
+               public void install(IDocument document) {
+                       fDocument = document;
+                       fDocument.addPositionCategory(fCategory);
+                       fDocument.addPositionUpdater(fPositionUpdater);
+               }
+
+               public void dispose() {
+                       uninstall(fDocument);
+               }
+
+               public void uninstall(IDocument document) {
+                       if (document == fDocument && document != null) {
+                               try {
+                                       fDocument.removePositionUpdater(fPositionUpdater);
+                                       fDocument.removePositionCategory(fCategory);
+                               } catch (BadPositionCategoryException x) {
+                                       // should not happen
+                               }
+                               fDocument = null;
+                       }
+               }
+
+               /*
+                * @see IPositionManager#addManagedPosition(Position)
+                */
+               public void addManagedPosition(Position position) {
+                       try {
+                               fDocument.addPosition(fCategory, position);
+                       } catch (BadPositionCategoryException x) {
+                               // should not happen
+                       } catch (BadLocationException x) {
+                               // should not happen
+                       }
+               }
+
+               /*
+                * @see IPositionManager#removeManagedPosition(Position)
+                */
+               public void removeManagedPosition(Position position) {
+                       try {
+                               fDocument.removePosition(fCategory, position);
+                       } catch (BadPositionCategoryException x) {
+                               // should not happen
+                       }
+               }
+       };
+
+       private List fPainters = new ArrayList(2);
+
+       private PositionManager fManager;
+
+       private ISourceViewer fSourceViewer;
+
+       private boolean fTextChanged = false;
+
+       private boolean fAutoRepeat = false;
+
+       public PaintManager(ISourceViewer sourceViewer) {
+               fSourceViewer = sourceViewer;
+       }
+
+       public void addPainter(IPainter painter) {
+               if (!fPainters.contains(painter)) {
+                       fPainters.add(painter);
+                       if (fPainters.size() == 1)
+                               install();
+                       painter.setPositionManager(fManager);
+                       painter.paint(IPainter.INTERNAL);
+               }
+       }
+
+       public void removePainter(IPainter painter) {
+               if (fPainters.remove(painter))
+                       painter.setPositionManager(null);
+               if (fPainters.size() == 0)
+                       dispose();
+       }
+
+       private void install() {
+
+               fManager = new PositionManager();
+               fManager.install(fSourceViewer.getDocument());
+
+               fSourceViewer.addTextInputListener(this);
+
+               ISelectionProvider provider = fSourceViewer.getSelectionProvider();
+               provider.addSelectionChangedListener(this);
+
+               fSourceViewer.addTextListener(this);
+
+               StyledText text = fSourceViewer.getTextWidget();
+               text.addKeyListener(this);
+               text.addMouseListener(this);
+       }
+
+       public void dispose() {
+
+               if (fManager != null) {
+                       fManager.dispose();
+                       fManager = null;
+               }
+
+               for (Iterator e = fPainters.iterator(); e.hasNext();)
+                       ((IPainter) e.next()).dispose();
+               fPainters.clear();
+
+               fSourceViewer.removeTextInputListener(this);
+
+               ISelectionProvider provider = fSourceViewer.getSelectionProvider();
+               if (provider != null)
+                       provider.removeSelectionChangedListener(this);
+
+               fSourceViewer.removeTextListener(this);
+
+               StyledText text = fSourceViewer.getTextWidget();
+               if (text != null && !text.isDisposed()) {
+                       text.removeKeyListener(this);
+                       text.removeMouseListener(this);
+               }
+       }
+
+       private void paint(int reason) {
+               for (Iterator e = fPainters.iterator(); e.hasNext();)
+                       ((IPainter) e.next()).paint(reason);
+       }
+
+       /*
+        * @see KeyListener#keyPressed(KeyEvent)
+        */
+       public void keyPressed(KeyEvent e) {
+               paint(IPainter.KEY_STROKE);
+       }
+
+       /*
+        * @see KeyListener#keyReleased(KeyEvent)
+        */
+       public void keyReleased(KeyEvent e) {
+       }
+
+       /*
+        * @see MouseListener#mouseDoubleClick(MouseEvent)
+        */
+       public void mouseDoubleClick(MouseEvent e) {
+       }
+
+       /*
+        * @see MouseListener#mouseDown(MouseEvent)
+        */
+       public void mouseDown(MouseEvent e) {
+               paint(IPainter.MOUSE_BUTTON);
+       }
+
+       /*
+        * @see MouseListener#mouseUp(MouseEvent)
+        */
+       public void mouseUp(MouseEvent e) {
+       }
+
+       /*
+        * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
+        */
+       public void selectionChanged(SelectionChangedEvent event) {
+               paint(IPainter.SELECTION);
+       }
+
+       /*
+        * @see ITextListener#textChanged(TextEvent)
+        */
+       public void textChanged(TextEvent event) {
+
+               if (!event.getViewerRedrawState())
+                       return;
+
+               fTextChanged = true;
+               Control control = fSourceViewer.getTextWidget();
+               if (control != null) {
+                       control.getDisplay().asyncExec(new Runnable() {
+                               public void run() {
+                                       if (fTextChanged && fSourceViewer != null)
+                                               paint(IPainter.TEXT_CHANGE);
+                               }
+                       });
+               }
+       }
+
+       /*
+        * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument,
+        *      IDocument)
+        */
+       public void inputDocumentAboutToBeChanged(IDocument oldInput,
+                       IDocument newInput) {
+               if (oldInput != null) {
+                       for (Iterator e = fPainters.iterator(); e.hasNext();)
+                               ((IPainter) e.next()).deactivate(false);
+                       fManager.uninstall(oldInput);
+               }
+       }
+
+       /*
+        * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
+        */
+       public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+               if (newInput != null) {
+                       fManager.install(newInput);
+                       paint(IPainter.TEXT_CHANGE);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PartiallySynchronizedDocument.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PartiallySynchronizedDocument.java
new file mode 100644 (file)
index 0000000..7dfb207
--- /dev/null
@@ -0,0 +1,138 @@
+/**********************************************************************
+ Copyright (c) 2000, 2003 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.ISynchronizable;
+import org.eclipse.jface.text.Position;
+
+/**
+ * Document that can also be used by a background reconciler.
+ */
+public class PartiallySynchronizedDocument extends Document implements
+               ISynchronizable {
+
+       private final Object fInternalLockObject = new Object();
+
+       private Object fLockObject;
+
+       /*
+        * @see org.eclipse.jface.text.ISynchronizable#setLockObject(java.lang.Object)
+        */
+       public void setLockObject(Object lockObject) {
+               fLockObject = lockObject;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.ISynchronizable#getLockObject()
+        */
+       public Object getLockObject() {
+               return fLockObject == null ? fInternalLockObject : fLockObject;
+       }
+
+       /*
+        * @see IDocumentExtension#startSequentialRewrite(boolean)
+        */
+       public void startSequentialRewrite(boolean normalized) {
+               synchronized (getLockObject()) {
+                       super.startSequentialRewrite(normalized);
+               }
+       }
+
+       /*
+        * @see IDocumentExtension#stopSequentialRewrite()
+        */
+       public void stopSequentialRewrite() {
+               synchronized (getLockObject()) {
+                       super.stopSequentialRewrite();
+               }
+       }
+
+       /*
+        * @see IDocument#get()
+        */
+       public String get() {
+               synchronized (getLockObject()) {
+                       return super.get();
+               }
+       }
+
+       /*
+        * @see IDocument#get(int, int)
+        */
+       public String get(int offset, int length) throws BadLocationException {
+               synchronized (getLockObject()) {
+                       return super.get(offset, length);
+               }
+       }
+
+       /*
+        * @see IDocument#getChar(int)
+        */
+       public char getChar(int offset) throws BadLocationException {
+               synchronized (getLockObject()) {
+                       return super.getChar(offset);
+               }
+       }
+
+       /*
+        * @see IDocument#replace(int, int, String)
+        */
+       public void replace(int offset, int length, String text)
+                       throws BadLocationException {
+               synchronized (getLockObject()) {
+                       super.replace(offset, length, text);
+               }
+       }
+
+       /*
+        * @see IDocument#set(String)
+        */
+       public void set(String text) {
+               synchronized (getLockObject()) {
+                       super.set(text);
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.AbstractDocument#addPosition(java.lang.String,
+        *      org.eclipse.jface.text.Position)
+        */
+       public void addPosition(String category, Position position)
+                       throws BadLocationException, BadPositionCategoryException {
+               synchronized (getLockObject()) {
+                       super.addPosition(category, position);
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.AbstractDocument#removePosition(java.lang.String,
+        *      org.eclipse.jface.text.Position)
+        */
+       public void removePosition(String category, Position position)
+                       throws BadPositionCategoryException {
+               synchronized (getLockObject()) {
+                       super.removePosition(category, position);
+               }
+       }
+
+       /*
+        * @see org.eclipse.jface.text.AbstractDocument#getPositions(java.lang.String)
+        */
+       public Position[] getPositions(String category)
+                       throws BadPositionCategoryException {
+               synchronized (getLockObject()) {
+                       return super.getPositions(category);
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PresentationAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PresentationAction.java
new file mode 100644 (file)
index 0000000..a2ad6dd
--- /dev/null
@@ -0,0 +1,54 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * A toolbar action which toggles the presentation model of the connected text
+ * editor. The editor shows either the highlight range only or always the whole
+ * document.
+ */
+public class PresentationAction extends TextEditorAction {
+
+       /**
+        * Constructs and updates the action.
+        */
+       public PresentationAction() {
+               super(PHPEditorMessages.getResourceBundle(),
+                               "TogglePresentation.", null); //$NON-NLS-1$
+               update();
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IAction
+        */
+       public void run() {
+
+               ITextEditor editor = getTextEditor();
+
+               editor.resetHighlightRange();
+               boolean show = editor.showsHighlightRangeOnly();
+               setChecked(!show);
+               editor.showHighlightRangeOnly(!show);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on TextEditorAction
+        */
+       public void update() {
+               setChecked(getTextEditor() != null
+                               && getTextEditor().showsHighlightRangeOnly());
+               setEnabled(true);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PrintMarginPainter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PrintMarginPainter.java
new file mode 100644 (file)
index 0000000..c941e15
--- /dev/null
@@ -0,0 +1,126 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+
+public class PrintMarginPainter implements IPainter, PaintListener {
+
+       private StyledText fTextWidget;
+
+       private int fMarginWidth = 80;
+
+       private Color fColor;
+
+       private int fLineStyle = SWT.LINE_SOLID;
+
+       private int fLineWidth = 1;
+
+       private int fCachedWidgetX = -1;
+
+       private boolean fIsActive = false;
+
+       public PrintMarginPainter(ISourceViewer sourceViewer) {
+               fTextWidget = sourceViewer.getTextWidget();
+       }
+
+       public void setMarginRulerColumn(int width) {
+               fMarginWidth = width;
+               intialize();
+       }
+
+       public void setMarginRulerStyle(int lineStyle) {
+               fLineStyle = lineStyle;
+       }
+
+       public void setMarginRulerWidth(int lineWidth) {
+               fLineWidth = lineWidth;
+       }
+
+       /**
+        * Must be called before <code>paint</code> is called the first time.
+        */
+       public void setMarginRulerColor(Color color) {
+               fColor = color;
+       }
+
+       /**
+        * Must be called explicitly when font of text widget changes.
+        */
+       public void intialize() {
+               computeWidgetX();
+               fTextWidget.redraw();
+       }
+
+       private void computeWidgetX() {
+               GC gc = new GC(fTextWidget);
+               int pixels = gc.getFontMetrics().getAverageCharWidth();
+               gc.dispose();
+
+               fCachedWidgetX = pixels * fMarginWidth;
+       }
+
+       /*
+        * @see IPainter#deactivate(boolean)
+        */
+       public void deactivate(boolean redraw) {
+               if (fIsActive) {
+                       fIsActive = false;
+                       fTextWidget.removePaintListener(this);
+                       if (redraw)
+                               fTextWidget.redraw();
+               }
+       }
+
+       /*
+        * @see IPainter#dispose()
+        */
+       public void dispose() {
+               fTextWidget = null;
+       }
+
+       /*
+        * @see IPainter#paint(int)
+        */
+       public void paint(int reason) {
+               if (!fIsActive) {
+                       fIsActive = true;
+                       fTextWidget.addPaintListener(this);
+                       if (fCachedWidgetX == -1)
+                               computeWidgetX();
+                       fTextWidget.redraw();
+               }
+       }
+
+       /*
+        * @see IPainter#setPositionManager(IPositionManager)
+        */
+       public void setPositionManager(IPositionManager manager) {
+       }
+
+       /*
+        * @see PaintListener#paintControl(PaintEvent)
+        */
+       public void paintControl(PaintEvent e) {
+               if (fTextWidget != null) {
+                       int x = fCachedWidgetX - fTextWidget.getHorizontalPixel();
+                       if (x >= 0) {
+                               Rectangle area = fTextWidget.getClientArea();
+                               e.gc.setForeground(fColor);
+                               e.gc.setLineStyle(fLineStyle);
+                               e.gc.setLineWidth(fLineWidth);
+                               e.gc.drawLine(x, 0, x, area.height);
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ProblemAnnotationIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ProblemAnnotationIterator.java
new file mode 100644 (file)
index 0000000..7895116
--- /dev/null
@@ -0,0 +1,73 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.Iterator;
+
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+/**
+ * Filters problems based on their types.
+ */
+public class ProblemAnnotationIterator implements Iterator {
+
+       private Iterator fIterator;
+
+       private IProblemAnnotation fNext;
+
+       private boolean fSkipIrrelevants;
+
+       public ProblemAnnotationIterator(IAnnotationModel model,
+                       boolean skipIrrelevants) {
+               fIterator = model.getAnnotationIterator();
+               fSkipIrrelevants = skipIrrelevants;
+               skip();
+       }
+
+       private void skip() {
+               while (fIterator.hasNext()) {
+                       Object next = fIterator.next();
+                       if (next instanceof IProblemAnnotation) {
+                               IProblemAnnotation a = (IProblemAnnotation) next;
+                               if (fSkipIrrelevants) {
+                                       if (a.isRelevant()) {
+                                               fNext = a;
+                                               return;
+                                       }
+                               } else {
+                                       fNext = a;
+                                       return;
+                               }
+                       }
+               }
+               fNext = null;
+       }
+
+       /*
+        * @see Iterator#hasNext()
+        */
+       public boolean hasNext() {
+               return fNext != null;
+       }
+
+       /*
+        * @see Iterator#next()
+        */
+       public Object next() {
+               try {
+                       return fNext;
+               } finally {
+                       skip();
+               }
+       }
+
+       /*
+        * @see Iterator#remove()
+        */
+       public void remove() {
+               throw new UnsupportedOperationException();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ProblemPainter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ProblemPainter.java
new file mode 100644 (file)
index 0000000..f125eea
--- /dev/null
@@ -0,0 +1,406 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelListener;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Highlights the temporary problems.
+ */
+public class ProblemPainter implements IPainter, PaintListener,
+               IAnnotationModelListener {
+
+       private static class ProblemPosition {
+               Position fPosition;
+
+               Color fColor;
+
+               boolean fMultiLine;
+       };
+
+       private boolean fIsActive = false;
+
+       private boolean fIsPainting = false;
+
+       private boolean fIsSettingModel = false;
+
+       private ITextEditor fTextEditor;
+
+       private ISourceViewer fSourceViewer;
+
+       private StyledText fTextWidget;
+
+       private IAnnotationModel fModel;
+
+       private List fProblemPositions = new ArrayList();
+
+       private Map fColorTable = new HashMap();
+
+       private Set fAnnotationSet = new HashSet();
+
+       public ProblemPainter(ITextEditor textEditor, ISourceViewer sourceViewer) {
+               fTextEditor = textEditor;
+               fSourceViewer = sourceViewer;
+               fTextWidget = sourceViewer.getTextWidget();
+       }
+
+       private boolean hasProblems() {
+               return !fProblemPositions.isEmpty();
+       }
+
+       private void enablePainting() {
+               if (!fIsPainting && hasProblems()) {
+                       fIsPainting = true;
+                       fTextWidget.addPaintListener(this);
+                       handleDrawRequest(null);
+               }
+       }
+
+       private void disablePainting(boolean redraw) {
+               if (fIsPainting) {
+                       fIsPainting = false;
+                       fTextWidget.removePaintListener(this);
+                       if (redraw && hasProblems())
+                               handleDrawRequest(null);
+               }
+       }
+
+       private void setModel(IAnnotationModel model) {
+               if (fModel != model) {
+                       if (fModel != null)
+                               fModel.removeAnnotationModelListener(this);
+                       fModel = model;
+                       if (fModel != null) {
+                               try {
+                                       fIsSettingModel = true;
+                                       fModel.addAnnotationModelListener(this);
+                               } finally {
+                                       fIsSettingModel = false;
+                               }
+                       }
+               }
+       }
+
+       private void catchupWithModel() {
+               if (fProblemPositions != null) {
+                       fProblemPositions.clear();
+                       if (fModel != null) {
+
+                               Iterator e = new ProblemAnnotationIterator(fModel, true);
+                               while (e.hasNext()) {
+                                       IProblemAnnotation pa = (IProblemAnnotation) e.next();
+                                       Annotation a = (Annotation) pa;
+
+                                       Color color = null;
+                                       AnnotationType type = pa.getAnnotationType();
+                                       if (fAnnotationSet.contains(type))
+                                               color = (Color) fColorTable.get(type);
+
+                                       if (color != null) {
+                                               ProblemPosition pp = new ProblemPosition();
+                                               pp.fPosition = fModel.getPosition(a);
+                                               pp.fColor = color;
+                                               pp.fMultiLine = true;
+                                               fProblemPositions.add(pp);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private void updatePainting() {
+               disablePainting(true);
+               catchupWithModel();
+               enablePainting();
+       }
+
+       /*
+        * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+        */
+       public void modelChanged(final IAnnotationModel model) {
+               if (fTextWidget != null && !fTextWidget.isDisposed()) {
+                       if (fIsSettingModel) {
+                               // inside the ui thread -> no need for posting
+                               updatePainting();
+                       } else {
+                               Display d = fTextWidget.getDisplay();
+                               if (d != null) {
+                                       d.asyncExec(new Runnable() {
+                                               public void run() {
+                                                       if (fTextWidget != null
+                                                                       && !fTextWidget.isDisposed())
+                                                               updatePainting();
+                                               }
+                                       });
+                               }
+                       }
+               }
+       }
+
+       public void setColor(AnnotationType annotationType, Color color) {
+               if (color != null)
+                       fColorTable.put(annotationType, color);
+               else
+                       fColorTable.remove(annotationType);
+       }
+
+       public void paintAnnotations(AnnotationType annotationType, boolean paint) {
+               if (paint)
+                       fAnnotationSet.add(annotationType);
+               else
+                       fAnnotationSet.remove(annotationType);
+       }
+
+       public boolean isPaintingAnnotations() {
+               return !fAnnotationSet.isEmpty();
+       }
+
+       /*
+        * @see IPainter#dispose()
+        */
+       public void dispose() {
+
+               if (fColorTable != null)
+                       fColorTable.clear();
+               fColorTable = null;
+
+               if (fAnnotationSet != null)
+                       fAnnotationSet.clear();
+               fAnnotationSet = null;
+
+               fTextWidget = null;
+               fModel = null;
+               fProblemPositions = null;
+       }
+
+       /*
+        * Returns the document offset of the upper left corner of the widgets
+        * viewport, possibly including partially visible lines.
+        */
+       private int getInclusiveTopIndexStartOffset() {
+
+               if (fTextWidget != null && !fTextWidget.isDisposed()) {
+                       int top = fSourceViewer.getTopIndex();
+                       if ((fTextWidget.getTopPixel() % fTextWidget.getLineHeight()) != 0)
+                               top--;
+                       try {
+                               IDocument document = fSourceViewer.getDocument();
+                               return document.getLineOffset(top);
+                       } catch (BadLocationException ex) {
+                       }
+               }
+
+               return -1;
+       }
+
+       /*
+        * @see PaintListener#paintControl(PaintEvent)
+        */
+       public void paintControl(PaintEvent event) {
+               if (fTextWidget != null)
+                       handleDrawRequest(event.gc);
+       }
+
+       private void handleDrawRequest(GC gc) {
+
+               int vOffset = getInclusiveTopIndexStartOffset();
+               // http://bugs.eclipse.org/bugs/show_bug.cgi?id=17147
+               int vLength = fSourceViewer.getBottomIndexEndOffset() + 1;
+
+               for (Iterator e = fProblemPositions.iterator(); e.hasNext();) {
+                       ProblemPosition pp = (ProblemPosition) e.next();
+                       Position p = pp.fPosition;
+                       if (p.overlapsWith(vOffset, vLength)) {
+
+                               if (!pp.fMultiLine) {
+
+                                       IRegion widgetRange = getWidgetRange(p);
+                                       if (widgetRange != null)
+                                               draw(gc, widgetRange.getOffset(), widgetRange
+                                                               .getLength(), pp.fColor);
+
+                               } else {
+
+                                       IDocument document = fSourceViewer.getDocument();
+                                       try {
+
+                                               int startLine = document.getLineOfOffset(p.getOffset());
+                                               int lastInclusive = Math.max(p.getOffset(), p
+                                                               .getOffset()
+                                                               + p.getLength() - 1);
+                                               int endLine = document.getLineOfOffset(lastInclusive);
+
+                                               for (int i = startLine; i <= endLine; i++) {
+                                                       IRegion line = document.getLineInformation(i);
+                                                       int paintStart = Math.max(line.getOffset(), p
+                                                                       .getOffset());
+                                                       int paintEnd = Math.min(line.getOffset()
+                                                                       + line.getLength(), p.getOffset()
+                                                                       + p.getLength());
+                                                       if (paintEnd > paintStart) {
+                                                               // otherwise inside a line delimiter
+                                                               IRegion widgetRange = getWidgetRange(new Position(
+                                                                               paintStart, paintEnd - paintStart));
+                                                               if (widgetRange != null)
+                                                                       draw(gc, widgetRange.getOffset(),
+                                                                                       widgetRange.getLength(), pp.fColor);
+                                                       }
+                                               }
+
+                                       } catch (BadLocationException x) {
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private IRegion getWidgetRange(Position p) {
+               if (fSourceViewer instanceof ITextViewerExtension5) {
+                       ITextViewerExtension5 extension = (ITextViewerExtension5) fSourceViewer;
+                       return extension.modelRange2WidgetRange(new Region(p.getOffset(), p
+                                       .getLength()));
+
+               } else {
+
+                       IRegion region = fSourceViewer.getVisibleRegion();
+                       int offset = region.getOffset();
+                       int length = region.getLength();
+
+                       if (p.overlapsWith(offset, length)) {
+                               int p1 = Math.max(offset, p.getOffset());
+                               int p2 = Math.min(offset + length, p.getOffset()
+                                               + p.getLength());
+                               return new Region(p1 - offset, p2 - p1);
+                       }
+               }
+
+               return null;
+       }
+
+       private int[] computePolyline(Point left, Point right, int height) {
+
+               final int WIDTH = 4; // must be even
+               final int HEIGHT = 2; // can be any number
+               // final int MINPEEKS= 2; // minimal number of peeks
+
+               int peeks = (right.x - left.x) / WIDTH;
+               // if (peeks < MINPEEKS) {
+               // int missing= (MINPEEKS - peeks) * WIDTH;
+               // left.x= Math.max(0, left.x - missing/2);
+               // peeks= MINPEEKS;
+               // }
+
+               int leftX = left.x;
+
+               // compute (number of point) * 2
+               int length = ((2 * peeks) + 1) * 2;
+               if (length < 0)
+                       return new int[0];
+
+               int[] coordinates = new int[length];
+
+               // cache peeks' y-coordinates
+               int bottom = left.y + height - 1;
+               int top = bottom - HEIGHT;
+
+               // populate array with peek coordinates
+               for (int i = 0; i < peeks; i++) {
+                       int index = 4 * i;
+                       coordinates[index] = leftX + (WIDTH * i);
+                       coordinates[index + 1] = bottom;
+                       coordinates[index + 2] = coordinates[index] + WIDTH / 2;
+                       coordinates[index + 3] = top;
+               }
+
+               // the last down flank is missing
+               coordinates[length - 2] = left.x + (WIDTH * peeks);
+               coordinates[length - 1] = bottom;
+
+               return coordinates;
+       }
+
+       private void draw(GC gc, int offset, int length, Color color) {
+               if (gc != null) {
+
+                       Point left = fTextWidget.getLocationAtOffset(offset);
+                       Point right = fTextWidget.getLocationAtOffset(offset + length);
+
+                       gc.setForeground(color);
+                       int[] polyline = computePolyline(left, right, gc.getFontMetrics()
+                                       .getHeight());
+                       gc.drawPolyline(polyline);
+
+               } else {
+                       fTextWidget.redrawRange(offset, length, true);
+               }
+       }
+
+       /*
+        * @see IPainter#deactivate(boolean)
+        */
+       public void deactivate(boolean redraw) {
+               if (fIsActive) {
+                       fIsActive = false;
+                       disablePainting(redraw);
+                       setModel(null);
+                       catchupWithModel();
+               }
+       }
+
+       /*
+        * @see IPainter#paint(int)
+        */
+       public void paint(int reason) {
+               if (!fIsActive) {
+                       fIsActive = true;
+                       IDocumentProvider provider = WebUI.getDefault()
+                                       .getCompilationUnitDocumentProvider();
+                       setModel(provider.getAnnotationModel(fTextEditor.getEditorInput()));
+               } else if (CONFIGURATION == reason || INTERNAL == reason)
+                       updatePainting();
+       }
+
+       /*
+        * @see IPainter#setPositionManager(IPositionManager)
+        */
+       public void setPositionManager(IPositionManager manager) {
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/SmartyDocumentSetupParticipant.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/SmartyDocumentSetupParticipant.java
new file mode 100644 (file)
index 0000000..4847d20
--- /dev/null
@@ -0,0 +1,39 @@
+/**********************************************************************
+ Copyright (c) 2000, 2003 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * The document setup participant for PHPDT.
+ */
+public class SmartyDocumentSetupParticipant implements
+               IDocumentSetupParticipant {
+
+       public SmartyDocumentSetupParticipant() {
+       }
+
+       /*
+        * @see org.eclipse.core.filebuffers.IDocumentSetupParticipant#setup(org.eclipse.jface.text.IDocument)
+        */
+       public void setup(IDocument document) {
+               JavaTextTools tools = WebUI.getDefault().getJavaTextTools();
+               tools.setupSmartyDocumentPartitioner(document,
+                               IPHPPartitions.PHP_PARTITIONING, null); // IPHPPartitions.PHP_PARTITIONING,
+                                                                                                               // null);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ToggleCommentAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/ToggleCommentAction.java
new file mode 100644 (file)
index 0000000..ada76ed
--- /dev/null
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ResourceAction;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * An action which toggles comment prefixes on the selected lines.
+ * 
+ * @since 3.0
+ */
+public final class ToggleCommentAction extends TextEditorAction {
+
+       /** The text operation target */
+       private ITextOperationTarget fOperationTarget;
+
+       /** The document partitioning */
+       private String fDocumentPartitioning;
+
+       /** The comment prefixes */
+       private Map fPrefixesMap;
+
+       /**
+        * Creates and initializes the action for the given text editor. The action
+        * configures its visual representation from the given resource bundle.
+        * 
+        * @param bundle
+        *            the resource bundle
+        * @param prefix
+        *            a prefix to be prepended to the various resource keys
+        *            (described in <code>ResourceAction</code> constructor), or
+        *            <code>null</code> if none
+        * @param editor
+        *            the text editor
+        * @see ResourceAction#ResourceAction(ResourceBundle, String, int)
+        */
+       public ToggleCommentAction(ResourceBundle bundle, String prefix,
+                       ITextEditor editor) {
+               super(bundle, prefix, editor);
+       }
+
+       /**
+        * Implementation of the <code>IAction</code> prototype. Checks if the
+        * selected lines are all commented or not and uncomments/comments them
+        * respectively.
+        */
+       public void run() {
+               if (fOperationTarget == null || fDocumentPartitioning == null
+                               || fPrefixesMap == null)
+                       return;
+
+               ITextEditor editor = getTextEditor();
+               if (editor == null)
+                       return;
+
+               if (!validateEditorInputState())
+                       return;
+
+               final int operationCode;
+               if (isSelectionCommented(editor.getSelectionProvider().getSelection()))
+                       operationCode = ITextOperationTarget.STRIP_PREFIX;
+               else
+                       operationCode = ITextOperationTarget.PREFIX;
+
+               Shell shell = editor.getSite().getShell();
+               if (!fOperationTarget.canDoOperation(operationCode)) {
+                       if (shell != null)
+                               MessageDialog
+                                               .openError(
+                                                               shell,
+                                                               PHPEditorMessages
+                                                                               .getString("ToggleComment.error.title"), PHPEditorMessages.getString("ToggleComment.error.message")); //$NON-NLS-1$ //$NON-NLS-2$
+                       return;
+               }
+
+               Display display = null;
+               if (shell != null && !shell.isDisposed())
+                       display = shell.getDisplay();
+
+               BusyIndicator.showWhile(display, new Runnable() {
+                       public void run() {
+                               fOperationTarget.doOperation(operationCode);
+                       }
+               });
+       }
+
+       /**
+        * Is the given selection single-line commented?
+        * 
+        * @param selection
+        *            Selection to check
+        * @return <code>true</code> iff all selected lines are commented
+        */
+       private boolean isSelectionCommented(ISelection selection) {
+               if (!(selection instanceof ITextSelection))
+                       return false;
+
+               ITextSelection textSelection = (ITextSelection) selection;
+               if (textSelection.getStartLine() < 0 || textSelection.getEndLine() < 0)
+                       return false;
+
+               IDocument document = getTextEditor().getDocumentProvider().getDocument(
+                               getTextEditor().getEditorInput());
+
+               try {
+
+                       IRegion block = getTextBlockFromSelection(textSelection, document);
+                       ITypedRegion[] regions = TextUtilities.computePartitioning(
+                                       document, fDocumentPartitioning, block.getOffset(), block
+                                                       .getLength(), false);
+
+                       int lineCount = 0;
+                       int[] lines = new int[regions.length * 2]; // [startline, endline,
+                                                                                                               // startline, endline,
+                                                                                                               // ...]
+                       for (int i = 0, j = 0; i < regions.length; i++, j += 2) {
+                               // start line of region
+                               lines[j] = getFirstCompleteLineOfRegion(regions[i], document);
+                               // end line of region
+                               int length = regions[i].getLength();
+                               int offset = regions[i].getOffset() + length;
+                               if (length > 0)
+                                       offset--;
+                               lines[j + 1] = (lines[j] == -1 ? -1 : document
+                                               .getLineOfOffset(offset));
+                               lineCount += lines[j + 1] - lines[j] + 1;
+                       }
+
+                       // Perform the check
+                       for (int i = 0, j = 0; i < regions.length; i++, j += 2) {
+                               String[] prefixes = (String[]) fPrefixesMap.get(regions[i]
+                                               .getType());
+                               if (prefixes != null && prefixes.length > 0 && lines[j] >= 0
+                                               && lines[j + 1] >= 0)
+                                       if (!isBlockCommented(lines[j], lines[j + 1], prefixes,
+                                                       document))
+                                               return false;
+                       }
+
+                       return true;
+
+               } catch (BadLocationException x) {
+                       // should not happen
+                       PHPeclipsePlugin.log(x);
+               }
+
+               return false;
+       }
+
+       /**
+        * Creates a region describing the text block (something that starts at the
+        * beginning of a line) completely containing the current selection.
+        * 
+        * @param selection
+        *            The selection to use
+        * @param document
+        *            The document
+        * @return the region describing the text block comprising the given
+        *         selection
+        */
+       private IRegion getTextBlockFromSelection(ITextSelection selection,
+                       IDocument document) {
+
+               try {
+                       IRegion line = document.getLineInformationOfOffset(selection
+                                       .getOffset());
+                       int length = selection.getLength() == 0 ? line.getLength()
+                                       : selection.getLength()
+                                                       + (selection.getOffset() - line.getOffset());
+                       return new Region(line.getOffset(), length);
+
+               } catch (BadLocationException x) {
+                       // should not happen
+                       PHPeclipsePlugin.log(x);
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns the index of the first line whose start offset is in the given
+        * text range.
+        * 
+        * @param region
+        *            the text range in characters where to find the line
+        * @param document
+        *            The document
+        * @return the first line whose start index is in the given range, -1 if
+        *         there is no such line
+        */
+       private int getFirstCompleteLineOfRegion(IRegion region, IDocument document) {
+
+               try {
+
+                       int startLine = document.getLineOfOffset(region.getOffset());
+
+                       int offset = document.getLineOffset(startLine);
+                       if (offset >= region.getOffset())
+                               return startLine;
+
+                       offset = document.getLineOffset(startLine + 1);
+                       return (offset > region.getOffset() + region.getLength() ? -1
+                                       : startLine + 1);
+
+               } catch (BadLocationException x) {
+                       // should not happen
+                       PHPeclipsePlugin.log(x);
+               }
+
+               return -1;
+       }
+
+       /**
+        * Determines whether each line is prefixed by one of the prefixes.
+        * 
+        * @param startLine
+        *            Start line in document
+        * @param endLine
+        *            End line in document
+        * @param prefixes
+        *            Possible comment prefixes
+        * @param document
+        *            The document
+        * @return <code>true</code> iff each line from <code>startLine</code>
+        *         to and including <code>endLine</code> is prepended by one of
+        *         the <code>prefixes</code>, ignoring whitespace at the begin of
+        *         line
+        */
+       private boolean isBlockCommented(int startLine, int endLine,
+                       String[] prefixes, IDocument document) {
+
+               try {
+
+                       // check for occurrences of prefixes in the given lines
+                       for (int i = startLine; i <= endLine; i++) {
+
+                               IRegion line = document.getLineInformation(i);
+                               String text = document.get(line.getOffset(), line.getLength());
+
+                               int[] found = TextUtilities.indexOf(prefixes, text, 0);
+
+                               if (found[0] == -1)
+                                       // found a line which is not commented
+                                       return false;
+
+                               String s = document.get(line.getOffset(), found[0]);
+                               s = s.trim();
+                               if (s.length() != 0)
+                                       // found a line which is not commented
+                                       return false;
+
+                       }
+
+                       return true;
+
+               } catch (BadLocationException x) {
+                       // should not happen
+                       PHPeclipsePlugin.log(x);
+               }
+
+               return false;
+       }
+
+       /**
+        * Implementation of the <code>IUpdate</code> prototype method discovers
+        * the operation through the current editor's
+        * <code>ITextOperationTarget</code> adapter, and sets the enabled state
+        * accordingly.
+        */
+       public void update() {
+               super.update();
+
+               if (!canModifyEditor()) {
+                       setEnabled(false);
+                       return;
+               }
+
+               ITextEditor editor = getTextEditor();
+               if (fOperationTarget == null && editor != null)
+                       fOperationTarget = (ITextOperationTarget) editor
+                                       .getAdapter(ITextOperationTarget.class);
+
+               boolean isEnabled = (fOperationTarget != null
+                               && fOperationTarget.canDoOperation(ITextOperationTarget.PREFIX) && fOperationTarget
+                               .canDoOperation(ITextOperationTarget.STRIP_PREFIX));
+               setEnabled(isEnabled);
+       }
+
+       /*
+        * @see TextEditorAction#setEditor(ITextEditor)
+        */
+       public void setEditor(ITextEditor editor) {
+               super.setEditor(editor);
+               fOperationTarget = null;
+       }
+
+       public void configure(ISourceViewer sourceViewer,
+                       SourceViewerConfiguration configuration) {
+               fPrefixesMap = null;
+
+               String[] types = configuration.getConfiguredContentTypes(sourceViewer);
+               Map prefixesMap = new HashMap(types.length);
+               for (int i = 0; i < types.length; i++) {
+                       String type = types[i];
+                       String[] prefixes = configuration.getDefaultPrefixes(sourceViewer,
+                                       type);
+                       if (prefixes != null && prefixes.length > 0) {
+                               int emptyPrefixes = 0;
+                               for (int j = 0; j < prefixes.length; j++)
+                                       if (prefixes[j].length() == 0)
+                                               emptyPrefixes++;
+
+                               if (emptyPrefixes > 0) {
+                                       String[] nonemptyPrefixes = new String[prefixes.length
+                                                       - emptyPrefixes];
+                                       for (int j = 0, k = 0; j < prefixes.length; j++) {
+                                               String prefix = prefixes[j];
+                                               if (prefix.length() != 0) {
+                                                       nonemptyPrefixes[k] = prefix;
+                                                       k++;
+                                               }
+                                       }
+                                       prefixes = nonemptyPrefixes;
+                               }
+
+                               prefixesMap.put(type, prefixes);
+                       }
+               }
+               fDocumentPartitioning = configuration
+                               .getConfiguredDocumentPartitioning(sourceViewer);
+               fPrefixesMap = prefixesMap;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/TogglePresentationAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/TogglePresentationAction.java
new file mode 100644 (file)
index 0000000..b46e1c4
--- /dev/null
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.actions.PHPEditorActionDefinitionIds;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * A toolbar action which toggles the presentation model of the connected text
+ * editor. The editor shows either the highlight range only or always the whole
+ * document.
+ */
+public class TogglePresentationAction extends TextEditorAction implements
+               IPropertyChangeListener {
+
+       private IPreferenceStore fStore;
+
+       /**
+        * Constructs and updates the action.
+        */
+       public TogglePresentationAction() {
+               super(PHPEditorMessages.getResourceBundle(),
+                               "TogglePresentation.", null); //$NON-NLS-1$
+               PHPUiImages.setToolImageDescriptors(this, "segment_edit.gif"); //$NON-NLS-1$
+               setToolTipText(PHPEditorMessages
+                               .getString("TogglePresentation.tooltip")); //$NON-NLS-1$
+               setActionDefinitionId(PHPEditorActionDefinitionIds.TOGGLE_PRESENTATION);
+               // WorkbenchHelp.setHelp(this,
+               // IJavaHelpContextIds.TOGGLE_PRESENTATION_ACTION);
+               update();
+       }
+
+       /*
+        * @see IAction#actionPerformed
+        */
+       public void run() {
+
+               ITextEditor editor = getTextEditor();
+               if (editor == null)
+                       return;
+
+               IRegion remembered = editor.getHighlightRange();
+               editor.resetHighlightRange();
+
+               boolean showAll = !editor.showsHighlightRangeOnly();
+               setChecked(showAll);
+
+               editor.showHighlightRangeOnly(showAll);
+               if (remembered != null)
+                       editor.setHighlightRange(remembered.getOffset(), remembered
+                                       .getLength(), true);
+
+               fStore.removePropertyChangeListener(this);
+               fStore.setValue(PreferenceConstants.EDITOR_SHOW_SEGMENTS, showAll);
+               fStore.addPropertyChangeListener(this);
+       }
+
+       /*
+        * @see TextEditorAction#update
+        */
+       public void update() {
+               ITextEditor editor = getTextEditor();
+               boolean checked = (editor != null && editor.showsHighlightRangeOnly());
+               setChecked(checked);
+               setEnabled(editor != null);
+       }
+
+       /*
+        * @see TextEditorAction#setEditor(ITextEditor)
+        */
+       public void setEditor(ITextEditor editor) {
+
+               super.setEditor(editor);
+
+               if (editor != null) {
+
+                       if (fStore == null) {
+                               fStore = WebUI.getDefault().getPreferenceStore();
+                               fStore.addPropertyChangeListener(this);
+                       }
+                       synchronizeWithPreference(editor);
+
+               } else if (fStore != null) {
+                       fStore.removePropertyChangeListener(this);
+                       fStore = null;
+               }
+
+               update();
+       }
+
+       /**
+        * Synchronizes the appearance of the editor with what the preference store
+        * tells him.
+        */
+       private void synchronizeWithPreference(ITextEditor editor) {
+
+               if (editor == null)
+                       return;
+
+               boolean showSegments = fStore
+                               .getBoolean(PreferenceConstants.EDITOR_SHOW_SEGMENTS);
+               setChecked(showSegments);
+
+               if (editor.showsHighlightRangeOnly() != showSegments) {
+                       IRegion remembered = editor.getHighlightRange();
+                       editor.resetHighlightRange();
+                       editor.showHighlightRangeOnly(showSegments);
+                       if (remembered != null)
+                               editor.setHighlightRange(remembered.getOffset(), remembered
+                                               .getLength(), true);
+               }
+       }
+
+       /*
+        * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+        */
+       public void propertyChange(PropertyChangeEvent event) {
+               if (event.getProperty()
+                               .equals(PreferenceConstants.EDITOR_SHOW_SEGMENTS))
+                       synchronizeWithPreference(getTextEditor());
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/WorkingCopyManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/WorkingCopyManager.java
new file mode 100644 (file)
index 0000000..1f96fb2
--- /dev/null
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpdt.ui.IWorkingCopyManagerExtension;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * This working copy manager works together with a given compilation unit
+ * document provider and additionally offers to "overwrite" the working copy
+ * provided by this document provider.
+ */
+public class WorkingCopyManager implements IWorkingCopyManager,
+               IWorkingCopyManagerExtension {
+
+       private ICompilationUnitDocumentProvider fDocumentProvider;
+
+       private Map fMap;
+
+       private boolean fIsShuttingDown;
+
+       /**
+        * Creates a new working copy manager that co-operates with the given
+        * compilation unit document provider.
+        * 
+        * @param provider
+        *            the provider
+        */
+       public WorkingCopyManager(ICompilationUnitDocumentProvider provider) {
+               Assert.isNotNull(provider);
+               fDocumentProvider = provider;
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.IWorkingCopyManager#connect(org.eclipse.ui.IEditorInput)
+        */
+       public void connect(IEditorInput input) throws CoreException {
+               fDocumentProvider.connect(input);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.IWorkingCopyManager#disconnect(org.eclipse.ui.IEditorInput)
+        */
+       public void disconnect(IEditorInput input) {
+               fDocumentProvider.disconnect(input);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.IWorkingCopyManager#shutdown()
+        */
+       public void shutdown() {
+               if (!fIsShuttingDown) {
+                       fIsShuttingDown = true;
+                       try {
+                               if (fMap != null) {
+                                       fMap.clear();
+                                       fMap = null;
+                               }
+                               fDocumentProvider.shutdown();
+                       } finally {
+                               fIsShuttingDown = false;
+                       }
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.ui.IWorkingCopyManager#getWorkingCopy(org.eclipse.ui.IEditorInput)
+        */
+       public ICompilationUnit getWorkingCopy(IEditorInput input) {
+               ICompilationUnit unit = fMap == null ? null : (ICompilationUnit) fMap
+                               .get(input);
+               return unit != null ? unit : fDocumentProvider.getWorkingCopy(input);
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.IWorkingCopyManagerExtension#setWorkingCopy(org.eclipse.ui.IEditorInput,
+        *      net.sourceforge.phpdt.core.ICompilationUnit)
+        */
+       public void setWorkingCopy(IEditorInput input, ICompilationUnit workingCopy) {
+               if (fDocumentProvider.getDocument(input) != null) {
+                       if (fMap == null)
+                               fMap = new HashMap();
+                       fMap.put(input, workingCopy);
+               }
+       }
+
+       /*
+        * @see net.sourceforge.phpdt.internal.ui.javaeditor.IWorkingCopyManagerExtension#removeWorkingCopy(org.eclipse.ui.IEditorInput)
+        */
+       public void removeWorkingCopy(IEditorInput input) {
+               fMap.remove(input);
+               if (fMap.isEmpty())
+                       fMap = null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/actions/RTrimAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/actions/RTrimAction.java
new file mode 100644 (file)
index 0000000..a014e9e
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Created on Oct 15, 2004
+ *
+ * The MIT License
+ * Copyright (c) 2004 Stephen Milligan
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a 
+ * copy of this software and associated documentation files (the "Software"), 
+ * to deal in the Software without restriction, including without limitation 
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+ * and/or sell copies of the Software, and to permit persons to whom the Software 
+ * is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+ * SOFTWARE.
+ */
+package net.sourceforge.phpeclipse.phpeditor.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * @author Stephen Milligan
+ */
+public class RTrimAction implements IEditorActionDelegate {
+
+       ITextEditor editor = null;
+
+       /**
+        * 
+        */
+       public RTrimAction() {
+               super();
+       }
+
+       public void setActiveEditor(IAction action, IEditorPart targetEditor) {
+
+               if (targetEditor instanceof ITextEditor) {
+                       editor = (ITextEditor) targetEditor;
+               }
+       }
+
+       /**
+        * this gets called for every action
+        */
+       public void run(IAction action) {
+               IDocument doc = editor.getDocumentProvider().getDocument(
+                               editor.getEditorInput());
+               ITextSelection sel = (ITextSelection) editor.getSelectionProvider()
+                               .getSelection();
+
+               int currentLine = 0;
+               int originalCursorOffset = sel.getOffset();
+               int cursorOffset = originalCursorOffset;
+               int originalSelectionLength = sel.getLength();
+               int selectionLength = originalSelectionLength;
+               String oldText;
+               int lineEnd;
+
+               try {
+
+                       while (currentLine < doc.getNumberOfLines()) {
+                               int offset = doc.getLineOffset(currentLine);
+                               int length = doc.getLineLength(currentLine);
+                               oldText = doc.get(offset, length);
+                               String lineDelimiter = doc.getLineDelimiter(currentLine);
+                               if (lineDelimiter == null) lineDelimiter = "";
+
+                               // -- Starts at the end of the line, looking for the first
+                               // non-first 'white space'
+                               // -- it then breaks out. No point in carrying on, as we have
+                               // found our true line end
+                               for (lineEnd = oldText.length() - lineDelimiter.length(); lineEnd > 0; --lineEnd) {
+                                       if (oldText.charAt(lineEnd - 1) != '\t'
+                                                       && oldText.charAt(lineEnd - 1) != ' ') {
+                                               break;
+                                       }
+                               }
+
+                               // -- Only replace the line if the lengths are different
+                               if (lineEnd != oldText.length() - lineDelimiter.length()) {
+                                       String newText = oldText.substring(0, lineEnd) + lineDelimiter;
+                                       doc.replace(offset, length, newText);
+
+//                                     if (offset + length <= cursorOffset) {
+//                                             if (oldText.length() != newText.length()) {
+//                                                     cursorOffset -= oldText.length() - newText.length();
+//                                             }
+//                                     } else if (offset <= cursorOffset + selectionLength
+//                                                     && selectionLength > 0) {
+//                                             selectionLength -= oldText.length() - newText.length();
+//                                     } else if (offset + length == cursorOffset + 2) {
+//                                             // Check if the cursor is at the end of the line.
+//                                             cursorOffset -= 2;
+//                                     }
+
+                                       int oldEndOffset = offset + length - lineDelimiter.length();
+                                       int newEndOffset = offset + lineEnd;
+
+                                       if (cursorOffset >= oldEndOffset) {
+                                               cursorOffset -= oldText.length() - newText.length();
+                                       } else if (cursorOffset >= newEndOffset) {
+                                               cursorOffset = newEndOffset;
+                                       }
+                                       if (selectionLength > 0) {
+                                               int selectionEndOffset = cursorOffset + selectionLength;
+                                               if (selectionEndOffset >= oldEndOffset) {
+                                                       if (cursorOffset <= newEndOffset) {
+                                                               // full overlap
+                                                               selectionLength -= oldText.length() - newText.length();
+                                                       } else {
+                                                               // starts inside
+                                                               selectionLength -= oldEndOffset - cursorOffset;
+                                                       }
+                                               } else if (selectionEndOffset >= newEndOffset) {
+                                                       if (cursorOffset <= newEndOffset) {
+                                                               // ends inside
+                                                               selectionLength -= selectionEndOffset - newEndOffset;
+                                                       } else {
+                                                               // full inside
+                                                               selectionLength = 0;
+                                                       }
+                                               }
+                                       }
+                               }
+                               currentLine++;
+                       }
+
+                       TextSelection selection = new TextSelection(doc, cursorOffset,
+                                       selectionLength);
+                       editor.getSelectionProvider().setSelection(selection);
+               } catch (Exception blx) {
+                       blx.printStackTrace();
+               }
+       }
+
+       public void selectionChanged(IAction action, ISelection selection) {
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/java.gif b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/java.gif
new file mode 100644 (file)
index 0000000..83de817
Binary files /dev/null and b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/java.gif differ
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCodeScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCodeScanner.java
new file mode 100644 (file)
index 0000000..64501fd
--- /dev/null
@@ -0,0 +1,195 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.util.HTMLWordDetector;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * A HTML code scanner.
+ */
+public class HTMLCodeScanner extends AbstractJavaScanner {
+
+       // private static String[] fgKeywords = {
+       // };
+       //
+       // private static String[] fgTypes = {
+       // };
+
+       // private IToken keyword;
+       private static String[] fgTokenProperties = {
+                       IPreferenceConstants.PHP_MULTILINE_COMMENT,
+                       IPreferenceConstants.PHP_SINGLELINE_COMMENT,
+                       IPreferenceConstants.PHP_TAG, IPreferenceConstants.PHP_KEYWORD,
+                       IPreferenceConstants.PHP_FUNCTIONNAME,
+                       IPreferenceConstants.PHP_VARIABLE,
+                       IPreferenceConstants.PHP_VARIABLE_DOLLAR,
+                       IPreferenceConstants.PHP_STRING_DQ,
+                       IPreferenceConstants.PHP_STRING_SQ, IPreferenceConstants.PHP_TYPE,
+                       IPreferenceConstants.PHP_CONSTANT,
+                       IPreferenceConstants.PHP_DEFAULT,
+                       IPreferenceConstants.PHP_OPERATOR,
+                       IPreferenceConstants.PHP_BRACE_OPERATOR,
+                       IPreferenceConstants.PHP_KEYWORD_RETURN };
+
+       /*
+        * @see AbstractJavaScanner#getTokenProperties()
+        */
+       protected String[] getTokenProperties() {
+               return fgTokenProperties;
+       }
+
+       private class HTMLWordRule extends WordRule {
+               private StringBuffer fBuffer = new StringBuffer();
+
+               public HTMLWordRule(IWordDetector detector) {
+                       super(detector, Token.UNDEFINED);
+               }
+
+               public HTMLWordRule(IWordDetector detector, IToken defaultToken) {
+                       super(detector, defaultToken);
+               }
+
+               public IToken evaluate(ICharacterScanner scanner) {
+                       int c = scanner.read();
+                       boolean tagBegin = false;
+                       if (fDetector.isWordStart((char) c)) {
+                               if (c == '<') {
+                                       tagBegin = true;
+                               }
+                               if (fColumn == UNDEFINED
+                                               || (fColumn == scanner.getColumn() - 1)) {
+
+                                       fBuffer.setLength(0);
+                                       do {
+                                               fBuffer.append((char) c);
+                                               c = scanner.read();
+                                               if (c == '>') {
+                                                       fBuffer.append((char) c);
+                                                       c = scanner.read();
+                                                       break;
+                                               }
+                                               if (c == '/' && (fBuffer.length() > 2)) {
+                                                       break;
+                                               }
+                                       } while (c != ICharacterScanner.EOF
+                                                       && fDetector.isWordPart((char) c));
+                                       scanner.unread();
+
+                                       if (tagBegin) {
+                                               return getToken(IPreferenceConstants.PHP_KEYWORD);
+                                       }
+                                       IToken token = (IToken) fWords.get(fBuffer.toString());
+                                       if (token != null)
+                                               return token;
+
+                                       if (fDefaultToken.isUndefined())
+                                               unreadBuffer(scanner);
+
+                                       return fDefaultToken;
+                               }
+                       }
+
+                       scanner.unread();
+                       return Token.UNDEFINED;
+               }
+
+       }
+
+       // private static String[] fgConstants = { "__LINE__", "__FILE__", "true",
+       // "false" };
+       private TextAttribute fComment;
+
+       private TextAttribute fKeyword;
+
+       private TextAttribute fType;
+
+       private TextAttribute fString;
+
+       private PHPColorProvider fColorProvider;
+
+       /**
+        * Creates a Java code scanner
+        */
+       public HTMLCodeScanner(IColorManager manager, IPreferenceStore store) {
+               super(manager, store);
+               initialize();
+       }
+
+       /*
+        * @see AbstractJavaScanner#createRules()
+        */
+       protected List createRules() {
+               List rules = new ArrayList();
+
+               // keyword = new Token(new
+               // TextAttribute(provider.getColor(PHPColorProvider.KEYWORD)));
+               // IToken type = new Token(new
+               // TextAttribute(provider.getColor(PHPColorProvider.FUNCTION_NAME)));
+               // IToken string = new Token(new
+               // TextAttribute(provider.getColor(PHPColorProvider.STRING_DQ)));
+               // IToken comment = new Token(new
+               // TextAttribute(provider.getColor(PHPColorProvider.SINGLE_LINE_COMMENT)));
+               // IToken multi_comment = new Token(new
+               // TextAttribute(provider.getColor(PHPColorProvider.MULTI_LINE_COMMENT)));
+               // IToken other = new Token(new
+               // TextAttribute(provider.getColor(PHPColorProvider.DEFAULT)));
+
+               // variable = new Token(new
+               // TextAttribute(provider.getColor(PHPColorProvider.VARIABLE)));
+
+               // Add rule for single line comments.
+               // rules.add(new EndOfLineRule("//", comment)); //$NON-NLS-1$
+               // rules.add(new EndOfLineRule("#", comment));
+
+               // Add rule for strings and character constants.
+               rules.add(new SingleLineRule(
+                               "\"", "\"", getToken(IPreferenceConstants.PHP_STRING_DQ))); //$NON-NLS-2$ //$NON-NLS-1$
+               // rules.add(new SingleLineRule("'", "'", string, '\\')); //$NON-NLS-2$
+               // //$NON-NLS-1$
+
+               // rules.add(new SingleLineRule("//", "//", php_comment));
+               // rules.add(new MultiLineRule("/*", "*/", multi_comment));
+
+               // Add generic whitespace rule.
+               rules.add(new WhitespaceRule(new PHPWhitespaceDetector()));
+
+               // Add word rule for keywords, types, and constants.
+               HTMLWordRule wordRule = new HTMLWordRule(new HTMLWordDetector(),
+                               getToken(IPreferenceConstants.PHP_DEFAULT));
+               // for (int i = 0; i < fgKeywords.length; i++)
+               // wordRule.addWord(fgKeywords[i], keyword);
+               // for (int i = 0; i < fgTypes.length; i++)
+               // wordRule.addWord(fgTypes[i], type);
+               rules.add(wordRule);
+
+               setDefaultReturnToken(getToken(IPreferenceConstants.PHP_DEFAULT));
+               return rules;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCompletionProcessor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCompletionProcessor.java
new file mode 100644 (file)
index 0000000..ac0a364
--- /dev/null
@@ -0,0 +1,309 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpdt.internal.ui.text.java.PHPCompletionProposalComparator;
+import net.sourceforge.phpdt.internal.ui.text.template.contentassist.TemplateEngine;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextPresentation;
+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.IContextInformationExtension;
+import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * HTML completion processor.
+ */
+public class HTMLCompletionProcessor implements IContentAssistProcessor {
+
+       /**
+        * Simple content assist tip closer. The tip is valid in a range of 5
+        * characters around its popup location.
+        */
+       protected static class Validator implements IContextInformationValidator,
+                       IContextInformationPresenter {
+
+               protected int fInstallOffset;
+
+               /*
+                * @see IContextInformationValidator#isContextInformationValid(int)
+                */
+               public boolean isContextInformationValid(int offset) {
+                       return Math.abs(fInstallOffset - offset) < 5;
+               }
+
+               /*
+                * @see IContextInformationValidator#install(IContextInformation,
+                *      ITextViewer, int)
+                */
+               public void install(IContextInformation info, ITextViewer viewer,
+                               int offset) {
+                       fInstallOffset = offset;
+               }
+
+               /*
+                * @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int,
+                *      TextPresentation)
+                */
+               public boolean updatePresentation(int documentPosition,
+                               TextPresentation presentation) {
+                       return false;
+               }
+       };
+
+       private static class ContextInformationWrapper implements
+                       IContextInformation, IContextInformationExtension {
+
+               private final IContextInformation fContextInformation;
+
+               private int fPosition;
+
+               public ContextInformationWrapper(IContextInformation contextInformation) {
+                       fContextInformation = contextInformation;
+               }
+
+               /*
+                * @see IContextInformation#getContextDisplayString()
+                */
+               public String getContextDisplayString() {
+                       return fContextInformation.getContextDisplayString();
+               }
+
+               /*
+                * @see IContextInformation#getImage()
+                */
+               public Image getImage() {
+                       return fContextInformation.getImage();
+               }
+
+               /*
+                * @see IContextInformation#getInformationDisplayString()
+                */
+               public String getInformationDisplayString() {
+                       return fContextInformation.getInformationDisplayString();
+               }
+
+               /*
+                * @see IContextInformationExtension#getContextInformationPosition()
+                */
+               public int getContextInformationPosition() {
+                       return fPosition;
+               }
+
+               public void setContextInformationPosition(int position) {
+                       fPosition = position;
+               }
+       };
+
+       protected IContextInformationValidator fValidator = new Validator();
+
+       private TemplateEngine fTemplateEngine;
+
+       private char[] fProposalAutoActivationSet;
+
+       private PHPCompletionProposalComparator fComparator;
+
+       private int fNumberOfComputedResults = 0;
+
+       private IEditorPart fEditor;
+
+       protected IWorkingCopyManager fManager;
+
+       public HTMLCompletionProcessor(IEditorPart editor) {
+               fEditor = editor;
+               fManager = WebUI.getDefault().getWorkingCopyManager();
+
+               TemplateContextType contextType = WebUI.getDefault()
+                               .getTemplateContextRegistry().getContextType("html"); //$NON-NLS-1$
+               if (contextType != null)
+                       fTemplateEngine = new TemplateEngine(contextType);
+
+               fComparator = new PHPCompletionProposalComparator();
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
+                       int documentOffset) {
+               int contextInformationPosition = guessContextInformationPosition(
+                               viewer, documentOffset);
+               return internalComputeCompletionProposals(viewer, documentOffset,
+                               contextInformationPosition);
+       }
+
+       private ICompletionProposal[] internalComputeCompletionProposals(
+                       ITextViewer viewer, int offset, int contextOffset) {
+               IDocument document = viewer.getDocument();
+               ICompilationUnit unit = fManager.getWorkingCopy(fEditor
+                               .getEditorInput());
+
+               if (fTemplateEngine != null) {
+                       ICompletionProposal[] results;
+                       // try {
+                       fTemplateEngine.reset();
+                       fTemplateEngine.complete(viewer, offset, unit);
+                       // } catch (JavaModelException x) {
+                       // Shell shell= viewer.getTextWidget().getShell();
+                       // ErrorDialog.openError(shell,
+                       // JavaTextMessages.getString("CompletionProcessor.error.accessing.title"),
+                       // JavaTextMessages.getString("CompletionProcessor.error.accessing.message"),
+                       // x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$
+                       // }
+
+                       IPHPCompletionProposal[] templateResults = fTemplateEngine
+                                       .getResults();
+
+                       // concatenate arrays
+                       IPHPCompletionProposal[] total;
+                       total = new IPHPCompletionProposal[templateResults.length];
+                       System.arraycopy(templateResults, 0, total, 0,
+                                       templateResults.length);
+                       results = total;
+
+                       fNumberOfComputedResults = (results == null ? 0 : results.length);
+                       /*
+                        * Order here and not in result collector to make sure that the
+                        * order applies to all proposals and not just those of the
+                        * compilation unit.
+                        */
+                       return order(results);
+               }
+               return new IPHPCompletionProposal[0];
+       }
+
+       private int guessContextInformationPosition(ITextViewer viewer, int offset) {
+               int contextPosition = offset;
+               IDocument document = viewer.getDocument();
+               return contextPosition;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       // public IContextInformation[] computeContextInformation(ITextViewer
+       // viewer, int documentOffset) {
+       // IContextInformation[] result = new IContextInformation[5];
+       // for (int i = 0; i < result.length; i++)
+       // result[i] = new
+       // ContextInformation(MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"),
+       // new Object[] { new Integer(i), new Integer(documentOffset)}),
+       // //$NON-NLS-1$
+       // MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"),
+       // new Object[] { new Integer(i), new Integer(documentOffset - 5), new
+       // Integer(documentOffset + 5)})); //$NON-NLS-1$
+       // return result;
+       // }
+       /**
+        * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+        */
+       public IContextInformation[] computeContextInformation(ITextViewer viewer,
+                       int offset) {
+               int contextInformationPosition = guessContextInformationPosition(
+                               viewer, offset);
+               List result = addContextInformations(viewer, contextInformationPosition);
+               return (IContextInformation[]) result
+                               .toArray(new IContextInformation[result.size()]);
+       }
+
+       private List addContextInformations(ITextViewer viewer, int offset) {
+               ICompletionProposal[] proposals = internalComputeCompletionProposals(
+                               viewer, offset, -1);
+
+               List result = new ArrayList();
+               for (int i = 0; i < proposals.length; i++) {
+                       IContextInformation contextInformation = proposals[i]
+                                       .getContextInformation();
+                       if (contextInformation != null) {
+                               ContextInformationWrapper wrapper = new ContextInformationWrapper(
+                                               contextInformation);
+                               wrapper.setContextInformationPosition(offset);
+                               result.add(wrapper);
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * Order the given proposals.
+        */
+       private ICompletionProposal[] order(ICompletionProposal[] proposals) {
+               Arrays.sort(proposals, fComparator);
+               return proposals;
+       }
+
+       /**
+        * Tells this processor to order the proposals alphabetically.
+        * 
+        * @param order
+        *            <code>true</code> if proposals should be ordered.
+        */
+       public void orderProposalsAlphabetically(boolean order) {
+               fComparator.setOrderAlphabetically(order);
+       }
+
+       /**
+        * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+        */
+       public char[] getCompletionProposalAutoActivationCharacters() {
+               return fProposalAutoActivationSet;
+       }
+
+       /**
+        * Sets this processor's set of characters triggering the activation of the
+        * completion proposal computation.
+        * 
+        * @param activationSet
+        *            the activation set
+        */
+       public void setCompletionProposalAutoActivationCharacters(
+                       char[] activationSet) {
+               fProposalAutoActivationSet = activationSet;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public char[] getContextInformationAutoActivationCharacters() {
+               return new char[] {};
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public IContextInformationValidator getContextInformationValidator() {
+               return fValidator;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public String getErrorMessage() {
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java
new file mode 100644 (file)
index 0000000..eab265e
--- /dev/null
@@ -0,0 +1,472 @@
+/**
+ * This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * Created on 05.03.2003
+ *
+ * @author Stefan Langer (musk)
+ * @version $Revision: 1.3 $
+ */
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * 
+ */
+public class HTMLPartitionScanner implements IPartitionTokenScanner {
+       private static final boolean DEBUG = false;
+
+       private boolean fInString = false;
+
+       private boolean fInDoubString = false;
+
+       private IDocument fDocument = null;
+
+       private int fOffset = -1;
+
+       private String fContentType = IPHPPartitions.HTML;
+
+       private String fPrevContentType = IPHPPartitions.HTML;
+
+       private boolean partitionBorder = false;
+
+       private int fTokenOffset;
+
+       private int fEnd = -1;
+
+       private int fLength;
+
+       private int fCurrentLength;
+
+       private int fFileType;
+
+       private Map tokens = new HashMap();
+
+       public HTMLPartitionScanner() {
+               this(IPHPPartitions.PHP_FILE);
+       }
+
+       public HTMLPartitionScanner(int fileType) {
+               this.tokens.put(IPHPPartitions.HTML, new Token(IPHPPartitions.HTML));
+               this.tokens.put(IPHPPartitions.HTML_MULTILINE_COMMENT, new Token(
+                               IPHPPartitions.HTML_MULTILINE_COMMENT));
+
+               this.tokens
+                               .put(IPHPPartitions.SMARTY, new Token(IPHPPartitions.SMARTY));
+               this.tokens.put(IPHPPartitions.SMARTY_MULTILINE_COMMENT, new Token(
+                               IPHPPartitions.SMARTY_MULTILINE_COMMENT));
+
+               this.tokens.put(IDocument.DEFAULT_CONTENT_TYPE, new Token(
+                               IDocument.DEFAULT_CONTENT_TYPE));
+               fFileType = fileType;
+       }
+
+       private IToken getToken(String type) {
+               fLength = fCurrentLength;
+               if (DEBUG) {
+
+                       try {
+                               if (fLength <= 0) {
+                                       int line = fDocument.getLineOfOffset(fOffset);
+                                       System.err.println("Error at "
+                                                       + line
+                                                       + " offset:"
+                                                       + String.valueOf(fOffset
+                                                                       - fDocument.getLineOffset(line)));
+                               }
+                       } catch (BadLocationException e) { // should never happen
+                               // TODO Write stacktrace to log
+                               e.printStackTrace();
+                       }
+               }
+               Assert.isTrue(fLength > 0, "Partition length <= 0!");
+               fCurrentLength = 0;
+               // String can never cross partition borders so reset string detection
+               fInString = false;
+               fInDoubString = false;
+               IToken token = (IToken) this.tokens.get(type);
+               Assert.isNotNull(token, "Token for type \"" + type + "\" not found!");
+               if (DEBUG) {
+                       System.out.println("Partition: fTokenOffset=" + fTokenOffset
+                                       + " fContentType=" + type + " fLength=" + fLength);
+               }
+               return token;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.text.rules.IPartitionTokenScanner#setPartialRange(org.eclipse.jface.text.IDocument,
+        *      int, int, java.lang.String, int)
+        */
+       public void setPartialRange(IDocument document, int offset, int length,
+                       String contentType, int partitionOffset) {
+               if (DEBUG) {
+                       System.out.println("*****");
+                       System.out.println("PartialRange: contentType=" + contentType
+                                       + " partitionOffset=" + partitionOffset);
+               }
+
+               try {
+                       if (partitionOffset > -1) {
+                               partitionBorder = false;
+                               // because of strings we have to parse the whole partition
+                               this.setRange(document, partitionOffset, offset
+                                               - partitionOffset + length);
+                               // sometimes we get a wrong partition so we retrieve the
+                               // partition
+                               // directly from the document
+                               fContentType = fDocument.getContentType(partitionOffset);
+                       } else
+                               this.setRange(document, offset, length);
+
+               } catch (BadLocationException e) {
+                       // should never happen
+                       // TODO print stack trace to log
+                       // fall back just scan the whole document again
+                       this.setRange(document, 0, fDocument.getLength());
+               }
+
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
+        */
+       public int getTokenLength() {
+               return fLength;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
+        */
+       public int getTokenOffset() {
+               return fTokenOffset;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+        */
+       public IToken nextToken() {
+               int c;
+
+               // check if we are not allready at the end of the
+               // file
+               if ((c = read()) == ICharacterScanner.EOF) {
+                       partitionBorder = false;
+                       return Token.EOF;
+               } else
+                       unread();
+
+               if (partitionBorder) {
+                       fTokenOffset = fOffset;
+                       partitionBorder = false;
+               }
+
+               while ((c = read()) != ICharacterScanner.EOF) {
+                       switch (c) {
+                       case '<':
+                               if (checkPattern(new char[] { '!', '-', '-' })) { // return
+                                                                                                                                       // previouse
+                                                                                                                                       // partition
+                                       if (fContentType != IPHPPartitions.HTML_MULTILINE_COMMENT
+                                                       && fCurrentLength > 4) {
+                                               unread(4);
+                                               IToken token = getToken(fContentType);
+                                               fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT;
+                                               return token;
+                                       } else
+                                               fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT;
+
+                                       fTokenOffset = fOffset - 4;
+                                       fCurrentLength = 4;
+                               }
+                               break;
+                       case '-':
+                               if (fContentType == IPHPPartitions.HTML_MULTILINE_COMMENT
+                                               && checkPattern(new char[] { '-', '>' })) {
+                                       fContentType = IPHPPartitions.HTML;
+                                       partitionBorder = true;
+                                       return getToken(IPHPPartitions.HTML_MULTILINE_COMMENT);
+                               }
+                               break;
+                       case '{': // SMARTY code starts here ?
+                               if (fFileType == IPHPPartitions.SMARTY_FILE) {
+                                       if ((c = read()) == '*') {
+                                               if (DEBUG) {
+                                                       System.out.println("SMARTYDOC_TOKEN start "
+                                                                       + fTokenOffset + " fContentType="
+                                                                       + fContentType + " fLength=" + fLength
+                                                                       + " fOffset=" + fOffset
+                                                                       + " fCurrentLength=" + fCurrentLength);
+                                               }
+                                               if (fContentType != IPHPPartitions.SMARTY_MULTILINE_COMMENT
+                                                               && fCurrentLength > 2) {
+                                                       // SMARTY doc code starts here
+                                                       unread(2);
+                                                       IToken token = getToken(fContentType);
+                                                       fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT;
+                                                       return token;
+                                                       // } else if (fContentType ==
+                                                       // IPHPPartitionScannerConstants.HTML && fOffset ==
+                                                       // 2) {
+                                                       // fContentType =
+                                                       // IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT;
+                                               } else { // if (fContentType ==
+                                                                       // IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT)
+                                                                       // {
+                                                       fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT;
+                                                       fTokenOffset = fOffset - 2;
+                                                       fCurrentLength = 2;
+                                               }
+                                               break;
+                                       }
+                                       if (DEBUG) {
+                                               System.out.println("SMARTY_TOKEN start " + fTokenOffset
+                                                               + " fContentType=" + fContentType + " fLength="
+                                                               + fLength + " fOffset=" + fOffset);
+                                       }
+                                       if (c != ICharacterScanner.EOF) {
+                                               unread();
+                                       }
+                                       if (fContentType != IPHPPartitions.SMARTY
+                                                       && fCurrentLength > 1) {
+                                               unread(1);
+                                               IToken token = getToken(fContentType);
+                                               fContentType = IPHPPartitions.SMARTY;
+                                               return token;
+                                               // } else if (fContentType ==
+                                               // IPHPPartitionScannerConstants.HTML && fOffset==1) {
+                                               // fContentType = IPHPPartitionScannerConstants.SMARTY;
+                                       } else {
+                                               fContentType = IPHPPartitions.SMARTY;
+                                               fTokenOffset = fOffset - 1;
+                                               fCurrentLength = 1;
+                                       }
+                               }
+                               break;
+                       case '}': // SMARTY code ends here ?
+                               if (fFileType == IPHPPartitions.SMARTY_FILE
+                                               && fContentType == IPHPPartitions.SMARTY) {
+                                       if (DEBUG) {
+                                               System.out.println("SMARTY_TOKEN end " + fTokenOffset
+                                                               + " fContentType=" + fContentType + " fLength="
+                                                               + fLength + " fOffset=" + fOffset);
+                                       }
+                                       fContentType = IPHPPartitions.HTML;
+                                       partitionBorder = true;
+                                       return getToken(IPHPPartitions.SMARTY);
+                               }
+                               break;
+                       // case '/' :
+                       // if (!isInString(IPHPPartitions.PHP_PARTITIONING) && (c = read())
+                       // == '*') { // MULTINE COMMENT JAVASCRIPT, CSS, PHP
+                       // if (fContentType == IPHPPartitions.PHP_PARTITIONING &&
+                       // fCurrentLength > 2) {
+                       // unread(2);
+                       // IToken token = getToken(fContentType);
+                       // fContentType = IPHPPartitions.PHP_PHPDOC_COMMENT;
+                       // return token;
+                       // } else if (fContentType == IPHPPartitions.PHP_PHPDOC_COMMENT) {
+                       // fTokenOffset = fOffset - 2;
+                       // fCurrentLength = 2;
+                       // }
+                       //
+                       // } else if (!isInString(IPHPPartitions.PHP_PARTITIONING) && c !=
+                       // ICharacterScanner.EOF)
+                       // unread();
+                       // break;
+                       case '*':
+                               if (fFileType == IPHPPartitions.SMARTY_FILE
+                                               && (c = read()) == '}') {
+                                       if (DEBUG) {
+                                               System.out.println("SMARTYDOC_TOKEN end "
+                                                               + fTokenOffset + " fContentType="
+                                                               + fContentType + " fLength=" + fLength
+                                                               + " fOffset=" + fOffset);
+                                       }
+                                       if (fContentType == IPHPPartitions.SMARTY_MULTILINE_COMMENT) {
+                                               fContentType = IPHPPartitions.HTML;
+                                               partitionBorder = true;
+                                               return getToken(IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+                                       }
+                               }
+                               break;
+                       case '\'':
+                               if (!fInDoubString)
+                                       fInString = !fInString;
+                               break;
+                       case '"':
+                               // toggle String mode
+                               if (!fInString)
+                                       fInDoubString = !fInDoubString;
+                               break;
+                       }
+               } // end of file reached but we have to return the
+               // last partition.
+               return getToken(fContentType);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(org.eclipse.jface.text.IDocument,
+        *      int, int)
+        */
+       public void setRange(IDocument document, int offset, int length) {
+               if (DEBUG) {
+                       System.out.println("SET RANGE: offset=" + offset + " length="
+                                       + length);
+               }
+
+               fDocument = document;
+               fOffset = offset;
+               fTokenOffset = offset;
+               fCurrentLength = 0;
+               fLength = 0;
+               fEnd = fOffset + length;
+               fInString = false;
+               fInDoubString = false;
+               fContentType = IPHPPartitions.HTML;
+               // String[] prev = getPartitionStack(offset);
+       }
+
+       private int read() {
+               try {
+                       if (fOffset < fEnd) {
+                               fCurrentLength++;
+                               return fDocument.getChar(fOffset++);
+                       }
+                       return ICharacterScanner.EOF;
+               } catch (BadLocationException e) {
+                       // should never happen
+                       // TODO write stacktrace to log
+                       fOffset = fEnd;
+                       return ICharacterScanner.EOF;
+               }
+       }
+
+       private void unread() {
+               --fOffset;
+               --fCurrentLength;
+       }
+
+       private void unread(int num) {
+               fOffset -= num;
+               fCurrentLength -= num;
+       }
+
+       private boolean checkPattern(char[] pattern) {
+               return checkPattern(pattern, false);
+       }
+
+       /**
+        * Check if next character sequence read from document is equals to the
+        * provided pattern. Pattern is read from left to right until the first
+        * character read doesn't match. If this happens all read characters are
+        * unread.
+        * 
+        * @param pattern
+        *            The pattern to check.
+        * @return <code>true</code> if pattern is equals else returns
+        *         <code>false</code>.
+        */
+       private boolean checkPattern(char[] pattern, boolean ignoreCase) {
+               int prevOffset = fOffset;
+               int prevLength = fCurrentLength;
+               for (int i = 0; i < pattern.length; i++) {
+                       int c = read();
+
+                       if (c == ICharacterScanner.EOF
+                                       || !letterEquals(c, pattern[i], ignoreCase)) {
+                               fOffset = prevOffset;
+                               fCurrentLength = prevLength;
+                               return false;
+                       }
+               }
+
+               return true;
+       }
+
+       private boolean letterEquals(int test, char letter, boolean ignoreCase) {
+               if (test == letter)
+                       return true;
+               else if (ignoreCase && Character.isLowerCase(letter)
+                               && test == Character.toUpperCase(letter))
+                       return true;
+               else if (ignoreCase && Character.isUpperCase(letter)
+                               && test == Character.toLowerCase(letter))
+                       return true;
+
+               return false;
+       }
+
+       /**
+        * Checks wether the offset is in a <code>String</code> and the specified
+        * contenttype is the current content type. Strings are delimited, mutual
+        * exclusive, by a " or by a '.
+        * 
+        * @param contentType
+        *            The contenttype to check.
+        * @return <code>true</code> if the current offset is in a string else
+        *         returns false.
+        */
+       private boolean isInString(String contentType) {
+               if (fContentType == contentType)
+                       return (fInString || fInDoubString);
+               else
+                       return false;
+       }
+
+       /**
+        * Returns the previouse partition stack for the given offset.
+        * 
+        * @param offset
+        *            The offset to return the previouse partitionstack for.
+        * 
+        * @return The stack as a string array.
+        */
+       private String[] getPartitionStack(int offset) {
+               ArrayList types = new ArrayList();
+               int tmpOffset = 0;
+               try {
+                       ITypedRegion region = fDocument.getPartition(offset);
+                       tmpOffset = region.getOffset();
+                       while (tmpOffset - 1 > 0) {
+                               region = fDocument.getPartition(tmpOffset - 1);
+                               tmpOffset = region.getOffset();
+                               types.add(0, region.getType());
+                       }
+               } catch (BadLocationException e) {
+                       if (DEBUG) {
+                               e.printStackTrace();
+                       }
+               }
+
+               String[] retVal = new String[types.size()];
+
+               retVal = (String[]) types.toArray(retVal);
+               return retVal;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLWordExtractor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLWordExtractor.java
new file mode 100644 (file)
index 0000000..9968341
--- /dev/null
@@ -0,0 +1,91 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Detects HTML words in documents.
+ */
+public class HTMLWordExtractor {
+
+       /**
+        * Find the location of the word at offset in document.
+        * 
+        * @returns Point - x is the start position, y is the end position. Return
+        *          null if it is not found.
+        * @param document
+        *            the document being searched.
+        * @param offset -
+        *            the position to start searching from.
+        */
+       public static Point findWord(IDocument document, int offset) {
+
+               int start = -1;
+               int end = -1;
+
+               try {
+
+                       int position = offset;
+                       char character = ' ';
+
+                       while (position >= 0) {
+                               character = document.getChar(position);
+                               if (!Scanner.isPHPIdentifierPart(character))
+                                       break;
+                               --position;
+                       }
+                       if ((position > 0) && (character == '<')) {
+                               --position;
+                       }
+                       if ((position > 1) && (character == '/')) {
+                               character = document.getChar(position - 1);
+                               if (character == '<') {
+                                       --position;
+                                       --position;
+                               }
+                       }
+                       if (position == offset) {
+                               return null;
+                       }
+
+                       start = position;
+
+                       position = offset;
+                       int length = document.getLength();
+                       character = ' ';
+
+                       while (position < length) {
+                               character = document.getChar(position);
+                               if (!Scanner.isPHPIdentifierPart(character))
+                                       break;
+                               ++position;
+                       }
+                       if ((position < length) && (character == '>')) {
+                               ++position;
+                       }
+                       start++;
+                       end = position;
+
+                       if (end > start)
+                               return new Point(start, end - start);
+
+               } catch (BadLocationException x) {
+               }
+
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPAutoIndentStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPAutoIndentStrategy.java
new file mode 100644 (file)
index 0000000..0283480
--- /dev/null
@@ -0,0 +1,333 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * Auto indent strategy sensitive to brackets.
+ */
+public class PHPAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
+
+       public PHPAutoIndentStrategy() {
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IAutoIndentStrategy
+        */
+       public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
+               if (c.length == 0 && c.text != null && endsWithDelimiter(d, c.text))
+                       smartIndentAfterNewLine(d, c);
+               else if ("}".equals(c.text)) {
+                       smartInsertAfterBracket(d, c);
+               }
+       }
+
+       /**
+        * Returns whether or not the text ends with one of the given search
+        * strings.
+        */
+       private boolean endsWithDelimiter(IDocument d, String txt) {
+
+               String[] delimiters = d.getLegalLineDelimiters();
+
+               for (int i = 0; i < delimiters.length; i++) {
+                       if (txt.endsWith(delimiters[i]))
+                               return true;
+               }
+
+               return false;
+       }
+
+       /**
+        * Returns the line number of the next bracket after end.
+        * 
+        * @returns the line number of the next matching bracket after end
+        * @param document -
+        *            the document being parsed
+        * @param line -
+        *            the line to start searching back from
+        * @param end -
+        *            the end position to search back from
+        * @param closingBracketIncrease -
+        *            the number of brackets to skip
+        */
+       protected int findMatchingOpenBracket(IDocument document, int line,
+                       int end, int closingBracketIncrease) throws BadLocationException {
+
+               int start = document.getLineOffset(line);
+               int brackcount = getBracketCount(document, start, end, false)
+                               - closingBracketIncrease;
+
+               // sum up the brackets counts of each line (closing brackets count
+               // negative,
+               // opening positive) until we find a line the brings the count to zero
+               while (brackcount < 0) {
+                       line--;
+                       if (line < 0) {
+                               return -1;
+                       }
+                       start = document.getLineOffset(line);
+                       end = start + document.getLineLength(line) - 1;
+                       brackcount += getBracketCount(document, start, end, false);
+               }
+               return line;
+       }
+
+       /**
+        * Returns the bracket value of a section of text. Closing brackets have a
+        * value of -1 and open brackets have a value of 1.
+        * 
+        * @returns the line number of the next matching bracket after end
+        * @param document -
+        *            the document being parsed
+        * @param start -
+        *            the start position for the search
+        * @param end -
+        *            the end position for the search
+        * @param ignoreCloseBrackets -
+        *            whether or not to ignore closing brackets in the count
+        */
+       private int getBracketCount(IDocument document, int start, int end,
+                       boolean ignoreCloseBrackets) throws BadLocationException {
+
+               int begin = start;
+               int bracketcount = 0;
+               while (begin < end) {
+                       char curr = document.getChar(begin);
+                       begin++;
+                       switch (curr) {
+                       case '/':
+                               if (begin < end) {
+                                       char next = document.getChar(begin);
+                                       if (next == '*') {
+                                               // a comment starts, advance to the comment end
+                                               begin = getCommentEnd(document, begin + 1, end);
+                                       } else if (next == '/') {
+                                               // '//'-comment: nothing to do anymore on this line
+                                               begin = end;
+                                       }
+                               }
+                               break;
+                       case '*':
+                               if (begin < end) {
+                                       char next = document.getChar(begin);
+                                       if (next == '/') {
+                                               // we have been in a comment: forget what we read before
+                                               bracketcount = 0;
+                                               begin++;
+                                       }
+                               }
+                               break;
+                       case '{':
+                               bracketcount++;
+                               ignoreCloseBrackets = false;
+                               break;
+                       case '}':
+                               if (!ignoreCloseBrackets) {
+                                       bracketcount--;
+                               }
+                               break;
+                       case '"':
+                       case '\'':
+                               begin = getStringEnd(document, begin, end, curr);
+                               break;
+                       default:
+                       }
+               }
+               return bracketcount;
+       }
+
+       /**
+        * Returns the end position a comment starting at pos.
+        * 
+        * @returns the end position a comment starting at pos
+        * @param document -
+        *            the document being parsed
+        * @param position -
+        *            the start position for the search
+        * @param end -
+        *            the end position for the search
+        */
+       private int getCommentEnd(IDocument document, int position, int end)
+                       throws BadLocationException {
+               int currentPosition = position;
+               while (currentPosition < end) {
+                       char curr = document.getChar(currentPosition);
+                       currentPosition++;
+                       if (curr == '*') {
+                               if (currentPosition < end
+                                               && document.getChar(currentPosition) == '/') {
+                                       return currentPosition + 1;
+                               }
+                       }
+               }
+               return end;
+       }
+
+       /**
+        * Returns the String at line with the leading whitespace removed.
+        * 
+        * @returns the String at line with the leading whitespace removed.
+        * @param document -
+        *            the document being parsed
+        * @param line -
+        *            the line being searched
+        */
+       protected String getIndentOfLine(IDocument document, int line)
+                       throws BadLocationException {
+               if (line > -1) {
+                       int start = document.getLineOffset(line);
+                       int end = start + document.getLineLength(line) - 1;
+                       int whiteend = findEndOfWhiteSpace(document, start, end);
+                       return document.get(start, whiteend - start);
+               } else {
+                       return ""; //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Returns the position of the character in the document after position.
+        * 
+        * @returns the next location of character.
+        * @param document -
+        *            the document being parsed
+        * @param position -
+        *            the position to start searching from
+        * @param end -
+        *            the end of the document
+        * @param character -
+        *            the character you are trying to match
+        */
+       private int getStringEnd(IDocument document, int position, int end,
+                       char character) throws BadLocationException {
+               int currentPosition = position;
+               while (currentPosition < end) {
+                       char currentCharacter = document.getChar(currentPosition);
+                       currentPosition++;
+                       if (currentCharacter == '\\') {
+                               // ignore escaped characters
+                               currentPosition++;
+                       } else if (currentCharacter == character) {
+                               return currentPosition;
+                       }
+               }
+               return end;
+       }
+
+       /**
+        * Set the indent of a new line based on the command provided in the
+        * supplied document.
+        * 
+        * @param document -
+        *            the document being parsed
+        * @param command -
+        *            the command being performed
+        */
+       protected void smartIndentAfterNewLine(IDocument document,
+                       DocumentCommand command) {
+
+               int docLength = document.getLength();
+               if (command.offset == -1 || docLength == 0)
+                       return;
+
+               try {
+                       int p = (command.offset == docLength ? command.offset - 1
+                                       : command.offset);
+                       int line = document.getLineOfOffset(p);
+
+                       StringBuffer buf = new StringBuffer(command.text);
+                       if (command.offset < docLength
+                                       && document.getChar(command.offset) == '}') {
+                               int indLine = findMatchingOpenBracket(document, line,
+                                               command.offset, 0);
+                               if (indLine == -1) {
+                                       indLine = line;
+                               }
+                               buf.append(getIndentOfLine(document, indLine));
+                       } else {
+                               int start = document.getLineOffset(line);
+                               int whiteend = findEndOfWhiteSpace(document, start,
+                                               command.offset);
+                               int offset = -1;
+                               // if (command.offset > 0 && command.offset < docLength &&
+                               // document.getChar(command.offset-1) == '{') {
+                               // offset = command.offset;
+                               // }
+                               buf.append(document.get(start, whiteend - start));
+                               if (getBracketCount(document, start, command.offset, true) > 0) {
+                                       buf.append('\t');
+                               }
+                               // if (offset >= 0) {
+                               // buf.append('}');
+                               // }
+                       }
+                       command.text = buf.toString();
+
+               } catch (BadLocationException excp) {
+                       System.out.println(PHPEditorMessages
+                                       .getString("AutoIndent.error.bad_location_1")); //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Set the indent of a bracket based on the command provided in the supplied
+        * document.
+        * 
+        * @param document -
+        *            the document being parsed
+        * @param command -
+        *            the command being performed
+        */
+       protected void smartInsertAfterBracket(IDocument document,
+                       DocumentCommand command) {
+               if (command.offset == -1 || document.getLength() == 0)
+                       return;
+
+               try {
+                       int p = (command.offset == document.getLength() ? command.offset - 1
+                                       : command.offset);
+                       int line = document.getLineOfOffset(p);
+                       int start = document.getLineOffset(line);
+                       int whiteend = findEndOfWhiteSpace(document, start, command.offset);
+
+                       // shift only when line does not contain any text up to the closing
+                       // bracket
+                       if (whiteend == command.offset) {
+                               // evaluate the line with the opening bracket that matches out
+                               // closing bracket
+                               int indLine = findMatchingOpenBracket(document, line,
+                                               command.offset, 1);
+                               if (indLine != -1 && indLine != line) {
+                                       // take the indent of the found line
+                                       StringBuffer replaceText = new StringBuffer(
+                                                       getIndentOfLine(document, indLine));
+                                       // add the rest of the current line including the just added
+                                       // close bracket
+                                       replaceText.append(document.get(whiteend, command.offset
+                                                       - whiteend));
+                                       replaceText.append(command.text);
+                                       // modify document command
+                                       command.length = command.offset - start;
+                                       command.offset = start;
+                                       command.text = replaceText.toString();
+                               }
+                       }
+               } catch (BadLocationException excp) {
+                       System.out.println(PHPEditorMessages
+                                       .getString("AutoIndent.error.bad_location_2")); //$NON-NLS-1$
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java
new file mode 100644 (file)
index 0000000..410e0c1
--- /dev/null
@@ -0,0 +1,477 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWordDetector;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * PHP Code Scanner
+ */
+public class PHPCodeScanner extends AbstractJavaScanner {
+
+       /**
+        * Rule to detect java operators.
+        * 
+        * @since 3.0
+        */
+       protected class OperatorRule implements IRule {
+
+               /** Java operators */
+               private final char[] PHP_OPERATORS = { ';', '(', ')', '.', '=', '/',
+                               '\\', '+', '-', '*', '[', ']', '<', '>', ':', '?', '!', ',',
+                               '|', '&', '^', '%', '~', '@' };
+
+               /** Token to return for this rule */
+               private final IToken fToken;
+
+               /** Token to return for braces */
+               private final IToken fTokenBraces;
+
+               /** Token to return for heredocs */
+               private final IToken fTokenHeredoc;
+
+               /**
+                * Creates a new operator rule.
+                * 
+                * @param token
+                *            Token to use for this rule
+                * @param tokenHeredoc
+                *            TODO
+                */
+               public OperatorRule(IToken token, IToken tokenBraces,
+                               IToken tokenHeredoc) {
+                       fToken = token;
+                       fTokenBraces = tokenBraces;
+                       fTokenHeredoc = tokenHeredoc;
+               }
+
+               /**
+                * Is this character an operator character?
+                * 
+                * @param character
+                *            Character to determine whether it is an operator character
+                * @return <code>true</code> iff the character is an operator,
+                *         <code>false</code> otherwise.
+                */
+               public boolean isOperator(char character) {
+                       for (int index = 0; index < PHP_OPERATORS.length; index++) {
+                               if (PHP_OPERATORS[index] == character)
+                                       return true;
+                       }
+                       return false;
+               }
+
+               /*
+                * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+                */
+               public IToken evaluate(ICharacterScanner scanner) {
+
+                       int character = scanner.read();
+                       if (character == '{' || character == '}') {
+                               return fTokenBraces;
+                       }
+                       if (isOperator((char) character)) {
+                               int lastCharacter = character;
+                               character = scanner.read();
+                               // the readHEREDOC(scanner) call doesn't work, if we have our
+                               // own partitions for single quoted
+                               // or double quoted strings:
+                               //
+                               // if (lastCharacter == '<' && character == '<') {
+                               // int heredocCharacter = scanner.read();
+                               // if (heredocCharacter == '<') {
+                               // // start of heredoc comment;
+                               // if (readHEREDOC(scanner)) {
+                               // return fTokenHeredoc;
+                               // }
+                               // } else {
+                               // scanner.unread();
+                               // }
+                               // }
+                               if (!isOperator((char) character)) {
+                                       scanner.unread();
+                                       return fToken;
+                               }
+                               if (checkPHPTag(scanner, lastCharacter, character)) {
+                                       return Token.UNDEFINED;
+                               }
+                               do {
+                                       lastCharacter = character;
+                                       character = scanner.read();
+                                       if (checkPHPTag(scanner, lastCharacter, character)) {
+                                               return fToken;
+                                       }
+                                       if (character == ICharacterScanner.EOF) {
+                                               return fToken;
+                                       }
+                               } while (isOperator((char) character));
+                               scanner.unread();
+                               return fToken;
+                       } else {
+                               scanner.unread();
+                               return Token.UNDEFINED;
+                       }
+               }
+
+               // private boolean readHEREDOC(ICharacterScanner scanner) {
+               // // search until heredoc ends
+               // int ch;
+               // StringBuffer buf = new StringBuffer();
+               // char[] heredocIdent;
+               //
+               // ch = scanner.read();
+               // if (!Scanner.isPHPIdentifierStart((char)ch)) {
+               // scanner.unread();
+               // scanner.unread();
+               // return false;
+               // }
+               // while (Scanner.isPHPIdentifierPart((char)ch)) {
+               // buf.append((char)ch);
+               // ch = scanner.read();
+               // }
+               // if (ch==ICharacterScanner.EOF) {
+               // return true;
+               // }
+               // heredocIdent = buf.toString().toCharArray();
+               // while (true) {
+               // ch = scanner.read();
+               // if (ch==ICharacterScanner.EOF) {
+               // return true;
+               // }
+               // if (ch == '\n') { // heredoc could end after a newline
+               // int pos = 0;
+               // while (true) {
+               // if (pos == heredocIdent.length) {
+               // return true;
+               // }
+               // ch = scanner.read(); // ignore escaped character
+               // if (ch != heredocIdent[pos]) {
+               // break;
+               // }
+               // if (ch==ICharacterScanner.EOF) {
+               // return true;
+               // }
+               // pos++;
+               // }
+               // }
+               // }
+               // }
+
+               /**
+                * Check if lastCharacter/character are a PHP start or end token ( &lt;?
+                * ... ?&gt; )
+                * 
+                * @param scanner
+                * @param lastCharacter
+                * @param character
+                * @return
+                */
+               private boolean checkPHPTag(ICharacterScanner scanner,
+                               int lastCharacter, int character) {
+                       if (lastCharacter == '<' && character == '?') {
+                               scanner.unread();
+                               scanner.unread();
+                               return true;
+                       } else if (lastCharacter == '?' && character == '>') {
+                               scanner.unread();
+                               scanner.unread();
+                               return true;
+                       }
+                       return false;
+               }
+       }
+
+       protected class AccentStringRule implements IRule {
+
+               /** Token to return for this rule */
+               private final IToken fToken;
+
+               public AccentStringRule(IToken token) {
+                       fToken = token;
+
+               }
+
+               /*
+                * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+                */
+               public IToken evaluate(ICharacterScanner scanner) {
+
+                       int character = scanner.read();
+
+                       if (character == '`') {
+
+                               while (character != ICharacterScanner.EOF) {
+                                       character = scanner.read();
+                                       if (character == '\\') {
+                                               character = scanner.read();
+                                       } else if (character == '`') {
+                                               return fToken;
+                                       }
+                               }
+                               scanner.unread();
+                               return Token.UNDEFINED;
+                       } else {
+                               scanner.unread();
+                               return Token.UNDEFINED;
+                       }
+               }
+
+       }
+
+       private class PHPWordRule extends WordRule {
+               private StringBuffer fBuffer = new StringBuffer();
+
+               protected Map fWordsIgnoreCase = new HashMap();
+
+               public PHPWordRule(IWordDetector detector) {
+                       super(detector, Token.UNDEFINED);
+               }
+
+               public PHPWordRule(IWordDetector detector, IToken defaultToken) {
+                       super(detector, defaultToken);
+               }
+
+               /**
+                * Adds a word and the token to be returned if it is detected.
+                * 
+                * @param word
+                *            the word this rule will search for, may not be
+                *            <code>null</code>
+                * @param token
+                *            the token to be returned if the word has been found, may
+                *            not be <code>null</code>
+                */
+               public void addWordIgnoreCase(String word, IToken token) {
+                       Assert.isNotNull(word);
+                       Assert.isNotNull(token);
+
+                       fWordsIgnoreCase.put(word, token);
+               }
+
+               public IToken evaluate(ICharacterScanner scanner) {
+                       int c = scanner.read();
+                       boolean isVariable = false;
+                       boolean isUnderscore = false;
+                       String word;
+                       if (c == '<') {
+                               c = scanner.read();
+                               if (c != '?') {
+                                       scanner.unread();
+                                       scanner.unread();
+                                       return Token.UNDEFINED;
+                               } else {
+                                       c = scanner.read();
+                                       if (c == '=') { // <?=
+                                               return getToken(IPreferenceConstants.PHP_TAG);
+                                       }
+                                       if (c != 'p' && c != 'P') {
+                                               scanner.unread();
+                                               return getToken(IPreferenceConstants.PHP_TAG);
+                                       } else {
+                                               c = scanner.read();
+                                               if (c != 'h' && c != 'H') {
+                                                       scanner.unread();
+                                                       scanner.unread();
+                                                       return getToken(IPreferenceConstants.PHP_TAG);
+                                               } else {
+                                                       c = scanner.read();
+                                                       if (c != 'p' && c != 'P') {
+                                                               scanner.unread();
+                                                               scanner.unread();
+                                                               scanner.unread();
+                                                               return getToken(IPreferenceConstants.PHP_TAG);
+                                                       } else {
+                                                               return getToken(IPreferenceConstants.PHP_TAG);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       if (c == '?') {
+                               c = scanner.read();
+                               if (c == '>') {
+                                       return getToken(IPreferenceConstants.PHP_TAG);
+                               }
+                               scanner.unread();
+                               scanner.unread();
+                               return Token.UNDEFINED;
+                       }
+                       if (fDetector.isWordStart((char) c)) {
+                               if (c == '$') {
+                                       isVariable = true;
+                               }
+                               if (fColumn == UNDEFINED
+                                               || (fColumn == scanner.getColumn() - 1)) {
+
+                                       fBuffer.setLength(0);
+                                       fBuffer.append((char) c);
+                                       c = scanner.read();
+                                       if (c == '_') {
+                                               isUnderscore = true;
+                                       }
+                                       while (c != ICharacterScanner.EOF
+                                                       && fDetector.isWordPart((char) c)) {
+                                               fBuffer.append((char) c);
+                                               c = scanner.read();
+                                       }
+                                       scanner.unread();
+
+                                       if (isVariable) {
+                                               if (isUnderscore) {
+                                                       return getToken(IPreferenceConstants.PHP_VARIABLE_DOLLAR);
+                                               }
+                                               return getToken(IPreferenceConstants.PHP_VARIABLE);
+                                       }
+                                       word = fBuffer.toString();
+                                       IToken token = (IToken) fWords.get(word);
+                                       if (token != null)
+                                               return token;
+
+                                       token = (IToken) fWordsIgnoreCase.get(word.toLowerCase());
+                                       if (token != null)
+                                               return token;
+
+                                       if (fDefaultToken.isUndefined())
+                                               unreadBuffer(scanner);
+
+                                       return fDefaultToken;
+                               }
+                       }
+
+                       scanner.unread();
+                       return Token.UNDEFINED;
+               }
+       }
+
+       // private PHPColorProvider fColorProvider;
+
+       private static String[] fgTokenProperties = {
+                       IPreferenceConstants.PHP_MULTILINE_COMMENT,
+                       IPreferenceConstants.PHP_SINGLELINE_COMMENT,
+                       IPreferenceConstants.PHP_TAG, IPreferenceConstants.PHP_KEYWORD,
+                       IPreferenceConstants.PHP_FUNCTIONNAME,
+                       IPreferenceConstants.PHP_VARIABLE,
+                       IPreferenceConstants.PHP_VARIABLE_DOLLAR,
+                       IPreferenceConstants.PHP_STRING_DQ,
+                       IPreferenceConstants.PHP_STRING_SQ, IPreferenceConstants.PHP_TYPE,
+                       IPreferenceConstants.PHP_CONSTANT,
+                       IPreferenceConstants.PHP_DEFAULT,
+                       IPreferenceConstants.PHP_OPERATOR,
+                       IPreferenceConstants.PHP_BRACE_OPERATOR,
+                       IPreferenceConstants.PHP_KEYWORD_RETURN };
+
+       /**
+        * Creates a PHP code scanner
+        */
+       // public PHPCodeScanner(JavaColorManager provider, IPreferenceStore store)
+       // {
+       public PHPCodeScanner(IColorManager manager, IPreferenceStore store) {
+               super(manager, store);
+               initialize();
+       }
+
+       /*
+        * @see AbstractJavaScanner#getTokenProperties()
+        */
+       protected String[] getTokenProperties() {
+               return fgTokenProperties;
+       }
+
+       /*
+        * @see AbstractJavaScanner#createRules()
+        */
+       protected List createRules() {
+               List rules = new ArrayList();
+               Token token = getToken(IPreferenceConstants.PHP_SINGLELINE_COMMENT);
+               // Add rule for single line comments.
+               // rules.add(new EndOfLineRule("//", token)); //$NON-NLS-1$
+               // rules.add(new EndOfLineRule("#", token)); //$NON-NLS-1$
+               // Add rule for strings and character constants.
+               // token = getToken(IPreferenceConstants.PHP_STRING_SQ);
+               // rules.add(new SingleQuoteStringRule(token));
+               // token = getToken(IPreferenceConstants.PHP_STRING_DQ);
+               // rules.add(new DoubleQuoteStringRule(token));
+               rules.add(new AccentStringRule(token));
+
+               token = getToken(IPreferenceConstants.PHP_MULTILINE_COMMENT);
+               rules.add(new MultiLineRule("/*", "*/", token)); //$NON-NLS-2$ //$NON-NLS-1$
+               // Add generic whitespace rule.
+               rules.add(new WhitespaceRule(new PHPWhitespaceDetector()));
+               // Add word rule for keywords, types, and constants.
+               token = getToken(IPreferenceConstants.PHP_DEFAULT);
+               PHPWordRule wordRule = new PHPWordRule(new PHPWordDetector(), token);
+
+               Token keyword = getToken(IPreferenceConstants.PHP_KEYWORD);
+               Token functionName = getToken(IPreferenceConstants.PHP_FUNCTIONNAME);
+               Token type = getToken(IPreferenceConstants.PHP_TYPE);
+               Token constant = getToken(IPreferenceConstants.PHP_CONSTANT);
+
+               ArrayList buffer = PHPSyntaxRdr.getSyntaxData();
+               // String strbuffer = null; unused
+               PHPElement elbuffer = null;
+               String name;
+               for (int i = 0; i < buffer.size(); i++) {
+                       // while ((buffer != null)
+                       // && (!buffer.isEmpty()
+                       // && ((elbuffer = (PHPElement) buffer.remove(0)) != null))) {
+                       elbuffer = (PHPElement) buffer.get(i);
+                       if (elbuffer instanceof PHPKeyword) {
+                               name = ((PHPKeyword) elbuffer).getName();
+                               if (!name.equals("return")) {
+                                       wordRule.addWord(name, keyword);
+                               }
+                       } else if (elbuffer instanceof PHPFunction) {
+                               wordRule.addWordIgnoreCase(((PHPFunction) elbuffer).getName(),
+                                               functionName);
+                       } else if (elbuffer instanceof PHPType) {
+                               wordRule.addWord(elbuffer.getName(), type);
+                       } else if (elbuffer instanceof PHPConstant) {
+                               wordRule.addWord(elbuffer.getName(), constant);
+                       }
+               }
+
+               // Add word rule for keyword 'return'.
+               token = getToken(IPreferenceConstants.PHP_KEYWORD_RETURN);
+               wordRule.addWord("return", token);
+
+               // Add rule for operators and brackets (at the end !)
+               rules.add(new OperatorRule(getToken(IPreferenceConstants.PHP_OPERATOR),
+                               getToken(IPreferenceConstants.PHP_BRACE_OPERATOR),
+                               getToken(IPreferenceConstants.PHP_STRING_DQ)));
+
+               rules.add(wordRule);
+
+               setDefaultReturnToken(getToken(IPreferenceConstants.PHP_DEFAULT));
+               return rules;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java
new file mode 100644 (file)
index 0000000..8c20ba6
--- /dev/null
@@ -0,0 +1,1068 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedMap;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.ToolFactory;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.DefaultErrorHandlingPolicies;
+import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
+import net.sourceforge.phpdt.internal.compiler.parser.VariableInfo;
+import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory;
+import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContextType;
+import net.sourceforge.phpdt.internal.ui.text.PHPCodeReader;
+import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
+import net.sourceforge.phpdt.internal.ui.text.java.JavaParameterListValidator;
+import net.sourceforge.phpdt.internal.ui.text.java.PHPCompletionProposalComparator;
+import net.sourceforge.phpdt.internal.ui.text.template.BuiltInEngine;
+import net.sourceforge.phpdt.internal.ui.text.template.DeclarationEngine;
+import net.sourceforge.phpdt.internal.ui.text.template.LocalVariableProposal;
+import net.sourceforge.phpdt.internal.ui.text.template.contentassist.TemplateEngine;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+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.IContextInformationExtension;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+
+/**
+ * Example PHP completion processor.
+ */
+public class PHPCompletionProcessor implements IContentAssistProcessor {
+       /**
+        * Simple content assist tip closer. The tip is valid in a range of 5
+        * characters around its popup location.
+        */
+       // protected static class Validator implements IContextInformationValidator,
+       // IContextInformationPresenter {
+       // protected int fInstallOffset;
+       //
+       // /*
+       // * @see IContextInformationValidator#isContextInformationValid(int)
+       // */
+       // public boolean isContextInformationValid(int offset) {
+       // return Math.abs(fInstallOffset - offset) < 5;
+       // }
+       //
+       // /*
+       // * @see IContextInformationValidator#install(IContextInformation,
+       // ITextViewer, int)
+       // */
+       // public void install(IContextInformation info, ITextViewer viewer, int
+       // offset) {
+       // fInstallOffset = offset;
+       // }
+       //
+       // /*
+       // * @see
+       // org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int,
+       // TextPresentation)
+       // */
+       // public boolean updatePresentation(int documentPosition, TextPresentation
+       // presentation) {
+       // return false;
+       // }
+       // };
+       private static class ContextInformationWrapper implements
+                       IContextInformation, IContextInformationExtension {
+               private final IContextInformation fContextInformation;
+
+               private int fPosition;
+
+               public ContextInformationWrapper(IContextInformation contextInformation) {
+                       fContextInformation = contextInformation;
+               }
+
+               /*
+                * @see IContextInformation#getContextDisplayString()
+                */
+               public String getContextDisplayString() {
+                       return fContextInformation.getContextDisplayString();
+               }
+
+               /*
+                * @see IContextInformation#getImage()
+                */
+               public Image getImage() {
+                       return fContextInformation.getImage();
+               }
+
+               /*
+                * @see IContextInformation#getInformationDisplayString()
+                */
+               public String getInformationDisplayString() {
+                       return fContextInformation.getInformationDisplayString();
+               }
+
+               /*
+                * @see IContextInformationExtension#getContextInformationPosition()
+                */
+               public int getContextInformationPosition() {
+                       return fPosition;
+               }
+
+               public void setContextInformationPosition(int position) {
+                       fPosition = position;
+               }
+       };
+
+       // private class TableName {
+       // String fTableName;
+       //
+       // TableName() {
+       // fTableName = null;
+       // }
+       //
+       // /**
+       // * @return Returns the tableName.
+       // */
+       // public String getTableName() {
+       // if (fTableName == null) {
+       // return "<!--no-table-->";
+       // }
+       // return fTableName;
+       // }
+       //
+       // /**
+       // * @param tableName
+       // * The tableName to set.
+       // */
+       // public void setTableName(String tableName) {
+       // fTableName = tableName;
+       // }
+       // }
+
+       private char[] fProposalAutoActivationSet;
+
+       protected IContextInformationValidator fValidator = null;
+
+       private TemplateEngine fTemplateEngine;
+
+       private PHPCompletionProposalComparator fComparator;
+
+       private IEditorPart fEditor;
+
+       protected IWorkingCopyManager fManager;
+
+       public PHPCompletionProcessor(IEditorPart editor) {
+               fEditor = editor;
+               fManager = WebUI.getDefault().getWorkingCopyManager();
+               TemplateContextType contextType = WebUI.getDefault()
+                               .getTemplateContextRegistry().getContextType("php"); //$NON-NLS-1$
+               if (contextType != null)
+                       fTemplateEngine = new TemplateEngine(contextType);
+               fComparator = new PHPCompletionProposalComparator();
+       }
+
+       /**
+        * Tells this processor to order the proposals alphabetically.
+        * 
+        * @param order
+        *            <code>true</code> if proposals should be ordered.
+        */
+       public void orderProposalsAlphabetically(boolean order) {
+               fComparator.setOrderAlphabetically(order);
+       }
+
+       /**
+        * Sets this processor's set of characters triggering the activation of the
+        * completion proposal computation.
+        * 
+        * @param activationSet
+        *            the activation set
+        */
+       public void setCompletionProposalAutoActivationCharacters(
+                       char[] activationSet) {
+               fProposalAutoActivationSet = activationSet;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
+                       int documentOffset) {
+               int contextInformationPosition = guessContextInformationPosition(
+                               viewer, documentOffset);
+               return internalComputeCompletionProposals(viewer, documentOffset,
+                               contextInformationPosition);
+       }
+
+       private int getLastToken(List list, ITextViewer viewer,
+                       int completionPosition, JavaContext context) {
+               // TableName tableName) {
+               IDocument document = viewer.getDocument();
+               int start = context.getStart();
+               // int end = context.getEnd();
+               String startText;
+               int lastSignificantToken = ITerminalSymbols.TokenNameEOF;
+               try {
+                       // begin search 2 lines behind of this
+                       int j = start;
+                       if (j != 0) {
+                               char ch;
+                               while (j > 0) {
+                                       ch = document.getChar(--j);
+                                       if (ch == '\n') {
+                                               break;
+                                       }
+                               }
+                               while (j > 0) {
+                                       ch = document.getChar(--j);
+                                       if (ch == '\n') {
+                                               break;
+                                       }
+                               }
+                       }
+                       if (j != start) {
+                               // scan the line for the dereferencing operator '->'
+                               startText = document.get(j, start - j);
+                               if (Scanner.DEBUG) {
+                                       System.out.println(startText);
+                               }
+                               int token = ITerminalSymbols.TokenNameEOF;
+                               // token = getLastSQLToken(startText);
+                               // tableName.setTableName(getLastSQLTableName(startText));
+                               Scanner scanner = ToolFactory
+                                               .createScanner(false, false, false);
+                               scanner.setSource(startText.toCharArray());
+                               scanner.setPHPMode(true);
+                               int beforeLastToken = ITerminalSymbols.TokenNameEOF;
+                               int lastToken = ITerminalSymbols.TokenNameEOF;
+                               char[] ident = null;
+                               try {
+                                       token = scanner.getNextToken();
+                                       lastToken = token;
+                                       while (token != ITerminalSymbols.TokenNameERROR
+                                                       && token != ITerminalSymbols.TokenNameEOF) {
+                                               beforeLastToken = lastToken;
+                                               if (token == ITerminalSymbols.TokenNameVariable) {
+                                                       ident = scanner.getCurrentTokenSource();
+                                                       if (ident.length == 5 && ident[0] == '$'
+                                                                       && ident[1] == 't' && ident[2] == 'h'
+                                                                       && ident[3] == 'i' && ident[4] == 's') {
+                                                               token = ITerminalSymbols.TokenNamethis_PHP_COMPLETION;
+                                                       }
+                                               }
+                                               lastToken = token;
+                                               // System.out.println(scanner.toStringAction(lastToken));
+                                               token = scanner.getNextToken();
+                                       }
+                               } catch (InvalidInputException e1) {
+                               } catch (SyntaxError e) {
+                               }
+                               switch (lastToken) {
+                               case ITerminalSymbols.TokenNameMINUS_GREATER:
+                                       // dereferencing operator '->' found
+                                       lastSignificantToken = ITerminalSymbols.TokenNameMINUS_GREATER;
+                                       if (beforeLastToken == ITerminalSymbols.TokenNameVariable) {
+                                               lastSignificantToken = ITerminalSymbols.TokenNameVariable;
+                                               list.set(0, ident);
+                                       } else if (beforeLastToken == ITerminalSymbols.TokenNamethis_PHP_COMPLETION) {
+                                               lastSignificantToken = ITerminalSymbols.TokenNamethis_PHP_COMPLETION;
+                                               list.set(0, ident);
+                                       }
+                                       break;
+                               case ITerminalSymbols.TokenNamenew:
+                                       lastSignificantToken = ITerminalSymbols.TokenNamenew;
+                                       break;
+                               }
+                       }
+               } catch (BadLocationException e) {
+               }
+               return lastSignificantToken;
+       }
+
+       String getSQLTableName(String sqlText, int start) {
+               int tableNameStart = -1;
+               int currentCharacterPosition = start + 1;
+               char ch;
+               try {
+                       while (true) {
+                               ch = sqlText.charAt(currentCharacterPosition++);
+                               if (tableNameStart == -1 && Scanner.isPHPIdentifierStart(ch)) {
+                                       tableNameStart = currentCharacterPosition - 1;
+                               } else {
+                                       if (!Scanner.isPHPIdentifierPart(ch)) {
+                                               return sqlText.substring(tableNameStart,
+                                                               currentCharacterPosition - 1);
+                                       }
+                               }
+                       }
+               } catch (IndexOutOfBoundsException e) {
+                       if (tableNameStart >= 0) {
+                               return sqlText.substring(tableNameStart,
+                                               currentCharacterPosition - 1);
+                       }
+               }
+               return "";
+       }
+
+       // private String getLastSQLTableName(String startText) {
+       // // scan for sql identifiers
+       // char ch = ' ';
+       // int currentSQLPosition = startText.length();
+       // int identEnd = -1;
+       // String ident = null;
+       // try {
+       // while (true) {
+       // ch = startText.charAt(--currentSQLPosition);
+       // if (Scanner.isSQLIdentifierPart(ch)) {
+       // // if (ch >= 'A' && ch <= 'Z') {
+       // if (identEnd < 0) {
+       // identEnd = currentSQLPosition + 1;
+       // }
+       // // } else if (ch >= 'a' && ch <= 'z') {
+       // // if (identEnd < 0) {
+       // // identEnd = currentSQLPosition + 1;
+       // // }
+       // } else if (identEnd >= 0) {
+       // ident = startText.substring(currentSQLPosition + 1, identEnd);
+       // // select -- from -- where --
+       // // update -- set -- where --
+       // // insert into -- ( -- ) values ( -- )
+       // if (ident.length() >= 4 && ident.length() <= 6) {
+       // ident = ident.toLowerCase();
+       // switch (ident.length()) {
+       // // case 3 :
+       // // if (ident.equals("set")) {
+       // // // System.out.println("set");
+       // // token = ITerminalSymbols.TokenNameSQLset;
+       // // return token;
+       // // }
+       // // break;
+       // case 4:
+       // if (ident.equals("from")) {
+       // // System.out.println("from");
+       // return getSQLTableName(startText, identEnd);
+       // } else if (ident.equals("into")) {
+       // // System.out.println("into");
+       // return getSQLTableName(startText, identEnd);
+       // }
+       // break;
+       // case 6:
+       // if (ident.equals("update")) {
+       // // System.out.println("update");
+       // return getSQLTableName(startText, identEnd);
+       // }
+       // break;
+       // }
+       // }
+       // identEnd = -1;
+       // } else if (Character.isWhitespace(ch)) {
+       // }
+       // }
+       // } catch (IndexOutOfBoundsException e) {
+       // }
+       // return "<!--no-table-->";
+       // }
+
+       /**
+        * Detect the last significant SQL token in the text before the completion
+        * 
+        * @param startText
+        */
+       // private int getLastSQLToken(String startText) {
+       // int token;
+       // // scan for sql identifiers
+       // char ch = ' ';
+       // int currentSQLPosition = startText.length();
+       // int identEnd = -1;
+       // String ident = null;
+       // try {
+       // while (true) {
+       // ch = startText.charAt(--currentSQLPosition);
+       // if (ch >= 'A' && ch <= 'Z') {
+       // if (identEnd < 0) {
+       // identEnd = currentSQLPosition + 1;
+       // }
+       // } else if (ch >= 'a' && ch <= 'z') {
+       // if (identEnd < 0) {
+       // identEnd = currentSQLPosition + 1;
+       // }
+       // } else if (identEnd >= 0) {
+       // ident = startText.substring(currentSQLPosition + 1, identEnd);
+       // // select -- from -- where --
+       // // update -- set -- where --
+       // // insert into -- ( -- ) values ( -- )
+       // if (ident.length() >= 3 && ident.length() <= 6) {
+       // ident = ident.toLowerCase();
+       // switch (ident.length()) {
+       // case 3:
+       // if (ident.equals("set")) {
+       // // System.out.println("set");
+       // token = ITerminalSymbols.TokenNameSQLset;
+       // return token;
+       // }
+       // break;
+       // case 4:
+       // if (ident.equals("from")) {
+       // // System.out.println("from");
+       // token = ITerminalSymbols.TokenNameSQLfrom;
+       // // getSQLTableName();
+       // return token;
+       // } else if (ident.equals("into")) {
+       // // System.out.println("into");
+       // token = ITerminalSymbols.TokenNameSQLinto;
+       // return token;
+       // }
+       // break;
+       // case 5:
+       // if (ident.equals("where")) {
+       // // System.out.println("where");
+       // token = ITerminalSymbols.TokenNameSQLwhere;
+       // return token;
+       // }
+       // break;
+       // case 6:
+       // if (ident.equals("select")) {
+       // // System.out.println("select");
+       // token = ITerminalSymbols.TokenNameSQLselect;
+       // return token;
+       // } else if (ident.equals("insert")) {
+       // // System.out.println("insert");
+       // token = ITerminalSymbols.TokenNameSQLinsert;
+       // return token;
+       // } else if (ident.equals("update")) {
+       // // System.out.println("update");
+       // token = ITerminalSymbols.TokenNameSQLupdate;
+       // return token;
+       // } else if (ident.equals("values")) {
+       // // System.out.println("values");
+       // token = ITerminalSymbols.TokenNameSQLvalues;
+       // return token;
+       // }
+       // break;
+       // }
+       // }
+       // identEnd = -1;
+       // }
+       // }
+       // } catch (IndexOutOfBoundsException e) {
+       // }
+       // return ITerminalSymbols.TokenNameEOF;
+       // }
+       private ICompletionProposal[] internalComputeCompletionProposals(
+                       ITextViewer viewer, int offset, int contextOffset) {
+               ICompilationUnit unit = fManager.getWorkingCopy(fEditor
+                               .getEditorInput());
+               IDocument document = viewer.getDocument();
+               IFile file = null;
+               IProject project = null;
+               if (offset > 0) {
+                       PHPEditor editor = null;
+                       if (fEditor != null && (fEditor instanceof PHPEditor)) {
+                               editor = (PHPEditor) fEditor;
+                               IEditorInput editorInput = editor.getEditorInput();
+                               if (editorInput instanceof IFileEditorInput) {
+                                       file = ((IFileEditorInput) editorInput).getFile();
+                                       project = file.getProject();
+                               } else {
+                                       return new ICompletionProposal[0];
+                               }
+                       }
+               }
+
+               Point selection = viewer.getSelectedRange();
+               // remember selected text
+               String selectedText = null;
+               if (selection.y != 0) {
+                       try {
+                               selectedText = document.get(selection.x, selection.y);
+                       } catch (BadLocationException e) {
+                       }
+               }
+
+               if (offset > 2 && fProposalAutoActivationSet != null) {
+                       // restrict auto activation for '>' character to '->' token
+
+                       try {
+                               char ch = document.getChar(offset - 1);
+                               if (ch == '>') {
+                                       for (int i = 0; i < fProposalAutoActivationSet.length; i++) {
+                                               ch = fProposalAutoActivationSet[i];
+                                               if (ch == '>') { // auto activation enabled
+                                                       ch = document.getChar(offset - 2);
+                                                       if (ch != '-') {
+                                                               return new IPHPCompletionProposal[0];
+                                                       }
+                                                       break;
+                                               }
+                                       }
+                               }
+                       } catch (BadLocationException e) {
+                               e.printStackTrace();
+                       }
+               }
+
+               JavaContextType phpContextType = (JavaContextType) WebUI
+                               .getDefault().getTemplateContextRegistry()
+                               .getContextType("php"); //$NON-NLS-1$
+               JavaContext context = (JavaContext) phpContextType.createContext(
+                               document, offset, selection.y, unit);
+               context.setVariable("selection", selectedText); //$NON-NLS-1$
+               String prefix = context.getKey();
+
+               HashMap methodVariables = null;
+               // HashMap typeVariables = null;
+               HashMap unitVariables = null;
+               ICompilationUnit compilationUnit = (ICompilationUnit) context
+                               .findEnclosingElement(IJavaElement.COMPILATION_UNIT);
+               // if (compilationUnit != null) {
+               // unitVariables = ((CompilationUnit) compilationUnit).variables;
+               // }
+               IType type = (IType) context.findEnclosingElement(IJavaElement.TYPE);
+               if (type != null) {
+                       // typeVariables = ((SourceType) type).variables;
+               }
+               IMethod method = (IMethod) context
+                               .findEnclosingElement(IJavaElement.METHOD);
+               // if (method != null) {
+               // methodVariables = ((SourceMethod) method).variables;
+               // }
+
+               boolean emptyPrefix = prefix == null || prefix.equals("");
+               IPHPCompletionProposal[] localVariableResults = new IPHPCompletionProposal[0];
+
+               if (!emptyPrefix && prefix.length() >= 1 && prefix.charAt(0) == '$') {
+                       // php Variable ?
+                       String lowerCasePrefix = prefix.toLowerCase();
+                       HashSet localVariables = new HashSet();
+                       if (compilationUnit != null) {
+                               unitVariables = getUnitVariables(unitVariables, compilationUnit);
+                               getVariableProposals(localVariables, viewer, project, context,
+                                               unitVariables, lowerCasePrefix, 94);
+                       }
+                       if (method != null) {
+                               methodVariables = getMethodVariables(methodVariables, method);
+                               getVariableProposals(localVariables, viewer, project, context,
+                                               methodVariables, lowerCasePrefix, 99);
+                       }
+                       if (!localVariables.isEmpty()) {
+                               localVariableResults = (IPHPCompletionProposal[]) localVariables
+                                               .toArray(new IPHPCompletionProposal[localVariables
+                                                               .size()]);
+                       }
+               }
+
+               // TableName sqlTable = new TableName();
+               ArrayList list = new ArrayList();
+               list.add(null);
+               int lastSignificantToken = getLastToken(list, viewer, offset, context); // ,
+                                                                                                                                                               // sqlTable);
+               boolean useClassMembers = (lastSignificantToken == ITerminalSymbols.TokenNameMINUS_GREATER)
+                               || (lastSignificantToken == ITerminalSymbols.TokenNameVariable)
+                               || (lastSignificantToken == ITerminalSymbols.TokenNamenew)
+                               || (lastSignificantToken == ITerminalSymbols.TokenNamethis_PHP_COMPLETION);
+
+               if (fTemplateEngine != null) {
+                       IPHPCompletionProposal[] templateResults = new IPHPCompletionProposal[0];
+                       ICompletionProposal[] results;
+                       if (!emptyPrefix) {
+                               fTemplateEngine.reset();
+                               fTemplateEngine.complete(viewer, offset, unit);
+                               templateResults = fTemplateEngine.getResults();
+                       }
+                       // TODO delete this
+                       IPHPCompletionProposal[] identifierResults = new IPHPCompletionProposal[0];
+
+                       // declarations stored in file project.index on project level
+                       IPHPCompletionProposal[] declarationResults = new IPHPCompletionProposal[0];
+                       if (project != null) {
+                               DeclarationEngine declarationEngine;
+                               JavaContextType contextType = (JavaContextType) WebUI
+                                               .getDefault().getTemplateContextRegistry()
+                                               .getContextType("php"); //$NON-NLS-1$
+                               if (contextType != null) {
+                                       IdentifierIndexManager indexManager = WebUI
+                                                       .getDefault().getIndexManager(project);
+                                       SortedMap sortedMap;
+                                       declarationEngine = new DeclarationEngine(project,
+                                                       contextType, lastSignificantToken, file);
+                                       if (lastSignificantToken == ITerminalSymbols.TokenNamethis_PHP_COMPLETION) {
+                                               // complete '$this->'
+                                               sortedMap = indexManager.getIdentifiers(file);
+                                               declarationEngine.completeObject(viewer, offset,
+                                                               sortedMap, unit);
+                                       } else {
+                                               String typeRef = null;
+                                               char[] varName = (char[]) list.get(0);
+                                               if (varName != null) {
+                                                       if (method != null) {
+                                                               methodVariables = getMethodVariables(
+                                                                               methodVariables, method);
+                                                               VariableInfo info = (VariableInfo) methodVariables
+                                                                               .get(new String(varName));
+                                                               if (info != null && info.typeIdentifier != null) {
+                                                                       typeRef = new String(info.typeIdentifier);
+                                                               }
+                                                       }
+                                               }
+                                               if (typeRef != null) {
+                                                       // complete '$variable->' with type information
+                                                       sortedMap = indexManager.getIdentifiers(typeRef);
+                                                       declarationEngine.completeObject(viewer, offset,
+                                                                       sortedMap, unit);
+                                               } else {
+                                                       // complete '$variable->' without type information
+                                                       sortedMap = indexManager.getIdentifierMap();
+                                                       declarationEngine.complete(viewer, offset,
+                                                                       sortedMap, unit);
+                                               }
+                                       }
+                                       declarationResults = declarationEngine.getResults();
+                               }
+                       }
+                       // built in function names from phpsyntax.xml
+                       ArrayList syntaxbuffer = PHPSyntaxRdr.getSyntaxData();
+                       IPHPCompletionProposal[] builtinResults = new IPHPCompletionProposal[0];
+                       if ((!useClassMembers) && syntaxbuffer != null) {
+                               BuiltInEngine builtinEngine;
+                               JavaContextType contextType = (JavaContextType) WebUI
+                                               .getDefault().getTemplateContextRegistry()
+                                               .getContextType("php"); //$NON-NLS-1$
+                               if (contextType != null) {
+                                       builtinEngine = new BuiltInEngine(contextType);
+                                       builtinEngine.complete(viewer, offset, syntaxbuffer, unit);
+                                       builtinResults = builtinEngine.getResults();
+                               }
+                       }
+                       // ICompletionProposal[] sqlResults = new ICompletionProposal[0];
+                       // if (project != null) {
+                       // sqlResults = getSQLProposals(viewer, project, context, prefix,
+                       // sqlTable);
+                       // }
+                       // concatenate the result arrays
+                       IPHPCompletionProposal[] total;
+                       total = new IPHPCompletionProposal[localVariableResults.length
+                                       + templateResults.length + identifierResults.length
+                                       + builtinResults.length + declarationResults.length];// +
+                       // sqlResults.length];
+                       System.arraycopy(templateResults, 0, total, 0,
+                                       templateResults.length);
+                       System.arraycopy(identifierResults, 0, total,
+                                       templateResults.length, identifierResults.length);
+                       System.arraycopy(builtinResults, 0, total, templateResults.length
+                                       + identifierResults.length, builtinResults.length);
+                       System.arraycopy(declarationResults, 0, total,
+                                       templateResults.length + identifierResults.length
+                                                       + builtinResults.length, declarationResults.length);
+                       // System.arraycopy(sqlResults, 0, total, templateResults.length +
+                       // identifierResults.length + builtinResults.length
+                       // + declarationResults.length, sqlResults.length);
+                       // System.arraycopy(localVariableResults, 0, total,
+                       // templateResults.length
+                       // + identifierResults.length + builtinResults.length
+                       // + declarationResults.length + sqlResults.length,
+                       // localVariableResults.length);
+                       System
+                                       .arraycopy(localVariableResults, 0, total,
+                                                       templateResults.length + identifierResults.length
+                                                                       + builtinResults.length
+                                                                       + declarationResults.length,
+                                                       localVariableResults.length);
+                       results = total;
+                       // fNumberOfComputedResults = (results == null ? 0 :
+                       // results.length);
+                       /*
+                        * Order here and not in result collector to make sure that the
+                        * order applies to all proposals and not just those of the
+                        * compilation unit.
+                        */
+                       return order(results);
+               }
+               return new IPHPCompletionProposal[0];
+       }
+
+       /**
+        * @param unitVariables
+        * @param unit
+        */
+       private HashMap getUnitVariables(HashMap unitVariables,
+                       ICompilationUnit unit) {
+               if (unitVariables == null) {
+                       try {
+                               String unitText = unit.getSource();
+                               unitVariables = new HashMap();
+
+                               ProblemReporter problemReporter = new ProblemReporter(
+                                               DefaultErrorHandlingPolicies.exitAfterAllProblems(),
+                                               new CompilerOptions(JavaCore.getOptions()),
+                                               new DefaultProblemFactory());
+                               UnitParser parser = new UnitParser(problemReporter);
+                               parser.compilationUnit = new CompilationUnitDeclaration(
+                                               problemReporter, null, unitText.length());
+                               parser.parse(unitText, unitVariables);
+
+                       } catch (Exception e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+               return unitVariables;
+       }
+
+       /**
+        * @param methodVariables
+        * @param method
+        */
+       private HashMap getMethodVariables(HashMap methodVariables, IMethod method) {
+               if (methodVariables == null) {
+                       try {
+                               String methodText = method.getSource();
+                               methodVariables = new HashMap();
+                               ProblemReporter problemReporter = new ProblemReporter(
+                                               DefaultErrorHandlingPolicies.exitAfterAllProblems(),
+                                               new CompilerOptions(JavaCore.getOptions()),
+                                               new DefaultProblemFactory());
+                               UnitParser parser = new UnitParser(problemReporter);
+                               parser.compilationUnit = new CompilationUnitDeclaration(
+                                               problemReporter, null, methodText.length());
+                               parser.parseFunction(methodText, methodVariables);
+                       } catch (Exception e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+               return methodVariables;
+       }
+
+       /**
+        * @param viewer
+        * @param project
+        * @param context
+        * @param prefix
+        * @return
+        */
+       private void getVariableProposals(HashSet localVariables,
+                       ITextViewer viewer, IProject project, JavaContext context,
+                       HashMap variables, String prefix, int relevance) {
+               // try {
+               int start = context.getStart();
+               int end = context.getEnd();
+               IRegion region = new Region(start, end - start);
+               // IMethod method = (IMethod)
+               // context.findEnclosingElement(IJavaElement.METHOD);
+               // if (method != null && (method instanceof SourceMethod) &&
+               // ((SourceMethod)
+               // method).variables != null) {
+               // HashMap map = ((SourceMethod) method).variables;
+               Set set = variables.keySet();
+               Iterator iter = set.iterator();
+               String varName;
+               boolean matchesVarName;
+               while (iter.hasNext()) {
+                       varName = (String) iter.next();
+                       if (varName.length() >= prefix.length()) {
+                               matchesVarName = true;
+                               for (int i = 0; i < prefix.length(); i++) {
+                                       if (prefix.charAt(i) != Character.toLowerCase(varName
+                                                       .charAt(i))) {
+                                               matchesVarName = false;
+                                               break;
+                                       }
+                               }
+                               if (matchesVarName) {
+                                       LocalVariableProposal prop;
+                                       // if (varName.length == prefix.length()) {
+                                       // prop = new LocalVariableProposal(new String(varName),
+                                       // region,
+                                       // viewer, relevance-10);
+                                       // } else {
+                                       prop = new LocalVariableProposal(new String(varName),
+                                                       region, viewer, relevance);
+                                       // }
+                                       localVariables.add(prop);
+                               }
+                       }
+               }
+               // }
+
+               // char[] varName;
+               // boolean matchesVarName;
+               // if (method != null) {
+               // ISourceRange range = method.getSourceRange();
+               // char[] source = method.getSource().toCharArray();
+               // Scanner scanner = new Scanner();
+               // scanner.setSource(source);
+               // scanner.phpMode = true;
+               // int token = Scanner.TokenNameWHITESPACE;
+               // while ((token = scanner.getNextToken()) != Scanner.TokenNameEOF) {
+               // if (token == Scanner.TokenNameVariable) {
+               // varName = scanner.getCurrentTokenSource();
+               // if (varName.length >= prefix.length()) {
+               // matchesVarName = true;
+               // for (int i = 0; i < prefix.length(); i++) {
+               // if (prefix.charAt(i) != varName[i]) {
+               // matchesVarName = false;
+               // break;
+               // }
+               // }
+               // if (matchesVarName) {
+               // LocalVariableProposal prop = new LocalVariableProposal(new
+               // String(varName), region, viewer);
+               // if (varName.length == prefix.length()) {
+               // prop.setRelevance(98);
+               // }
+               // localVariables.add(prop);
+               // }
+               // }
+               // }
+               // }
+               // }
+               // } catch (Throwable e) {
+               // // ignore - Syntax exceptions could occur, if there are syntax errors
+               // !
+               // }
+       }
+
+       /**
+        * @param viewer
+        * @param project
+        * @param context
+        * @param prefix
+        * @param sqlTable
+        * @param sqlResults
+        * @return
+        */
+       // private ICompletionProposal[] getSQLProposals(ITextViewer viewer,
+       // IProject
+       // project, DocumentTemplateContext context,
+       // String prefix, TableName sqlTable) {
+       // ICompletionProposal[] sqlResults = new ICompletionProposal[0];
+       // // Get The Database bookmark from the Quantum SQL plugin:
+       // // BookmarkCollection sqlBookMarks = BookmarkCollection.getInstance();
+       // // if (sqlBookMarks != null) {
+       // String bookmarkString =
+       // ProjectPrefUtil.getMiscProjectsPreferenceValue(project,
+       // IPreferenceConstants.PHP_BOOKMARK_DEFAULT);
+       // if (bookmarkString != null && !bookmarkString.equals("")) {
+       // String[] bookmarks = ExternalInterface.getBookmarkNames();
+       // boolean foundBookmark = false;
+       // for (int i = 0; i < bookmarks.length; i++) {
+       // if (bookmarks[i].equals(bookmarkString)) {
+       // foundBookmark = true;
+       // }
+       // }
+       // if (!foundBookmark) {
+       // return sqlResults;
+       // }
+       // // Bookmark bookmark = sqlBookMarks.find(bookmarkString);
+       // ArrayList sqlList = new ArrayList();
+       // if (!ExternalInterface.isBookmarkConnected(bookmarkString)) {
+       // ExternalInterface.connectBookmark(bookmarkString, null);
+       // if (!ExternalInterface.isBookmarkConnected(bookmarkString)) {
+       // return sqlResults;
+       // }
+       // }
+       // // if (ExternalInterface.isBookmarkConnected(bookmarkString)) {
+       // try {
+       // int start = context.getStart();
+       // int end = context.getEnd();
+       // String foundSQLTableName = sqlTable.getTableName();
+       // String tableName;
+       // String columnName;
+       // String prefixWithoutDollar = prefix;
+       // boolean isDollarPrefix = false;
+       // if (prefix.length() > 0 && prefix.charAt(0) == '$') {
+       // prefixWithoutDollar = prefix.substring(1);
+       // isDollarPrefix = true;
+       // }
+       // IRegion region = new Region(start, end - start);
+       // ResultSet set;
+       // if (!isDollarPrefix) {
+       // String[] tableNames = ExternalInterface.getMatchingTableNames(null,
+       // bookmarkString, prefixWithoutDollar, null, false);
+       // for (int i = 0; i < tableNames.length; i++) {
+       // sqlList.add(new SQLProposal(tableNames[i], context, region, viewer,
+       // PHPUiImages.get(PHPUiImages.IMG_TABLE)));
+       // }
+       // }
+       //
+       // String[] columnNames = ExternalInterface.getMatchingColumnNames(null,
+       // bookmarkString, prefixWithoutDollar, null, false);
+       // for (int i = 0; i < columnNames.length; i++) {
+       // sqlList.add(new SQLProposal(columnNames[i], context, region, viewer,
+       // PHPUiImages.get(PHPUiImages.IMG_TABLE)));
+       // }
+       //
+       // sqlResults = new IPHPCompletionProposal[sqlList.size()];
+       // for (int i = 0; i < sqlList.size(); i++) {
+       // sqlResults[i] = (SQLProposal) sqlList.get(i);
+       // }
+       // } catch (Exception /* NotConnectedException */ e) {
+       //
+       // }
+       // // }
+       // }
+       // // }
+       // return sqlResults;
+       // }
+       private boolean looksLikeMethod(PHPCodeReader reader) throws IOException {
+               int curr = reader.read();
+               while (curr != PHPCodeReader.EOF && Character.isWhitespace((char) curr))
+                       curr = reader.read();
+
+               if (curr == PHPCodeReader.EOF)
+                       return false;
+
+               return Scanner.isPHPIdentifierPart((char) curr);
+       }
+
+       private int guessContextInformationPosition(ITextViewer viewer, int offset) {
+               int contextPosition = offset;
+               IDocument document = viewer.getDocument();
+               try {
+
+                       PHPCodeReader reader = new PHPCodeReader();
+                       reader.configureBackwardReader(document, offset, true, true);
+
+                       int nestingLevel = 0;
+
+                       int curr = reader.read();
+                       while (curr != PHPCodeReader.EOF) {
+
+                               if (')' == (char) curr)
+                                       ++nestingLevel;
+
+                               else if ('(' == (char) curr) {
+                                       --nestingLevel;
+
+                                       if (nestingLevel < 0) {
+                                               int start = reader.getOffset();
+                                               if (looksLikeMethod(reader))
+                                                       return start + 1;
+                                       }
+                               }
+
+                               curr = reader.read();
+                       }
+               } catch (IOException e) {
+               }
+               return contextPosition;
+       }
+
+       /**
+        * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+        */
+       public IContextInformation[] computeContextInformation(ITextViewer viewer,
+                       int offset) {
+               int contextInformationPosition = guessContextInformationPosition(
+                               viewer, offset);
+               List result = addContextInformations(viewer, contextInformationPosition);
+               return (IContextInformation[]) result
+                               .toArray(new IContextInformation[result.size()]);
+       }
+
+       private List addContextInformations(ITextViewer viewer, int offset) {
+               ICompletionProposal[] proposals = internalComputeCompletionProposals(
+                               viewer, offset, -1);
+               List result = new ArrayList();
+               for (int i = 0; i < proposals.length; i++) {
+                       IContextInformation contextInformation = proposals[i]
+                                       .getContextInformation();
+                       if (contextInformation != null) {
+                               ContextInformationWrapper wrapper = new ContextInformationWrapper(
+                                               contextInformation);
+                               wrapper.setContextInformationPosition(offset);
+                               result.add(wrapper);
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * Order the given proposals.
+        */
+       private ICompletionProposal[] order(ICompletionProposal[] proposals) {
+               Arrays.sort(proposals, fComparator);
+               // int len = proposals.length;
+               // if (len > 10) {
+               // len = 10;
+               // }
+               // for (int i = 0; i < len; i++) {
+               // System.out.println(proposals[i].getDisplayString());
+               // }
+               return proposals;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public char[] getCompletionProposalAutoActivationCharacters() {
+               return fProposalAutoActivationSet;
+               // return null; // new char[] { '$' };
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public char[] getContextInformationAutoActivationCharacters() {
+               return null;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public IContextInformationValidator getContextInformationValidator() {
+               if (fValidator == null)
+                       fValidator = new JavaParameterListValidator();
+               return fValidator;
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IContentAssistProcessor
+        */
+       public String getErrorMessage() {
+               return null;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPConstant.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPConstant.java
new file mode 100644 (file)
index 0000000..b77593b
--- /dev/null
@@ -0,0 +1,29 @@
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+/**
+ * @author Choochter
+ * 
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>ObfuscatorIgnores. To enable and disable the creation
+ * of type comments go to Window>Preferences>Java>Code Generation.
+ */
+public class PHPConstant extends PHPElement {
+       private String fDescription;
+
+       public void setDescription(String description) {
+               this.fDescription = description;
+       }
+
+       public String getDescription() {
+               return this.fDescription;
+       }
+
+       public String getHoverText() {
+               return super.getHoverText() + "<br>" + getDescription();
+       }
+
+       public PHPConstant(String Name, String usage, String description) {
+               super(Name, usage);
+               setDescription(description);
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java
new file mode 100644 (file)
index 0000000..587806c
--- /dev/null
@@ -0,0 +1,95 @@
+/**********************************************************************
+ Copyright (c) 2002  Widespace, OU  and others.
+ All rights reserved.   This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://solareclipse.sourceforge.net/legal/cpl-v10.html
+
+ Contributors:
+ Igor Malinin - initial contribution
+
+ $Id: PHPDocumentPartitioner.java,v 1.6 2006-10-21 23:18:33 pombredanne Exp $
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.text.rules.FlatNode;
+import net.sourceforge.phpeclipse.ui.text.rules.MultiViewPartitioner;
+import net.sourceforge.phpeclipse.ui.text.rules.ViewNode;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class PHPDocumentPartitioner extends MultiViewPartitioner {
+       public static final String PHP_TEMPLATE_DATA = "__php_template_data";
+
+       public static final String PHP_SCRIPT_CODE = "__php_script_code";
+
+       public static final String[] LEGAL_TYPES = { PHP_TEMPLATE_DATA,
+                       PHP_SCRIPT_CODE };
+
+       public PHPDocumentPartitioner(IPartitionTokenScanner scanner) {
+               super(scanner);
+       }
+
+       protected FlatNode createNode(String type, int offset, int length) {
+               if (type.equals(PHPPartitionScanner.PHP_SCRIPTING_AREA)) {
+                       if (DEBUG) {
+                               Assert.isTrue(offset >= 0);
+                       }
+                       ViewNode node = new ViewNode(type);
+                       node.offset = offset;
+                       node.length = length;
+                       return node;
+               }
+
+               return super.createNode(type, offset, length);
+       }
+
+       /*
+        * @see net.sf.solareclipse.text.rules.DocumentViewPartitioner#createPartitioner(String)
+        */
+       protected IDocumentPartitioner createPartitioner(String contentType) {
+               if (contentType == null) {
+                       // return JavaTextTools.createHTMLPartitioner();
+                       return WebUI.getDefault().getJavaTextTools()
+                                       .getXMLTextTools().createPHPXMLPartitioner();
+               }
+
+               if (contentType.equals(PHPPartitionScanner.PHP_SCRIPTING_AREA)) {
+                       return WebUI.getDefault().getJavaTextTools()
+                                       .createPHPPartitioner();
+               }
+               return null;
+       }
+
+       /*
+        * @see net.sf.solareclipse.text.rules.DocumentViewPartitioner#getContentType(String,
+        *      String)
+        */
+       protected String getContentType(String parent, String view) {
+               if (parent == null) {
+                       if (view == IDocument.DEFAULT_CONTENT_TYPE) {
+                               return PHP_TEMPLATE_DATA;
+                       }
+               } else {
+                       if (view == IDocument.DEFAULT_CONTENT_TYPE) {
+                               return PHP_SCRIPT_CODE;
+                       }
+               }
+
+               return super.getContentType(parent, view);
+       }
+
+       public String[] getLegalContentTypes() {
+               return LEGAL_TYPES;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDoubleClickSelector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDoubleClickSelector.java
new file mode 100644 (file)
index 0000000..9a38d3b
--- /dev/null
@@ -0,0 +1,261 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextViewer;
+
+/**
+ * Double click strategy aware of PHP identifier syntax rules.
+ */
+public class PHPDoubleClickSelector implements ITextDoubleClickStrategy {
+
+       protected ITextViewer fText;
+
+       protected int fPos;
+
+       protected int fStartPos;
+
+       protected int fEndPos;
+
+       protected static char[] fgBrackets = { '{', '}', '(', ')', '[', ']', '"',
+                       '"' };
+
+       /*
+        * Create a PHPDoubleClickSelector.
+        */
+       public PHPDoubleClickSelector() {
+               super();
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ITextDoubleClickStrategy
+        */
+       public void doubleClicked(ITextViewer text) {
+
+               fPos = text.getSelectedRange().x;
+
+               if (fPos < 0)
+                       return;
+
+               fText = text;
+
+               if (!selectBracketBlock())
+                       selectWord();
+       }
+
+       /**
+        * Match the brackets at the current selection. Return true if successful,
+        * false otherwise.
+        */
+       protected boolean matchBracketsAt() {
+
+               char prevChar, nextChar;
+
+               int i;
+               int bracketIndex1 = fgBrackets.length;
+               int bracketIndex2 = fgBrackets.length;
+
+               fStartPos = -1;
+               fEndPos = -1;
+
+               // get the chars preceding and following the start position
+               try {
+
+                       IDocument doc = fText.getDocument();
+
+                       prevChar = doc.getChar(fPos - 1);
+                       nextChar = doc.getChar(fPos);
+
+                       // is the char either an open or close bracket?
+                       for (i = 0; i < fgBrackets.length; i = i + 2) {
+                               if (prevChar == fgBrackets[i]) {
+                                       fStartPos = fPos - 1;
+                                       bracketIndex1 = i;
+                               }
+                       }
+                       for (i = 1; i < fgBrackets.length; i = i + 2) {
+                               if (nextChar == fgBrackets[i]) {
+                                       fEndPos = fPos;
+                                       bracketIndex2 = i;
+                               }
+                       }
+
+                       if (fStartPos > -1 && bracketIndex1 < bracketIndex2) {
+                               fEndPos = searchForClosingBracket(fStartPos, prevChar,
+                                               fgBrackets[bracketIndex1 + 1], doc);
+                               if (fEndPos > -1)
+                                       return true;
+                               else
+                                       fStartPos = -1;
+                       } else if (fEndPos > -1) {
+                               fStartPos = searchForOpenBracket(fEndPos,
+                                               fgBrackets[bracketIndex2 - 1], nextChar, doc);
+                               if (fStartPos > -1)
+                                       return true;
+                               else
+                                       fEndPos = -1;
+                       }
+
+               } catch (BadLocationException x) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Select the word at the current selection. Return true if successful,
+        * false otherwise.
+        */
+       protected boolean matchWord() {
+
+               IDocument doc = fText.getDocument();
+
+               try {
+
+                       int pos = fPos;
+                       char c;
+
+                       while (pos >= 0) {
+                               c = doc.getChar(pos);
+                               if (!Scanner.isPHPIdentifierPart(c) && (c != '$')) {
+                                       break;
+                               }
+                               --pos;
+                       }
+
+                       fStartPos = pos;
+
+                       pos = fPos;
+                       int length = doc.getLength();
+
+                       while (pos < length) {
+                               c = doc.getChar(pos);
+                               if (!Scanner.isPHPIdentifierPart(c) && (c != '$'))
+                                       break;
+                               ++pos;
+                       }
+
+                       fEndPos = pos;
+
+                       return true;
+
+               } catch (BadLocationException x) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Returns the position of the closing bracket after startPosition.
+        * 
+        * @returns the location of the closing bracket.
+        * @param startPosition -
+        *            the beginning position
+        * @param openBracket -
+        *            the character that represents the open bracket
+        * @param closeBracket -
+        *            the character that represents the close bracket
+        * @param document -
+        *            the document being searched
+        */
+       protected int searchForClosingBracket(int startPosition, char openBracket,
+                       char closeBracket, IDocument document) throws BadLocationException {
+               int stack = 1;
+               int closePosition = startPosition + 1;
+               int length = document.getLength();
+               char nextChar;
+
+               while (closePosition < length && stack > 0) {
+                       nextChar = document.getChar(closePosition);
+                       if (nextChar == openBracket && nextChar != closeBracket)
+                               stack++;
+                       else if (nextChar == closeBracket)
+                               stack--;
+                       closePosition++;
+               }
+
+               if (stack == 0)
+                       return closePosition - 1;
+               else
+                       return -1;
+
+       }
+
+       /**
+        * Returns the position of the open bracket before startPosition.
+        * 
+        * @returns the location of the starting bracket.
+        * @param startPosition -
+        *            the beginning position
+        * @param openBracket -
+        *            the character that represents the open bracket
+        * @param closeBracket -
+        *            the character that represents the close bracket
+        * @param document -
+        *            the document being searched
+        */
+       protected int searchForOpenBracket(int startPosition, char openBracket,
+                       char closeBracket, IDocument document) throws BadLocationException {
+               int stack = 1;
+               int openPos = startPosition - 1;
+               char nextChar;
+
+               while (openPos >= 0 && stack > 0) {
+                       nextChar = document.getChar(openPos);
+                       if (nextChar == closeBracket && nextChar != openBracket)
+                               stack++;
+                       else if (nextChar == openBracket)
+                               stack--;
+                       openPos--;
+               }
+
+               if (stack == 0)
+                       return openPos + 1;
+               else
+                       return -1;
+       }
+
+       /**
+        * Select the area between the selected bracket and the closing bracket.
+        * Return true if successful.
+        */
+       protected boolean selectBracketBlock() {
+               if (matchBracketsAt()) {
+
+                       if (fStartPos == fEndPos)
+                               fText.setSelectedRange(fStartPos, 0);
+                       else
+                               fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1);
+
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Select the word at the current selection.
+        */
+       protected void selectWord() {
+               if (matchWord()) {
+
+                       if (fStartPos == fEndPos)
+                               fText.setSelectedRange(fStartPos, 0);
+                       else
+                               fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPEditorMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPEditorMessages.java
new file mode 100644 (file)
index 0000000..905771d
--- /dev/null
@@ -0,0 +1,44 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class PHPEditorMessages {
+
+       private static final String RESOURCE_BUNDLE = "net.sourceforge.phpeclipse.phpeditor.PHPEditorMessages"; //$NON-NLS-1$
+
+       // private static ResourceBundle fgResourceBundle = null;
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       // ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       private PHPEditorMessages() {
+               // if (fgResourceBundle == null) {
+               // try {
+               // fgResourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+               // } catch (MissingResourceException x) {
+               // fgResourceBundle = null;
+               // }
+               // }
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!"; //$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPElement.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPElement.java
new file mode 100644 (file)
index 0000000..fde8279
--- /dev/null
@@ -0,0 +1,46 @@
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+/**
+ * @author choochter
+ */
+public abstract class PHPElement {
+
+       private String ElementName;
+
+       private String ElementUsage;
+
+       // Setters
+       public final void setName(String ElementName) {
+               this.ElementName = ElementName;
+       }
+
+       public final void setUsage(String usage) {
+               this.ElementUsage = usage;
+       }
+
+       // Getters
+       public final String getName() {
+               return ElementName;
+       }
+
+       public final String getUsage() {
+               return ElementUsage;
+       }
+
+       public String getHoverText() {
+               return "<b>" + getUsage() + "</b>";
+       }
+
+       public PHPElement() {
+       }
+
+       public PHPElement(String name, String usage) {
+               setName(name);
+               if ((usage == null) || (usage.equals(""))) {
+                       setUsage(name + " - ");
+               } else {
+                       setUsage(usage);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPFunction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPFunction.java
new file mode 100644 (file)
index 0000000..2949a27
--- /dev/null
@@ -0,0 +1,29 @@
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+/**
+ * @author Choochter
+ * 
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>ObfuscatorIgnores. To enable and disable the creation
+ * of type comments go to Window>Preferences>Java>Code Generation.
+ */
+public class PHPFunction extends PHPElement {
+       private String fDescription;
+
+       public void setDescription(String description) {
+               this.fDescription = description;
+       }
+
+       public String getDescription() {
+               return this.fDescription;
+       }
+
+       public String getHoverText() {
+               return super.getHoverText() + "<br>" + getDescription();
+       }
+
+       public PHPFunction(String Name, String usage, String description) {
+               super(Name, usage);
+               setDescription(description);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeyword.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeyword.java
new file mode 100644 (file)
index 0000000..c710e18
--- /dev/null
@@ -0,0 +1,29 @@
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+/**
+ * @author Choochter
+ * 
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>ObfuscatorIgnores. To enable and disable the creation
+ * of type comments go to Window>Preferences>Java>Code Generation.
+ */
+public class PHPKeyword extends PHPElement {
+       // private int tokenval;
+       // public void settokenval(String tokenval) { this.tokenval =
+       // Integer.parseInt(tokenval);}
+       // public void settokenval(int tokenval) { this.tokenval = tokenval;}
+       // public int gettokenval() { return this.tokenval; }
+
+       public PHPKeyword(String Name, String Description) {
+               super(Name, Description);
+               // if ((tokenval == null) || (tokenval.equals("")))
+               // {
+               // //if there is not a tokenval, then not implemented.
+               // settokenval(-1);
+               // }
+               // else {
+               // settokenval(tokenval);
+               // }
+               // settokenval(tokenval);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java
new file mode 100644 (file)
index 0000000..0b8409d
--- /dev/null
@@ -0,0 +1,465 @@
+/**********************************************************************
+ Copyright (c) 2002  Widespace, OU  and others.
+ All rights reserved.   This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://solareclipse.sourceforge.net/legal/cpl-v10.html
+
+ Contributors:
+ Igor Malinin - initial contribution
+
+ $Id: PHPPartitionScanner.java,v 1.35 2007-03-17 14:07:31 axelcl Exp $
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpeclipse.ui.text.rules.AbstractPartitioner;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class PHPPartitionScanner implements IPartitionTokenScanner {
+       public static final String PHP_SCRIPTING_AREA = "__php_scripting_area ";
+
+       public static final int STATE_DEFAULT = 0;
+
+       // public static final int STATE_TAG = 1;
+       // public static final int STATE_SCRIPT = 2;
+
+       private IDocument document;
+
+       // private int begin;
+
+       private int end;
+
+       private int offset;
+
+       private int length;
+
+       private int position;
+
+       // private int state;
+
+       private Map tokens = new HashMap();
+
+       public PHPPartitionScanner() {
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+        */
+       public IToken nextToken() {
+               offset += length;
+
+               /*
+                * switch (state) { case STATE_TAG: return nextTagToken(); }
+                */
+
+               switch (read()) {
+               case ICharacterScanner.EOF:
+                       // state = STATE_DEFAULT;
+                       return getToken(null);
+
+               case '<':
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               // state = STATE_DEFAULT;
+                               return getToken(null);
+
+                       case '?': // <?
+                               // int ch = read();
+                               //
+                               // switch (ch) {
+                               // case ICharacterScanner.EOF:
+                               // state = STATE_DEFAULT;
+                               // return getToken(PHP_SCRIPTING_AREA);
+                               // }
+                               return scanUntilPHPEndToken(PHP_SCRIPTING_AREA);
+                       }
+
+                       unread();
+               }
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               // state = STATE_DEFAULT;
+                               return getToken(null);
+
+                       case '<':
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       // state = STATE_DEFAULT;
+                                       return getToken(null);
+
+                               case '?':
+                                       unread();
+                                       break;
+
+                               case '<':
+                                       unread();
+
+                               default:
+                                       continue loop;
+                               }
+
+                               unread();
+
+                               // state = STATE_DEFAULT;
+                               return getToken(null);
+                       }
+               }
+       }
+
+       private IToken scanUntilPHPEndToken(String token) {
+               int ch = read();
+               while (true) {
+                       switch (ch) {
+                       case ICharacterScanner.EOF:
+                               // state = STATE_DEFAULT;
+                               return getToken(token);
+                       case '"': // double quoted string
+                               // read until end of double quoted string
+                               if (!readUntilEscapedDQ()) {
+                                       // state = STATE_DEFAULT;
+                                       return getToken(token);
+                               }
+                               break;
+                       case '<': // heredoc string
+                               ch = read();
+                               switch (ch) {
+                               case ICharacterScanner.EOF:
+                                       break;
+                               case '<':
+                                       ch = read();
+                                       switch (ch) {
+                                       case ICharacterScanner.EOF:
+                                               break;
+                                       case '<':
+                                               // read until end of heredoc string
+                                               if (!readUntilEscapedHEREDOC()) {
+                                                       // state = STATE_DEFAULT;
+                                                       return getToken(token);
+                                               }
+                                       }
+                               }
+                               break;
+                       case '\'': // single quoted string
+                               // read until end of single quoted string
+                               if (!readUntilEscapedSQ()) {
+                                       // state = STATE_DEFAULT;
+                                       return getToken(token);
+                               }
+                               break;
+                       case '/': // comment start?
+                               ch = read();
+                               switch (ch) {
+                               case ICharacterScanner.EOF:
+                                       break;
+                               case '/':
+                                       // read until end of line
+                                       if (!readSingleLine()) {
+                                               // state = STATE_DEFAULT;
+                                               return getToken(token);
+                                       }
+                                       break;
+                               case '*':
+                                       // read until end of comment
+                                       if (!readMultiLineComment()) {
+                                               // state = STATE_DEFAULT;
+                                               return getToken(token);
+                                       }
+                                       break;
+                               default:
+                                       continue;
+                               }
+                               break;
+                       case '#': // line comment
+                               // read until end of line
+                               if (!readSingleLine()) {
+                                       // state = STATE_DEFAULT;
+                                       return getToken(token);
+                               }
+                               break;
+                       case '?':
+                               ch = read();
+                               switch (ch) {
+                               case ICharacterScanner.EOF:
+                               case '>':
+                                       // state = STATE_DEFAULT;
+                                       return getToken(token);
+
+                               case '?':
+                                       continue;
+                               default:
+                                       continue;
+                               }
+                       }
+
+                       ch = read();
+               }
+       }
+
+       private IToken getToken(String type) {
+               length = position - offset;
+
+               if (length == 0) {
+                       return Token.EOF;
+               }
+
+               // if (length<0) {
+               // try {
+               // System.out.println("Length<0:"+document.get(offset,5)+""+length);
+               // } catch (BadLocationException e) {
+               // e.printStackTrace();
+               // }
+               // }
+
+               if (type == null) {
+                       return Token.UNDEFINED;
+               }
+
+               IToken token = (IToken) tokens.get(type);
+               if (token == null) {
+                       token = new Token(type);
+                       tokens.put(type, token);
+               }
+
+               return token;
+       }
+
+       private int read() {
+               if (position >= end) {
+                       return ICharacterScanner.EOF;
+               }
+
+               try {
+                       return document.getChar(position++);
+               } catch (BadLocationException e) {
+                       --position;
+                       return ICharacterScanner.EOF;
+               }
+       }
+
+       private boolean readUntilEscapedDQ() {
+               // search last double quoted character
+               try {
+                       char ch;
+                       while (true) {
+                               if (position >= end) {
+                                       return false;
+                               }
+                               ch = document.getChar(position++);
+                               if (ch == '\\') {
+                                       if (position >= end) {
+                                               return false;
+                                       }
+                                       ch = document.getChar(position++); // ignore escaped
+                                       // character
+                               } else if (ch == '"') {
+                                       return true;
+                               }
+                       }
+               } catch (BadLocationException e) {
+                       --position;
+               }
+               return false;
+       }
+
+       private boolean readUntilEscapedSQ() {
+               // search last single quoted character
+               try {
+                       char ch;
+                       while (true) {
+                               if (position >= end) {
+                                       return false;
+                               }
+                               ch = document.getChar(position++);
+                               if (ch == '\\') {
+                                       if (position >= end) {
+                                               return false;
+                                       }
+                                       ch = document.getChar(position++); // ignore escaped
+                                       // character
+                               } else if (ch == '\'') {
+                                       return true;
+                               }
+                       }
+               } catch (BadLocationException e) {
+                       --position;
+               }
+               return false;
+       }
+
+       private boolean readUntilEscapedHEREDOC() {
+               // search until heredoc ends
+               try {
+                       char ch;
+                       StringBuffer buf = new StringBuffer();
+                       char[] heredocIdent;
+                       if (position >= end) {
+                               return false;
+                       }
+                       ch = document.getChar(position++);
+                       // #1493165 start
+                       while (ch == ' ') {
+                               if (position >= end) {
+                                       return false;
+                               }
+                               ch = document.getChar(position++);
+                       }
+                       // #1493165 end
+                       if (!Scanner.isPHPIdentifierStart(ch)) {
+                               return false;
+                       }
+                       while (Scanner.isPHPIdentifierPart(ch)) {
+                               buf.append(ch);
+                               if (position >= end) {
+                                       return false;
+                               }
+                               ch = document.getChar(position++);
+                       }
+                       heredocIdent = buf.toString().toCharArray();
+                       while (true) {
+                               if (position >= end) {
+                                       return false;
+                               }
+                               ch = document.getChar(position++);
+                               if (ch == '\n') { // heredoc could end after a newline
+                                       int pos = 0;
+                                       while (true) {
+                                               if (position >= end) {
+                                                       return false;
+                                               }
+                                               if (pos == heredocIdent.length) {
+                                                       return true;
+                                               }
+                                               ch = document.getChar(position++); // ignore escaped
+                                               // character
+                                               if (ch != heredocIdent[pos]) {
+                                                       break;
+                                               }
+                                               pos++;
+                                       }
+                               }
+                       }
+               } catch (BadLocationException e) {
+                       --position;
+               }
+               return false;
+       }
+
+       private boolean readSingleLine() {
+               try {
+                       do {
+                               if (position >= end) {
+                                       return false;
+                               }
+                       } while (document.getChar(position++) != '\n');
+                       return true;
+               } catch (BadLocationException e) {
+                       --position;
+               }
+               return false;
+       }
+
+       private boolean readMultiLineComment() {
+               try {
+                       char ch;
+                       while (true) {
+                               if (position >= end) {
+                                       return false;
+                               }
+                               ch = document.getChar(position++);
+                               if (ch == '*') {
+                                       if (position >= end) {
+                                               return false;
+                                       }
+                                       if (document.getChar(position) == '/') {
+                                               position++;
+                                               return true;
+                                       }
+                               }
+                       }
+               } catch (BadLocationException e) {
+                       --position;
+               }
+               return false;
+       }
+
+       private void unread() {
+               --position;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
+        */
+       public int getTokenOffset() {
+               if (AbstractPartitioner.DEBUG) {
+                       Assert.isTrue(offset >= 0, Integer.toString(offset));
+               }
+               return offset;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
+        */
+       public int getTokenLength() {
+               return length;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int,
+        *      int)
+        */
+       public void setRange(IDocument document, int offset, int length) {
+               this.document = document;
+               // this.begin = offset;
+               this.end = offset + length;
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
+        */
+       public void setPartialRange(IDocument document, int offset, int length,
+                       String contentType, int partitionOffset) {
+               // state = STATE_DEFAULT;
+               if (partitionOffset > -1) {
+                       int delta = offset - partitionOffset;
+                       if (delta > 0) {
+                               setRange(document, partitionOffset, length + delta);
+                               return;
+                       }
+               }
+               setRange(document, partitionOffset, length);
+       }
+
+       // private boolean isContinuationPartition(IDocument document, int offset) {
+       // try {
+       // String type = document.getContentType(offset - 1);
+       //
+       // if (type != IDocument.DEFAULT_CONTENT_TYPE) {
+       // return true;
+       // }
+       // } catch (BadLocationException e) {}
+       //
+       // return false;
+       // }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPType.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPType.java
new file mode 100644 (file)
index 0000000..5b109ee
--- /dev/null
@@ -0,0 +1,14 @@
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+/**
+ * @author Choochter
+ * 
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>ObfuscatorIgnores. To enable and disable the creation
+ * of type comments go to Window>Preferences>Java>Code Generation.
+ */
+public class PHPType extends PHPElement {
+       public PHPType(String Name, String Description) {
+               super(Name, Description);
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPWordExtractor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/PHPWordExtractor.java
new file mode 100644 (file)
index 0000000..ed9b88c
--- /dev/null
@@ -0,0 +1,77 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Detects PHP words in documents.
+ */
+public class PHPWordExtractor {
+
+       /**
+        * Find the location of the word at offset in document.
+        * 
+        * @returns Point - x is the start position, y is the end position. Return
+        *          null if it is not found.
+        * @param document
+        *            the document being searched.
+        * @param offset -
+        *            the position to start searching from.
+        */
+       public static Point findWord(IDocument document, int offset) {
+
+               int start = -1;
+               int end = -1;
+
+               try {
+
+                       int position = offset;
+                       char character;
+
+                       while (position >= 0) {
+                               character = document.getChar(position);
+                               if (!Scanner.isPHPIdentifierPart(character)
+                                               && (character != '$'))
+                                       break;
+                               --position;
+                       }
+
+                       start = position;
+
+                       position = offset;
+                       int length = document.getLength();
+
+                       while (position < length) {
+                               character = document.getChar(position);
+                               if (!Scanner.isPHPIdentifierPart(character)
+                                               && (character != '$'))
+                                       break;
+                               ++position;
+                       }
+
+                       start++;
+                       end = position;
+
+                       if (end > start)
+                               return new Point(start, end - start);
+
+               } catch (BadLocationException x) {
+               }
+
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java
new file mode 100644 (file)
index 0000000..ac1aa25
--- /dev/null
@@ -0,0 +1,182 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWordDetector;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * PHP Code Scanner
+ */
+public class SmartyCodeScanner extends AbstractJavaScanner {
+       public static String[] SMARTY_KEYWORDS = { "capture", "config_load",
+                       "else", "elseif", "foreach", "foreachelse", "if", "include",
+                       "insert", "ldelim", "literal", "php", "rdelim", "section",
+                       "sectionelse", "strip" };
+
+       public static String[] SMARTY_FUNCTION_NAMES = { "assign", "counter",
+                       "cycle", "debug", "eval", "fetch", "html_checkboxes", "html_image",
+                       "html_options", "html_radios", "html_select_date",
+                       "html_select_time", "html_table", "math", "popup", "popup_init",
+                       "textformat" };
+
+       private class SmartyWordRule extends WordRule {
+               private StringBuffer fBuffer = new StringBuffer();
+
+               public SmartyWordRule(IWordDetector detector) {
+                       super(detector, Token.UNDEFINED);
+               }
+
+               public SmartyWordRule(IWordDetector detector, IToken defaultToken) {
+                       super(detector, defaultToken);
+               }
+
+               public IToken evaluate(ICharacterScanner scanner) {
+                       int c = scanner.read();
+                       boolean isVariable = false;
+                       if (c == '{') {
+                               c = scanner.read();
+                               if (c != '/') {
+                                       scanner.unread();
+                               }
+                               return getToken(IPreferenceConstants.PHP_TAG);
+                       }
+                       if (c == '}') {
+                               return getToken(IPreferenceConstants.PHP_TAG);
+                       }
+                       if (fDetector.isWordStart((char) c)) {
+                               if (c == '$') {
+                                       isVariable = true;
+                               }
+                               if (fColumn == UNDEFINED
+                                               || (fColumn == scanner.getColumn() - 1)) {
+
+                                       fBuffer.setLength(0);
+                                       do {
+                                               fBuffer.append((char) c);
+                                               c = scanner.read();
+                                       } while (c != ICharacterScanner.EOF
+                                                       && fDetector.isWordPart((char) c));
+                                       scanner.unread();
+
+                                       if (isVariable) {
+                                               return getToken(IPreferenceConstants.PHP_VARIABLE);
+                                       }
+                                       IToken token = (IToken) fWords.get(fBuffer.toString());
+                                       if (token != null)
+                                               return token;
+
+                                       if (fDefaultToken.isUndefined())
+                                               unreadBuffer(scanner);
+
+                                       return fDefaultToken;
+                               }
+                       }
+
+                       scanner.unread();
+                       return Token.UNDEFINED;
+               }
+       }
+
+       private static String[] fgTokenProperties = {
+                       IPreferenceConstants.PHP_MULTILINE_COMMENT,
+                       IPreferenceConstants.PHP_SINGLELINE_COMMENT,
+                       IPreferenceConstants.PHP_TAG, IPreferenceConstants.PHP_KEYWORD,
+                       IPreferenceConstants.PHP_FUNCTIONNAME,
+                       IPreferenceConstants.PHP_VARIABLE,
+                       IPreferenceConstants.PHP_VARIABLE_DOLLAR,
+                       IPreferenceConstants.PHP_STRING_DQ,
+                       IPreferenceConstants.PHP_STRING_SQ, IPreferenceConstants.PHP_TYPE,
+                       IPreferenceConstants.PHP_CONSTANT, IPreferenceConstants.PHP_DEFAULT };
+
+       /**
+        * Creates a PHP code scanner
+        */
+       // public PHPCodeScanner(JavaColorManager provider, IPreferenceStore store)
+       // {
+       public SmartyCodeScanner(IColorManager manager, IPreferenceStore store) {
+               super(manager, store);
+               initialize();
+       }
+
+       /*
+        * @see AbstractJavaScanner#getTokenProperties()
+        */
+       protected String[] getTokenProperties() {
+               return fgTokenProperties;
+       }
+
+       /*
+        * @see AbstractJavaScanner#createRules()
+        */
+       protected List createRules() {
+               List rules = new ArrayList();
+               // Add rule for strings and character constants.
+               Token token = getToken(IPreferenceConstants.PHP_STRING_DQ);
+               rules.add(new MultiLineRule("\"", "\"", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+
+               // Add generic whitespace rule.
+               rules.add(new WhitespaceRule(new PHPWhitespaceDetector()));
+               // Add word rule for keywords, types, and constants.
+               token = getToken(IPreferenceConstants.PHP_DEFAULT);
+
+               SmartyWordRule wordRule = new SmartyWordRule(new PHPWordDetector(),
+                               token);
+
+               Token keyword = getToken(IPreferenceConstants.PHP_KEYWORD);
+               Token functionName = getToken(IPreferenceConstants.PHP_FUNCTIONNAME);
+               // Token type = getToken(IPreferenceConstants.PHP_TYPE);
+               // Token constant = getToken(IPreferenceConstants.PHP_CONSTANT);
+
+               for (int i = 0; i < SMARTY_KEYWORDS.length; i++) {
+                       wordRule.addWord(SMARTY_KEYWORDS[i], keyword);
+               }
+
+               for (int i = 0; i < SMARTY_FUNCTION_NAMES.length; i++) {
+                       wordRule.addWord(SMARTY_FUNCTION_NAMES[i], functionName);
+               }
+
+               // ArrayList buffer = PHPSyntaxRdr.getSyntaxData();
+               // PHPElement elbuffer = null;
+               // for (int i = 0; i < buffer.size(); i++) {
+               //
+               // elbuffer = (PHPElement) buffer.get(i);
+               // if (elbuffer instanceof PHPKeyword)
+               // wordRule.addWord(((PHPKeyword) elbuffer).getName(), keyword);
+               // // if (elbuffer instanceof PHPFunction)
+               // // wordRule.addWord(((PHPFunction) elbuffer).getName(),
+               // functionName);
+               // if (elbuffer instanceof PHPType)
+               // wordRule.addWord(elbuffer.getName(), type);
+               // if (elbuffer instanceof PHPConstant)
+               // wordRule.addWord(elbuffer.getName(), constant);
+               // }
+               rules.add(wordRule);
+               setDefaultReturnToken(getToken(IPreferenceConstants.PHP_DEFAULT));
+               return rules;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyDocCodeScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyDocCodeScanner.java
new file mode 100644 (file)
index 0000000..a483212
--- /dev/null
@@ -0,0 +1,180 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * A rule based SmartyDoc scanner.
+ */
+public final class SmartyDocCodeScanner extends AbstractJavaScanner {
+
+       /**
+        * A key word detector.
+        */
+       static class JavaDocKeywordDetector implements IWordDetector {
+
+               /**
+                * @see IWordDetector#isWordStart
+                */
+               public boolean isWordStart(char c) {
+                       return (c == '@');
+               }
+
+               /**
+                * @see IWordDetector#isWordPart
+                */
+               public boolean isWordPart(char c) {
+                       return Character.isLetter(c);
+               }
+       };
+
+       /**
+        * Detector for HTML comment delimiters.
+        */
+       static class HTMLCommentDetector implements IWordDetector {
+
+               /**
+                * @see IWordDetector#isWordStart
+                */
+               public boolean isWordStart(char c) {
+                       return (c == '<' || c == '-');
+               }
+
+               /**
+                * @see IWordDetector#isWordPart
+                */
+               public boolean isWordPart(char c) {
+                       return (c == '-' || c == '!' || c == '>');
+               }
+       };
+
+       class TagRule extends SingleLineRule {
+
+               /*
+                * @see SingleLineRule
+                */
+               public TagRule(IToken token) {
+                       super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$
+               }
+
+               /*
+                * @see SingleLineRule
+                */
+               public TagRule(IToken token, char escapeCharacter) {
+                       super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$
+               }
+
+               private IToken checkForWhitespace(ICharacterScanner scanner) {
+
+                       try {
+
+                               char c = getDocument().getChar(getTokenOffset() + 1);
+                               if (!Character.isWhitespace(c))
+                                       return fToken;
+
+                       } catch (BadLocationException x) {
+                       }
+
+                       return Token.UNDEFINED;
+               }
+
+               /*
+                * @see PatternRule#evaluate(ICharacterScanner)
+                */
+               public IToken evaluate(ICharacterScanner scanner) {
+                       IToken result = super.evaluate(scanner);
+                       if (result == fToken)
+                               return checkForWhitespace(scanner);
+                       return result;
+               }
+       };
+
+       private static String[] fgKeywords = {
+               "@author", "@deprecated", "@exception", "@link", "@param", "@return", "@see", "@since", "@throws", "@value", "@version", "@license", "@abstract", "@access", "@category",
+               "@copyright", "@example", "@final", "@filesource", "@global", "@ignore", "@internal", "@link", "@method", "@name", "@package", "@param", "@property", "@static",
+               "@staticvar", "@subpackage", "@todo", "@tutorial", "@uses", "@var","@id", "inheritdoc", "@property-read", "@property-write", "@source" }; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+       private static String[] fgTokenProperties = {
+                       IPreferenceConstants.PHPDOC_KEYWORD,
+                       IPreferenceConstants.PHPDOC_TAG, IPreferenceConstants.PHPDOC_LINK,
+                       IPreferenceConstants.PHPDOC_DEFAULT };
+
+       public SmartyDocCodeScanner(IColorManager manager, IPreferenceStore store) {
+               super(manager, store);
+               initialize();
+       }
+
+       public IDocument getDocument() {
+               return fDocument;
+       }
+
+       /*
+        * @see AbstractJavaScanner#getTokenProperties()
+        */
+       protected String[] getTokenProperties() {
+               return fgTokenProperties;
+       }
+
+       /*
+        * @see AbstractJavaScanner#createRules()
+        */
+       protected List createRules() {
+
+               List list = new ArrayList();
+
+               // Add rule for tags.
+               Token token = getToken(IPreferenceConstants.PHPDOC_TAG);
+               list.add(new TagRule(token));
+
+               // Add rule for HTML comments
+               WordRule wordRule = new WordRule(new HTMLCommentDetector(), token);
+               wordRule.addWord("<!--", token); //$NON-NLS-1$
+               wordRule.addWord("--!>", token); //$NON-NLS-1$
+               list.add(wordRule);
+
+               // Add rule for links.
+               token = getToken(IPreferenceConstants.PHPDOC_LINK);
+               list.add(new SingleLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+
+               // Add generic whitespace rule.
+               list.add(new WhitespaceRule(new PHPWhitespaceDetector()));
+
+               // Add word rule for keywords.
+               token = getToken(IPreferenceConstants.PHPDOC_DEFAULT);
+               wordRule = new WordRule(new JavaDocKeywordDetector(), token);
+
+               token = getToken(IPreferenceConstants.PHPDOC_KEYWORD);
+               for (int i = 0; i < fgKeywords.length; i++)
+                       wordRule.addWord(fgKeywords[i], token);
+               list.add(wordRule);
+
+               setDefaultReturnToken(getToken(IPreferenceConstants.PHPDOC_DEFAULT));
+               return list;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/syntax.xml b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/syntax.xml
new file mode 100644 (file)
index 0000000..6eef0eb
--- /dev/null
@@ -0,0 +1,6633 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpstandardsyntax>
+<s f="bcadd" u="string bcadd(string left_operand, string right_operand [, int scale])">Returns the sum of two arbitrary precision numbers</s>
+<s f="bccomp" u="int bccomp(string left_operand, string right_operand [, int scale])">Compares two arbitrary precision numbers</s>
+<s f="bcdiv" u="string bcdiv(string left_operand, string right_operand [, int scale])">Returns the quotient of two arbitrary precision numbers (division)</s>
+<s f="bcmod" u="string bcmod(string left_operand, string right_operand)">Returns the modulus of the two arbitrary precision operands</s>
+<s f="bcmul" u="string bcmul(string left_operand, string right_operand [, int scale])">Returns the multiplication of two arbitrary precision numbers</s>
+<s f="bcpow" u="string bcpow(string x, string y [, int scale])">Returns the value of an arbitrary precision number raised to the power of another</s>
+<s f="bcpowmod" u="string bcpowmod(string x, string y, string mod [, int scale])">Returns the value of an arbitrary precision number raised to the power of another reduced by a modulous</s>
+<s f="bcscale" u="bool bcscale(int scale)">Sets default scale parameter for all bc math functions</s>
+<s f="bcsqrt" u="string bcsqrt(string operand [, int scale])">Returns the square root of an arbitray precision number</s>
+<s f="bcsub" u="string bcsub(string left_operand, string right_operand [, int scale])">Returns the difference between two arbitrary precision numbers</s>
+<s f="bzcompress" u="string bzcompress(string source [, int blocksize100k [, int workfactor]])">Compresses a string into BZip2 encoded data</s>
+<s f="bzdecompress" u="string bzdecompress(string source [, int small])">Decompresses BZip2 compressed data</s>
+<s f="bzerrno" u="int bzerrno(resource bz)">Returns the error number</s>
+<s f="bzerror" u="array bzerror(resource bz)">Returns the error number and error string in an associative array</s>
+<s f="bzerrstr" u="string bzerrstr(resource bz)">Returns the error string</s>
+<s f="bzopen" u="resource bzopen(string|int file|fp, string mode)">Opens a new BZip2 stream</s>
+<s f="bzread" u="string bzread(resource bz[, int length])">Reads up to length bytes from a BZip2 stream, or 1024 bytes if length is not specified</s>
+<s f="jdtounix" u="int jdtounix(int jday)">Convert Julian Day to UNIX timestamp</s>
+<s f="unixtojd" u="int unixtojd([int timestamp])">Convert UNIX timestamp to Julian Day</s>
+<s f="cal_days_in_month" u="int cal_days_in_month(int calendar, int month, int year)">Returns the number of days in a month for a given year and calendar</s>
+<s f="cal_from_jd" u="array cal_from_jd(int jd, int calendar)">Converts from Julian Day Count to a supported calendar and return extended information</s>
+<s f="cal_info" u="array cal_info([int calendar])">Returns information about a particular calendar</s>
+<s f="cal_to_jd" u="int cal_to_jd(int calendar, int month, int day, int year)">Converts from a supported calendar to Julian Day Count</s>
+<s f="frenchtojd" u="int frenchtojd(int month, int day, int year)">Converts a french republic calendar date to julian day count</s>
+<s f="gregoriantojd" u="int gregoriantojd(int month, int day, int year)">Converts a gregorian calendar date to julian day count</s>
+<s f="jddayofweek" u="mixed jddayofweek(int juliandaycount [, int mode])">Returns name or number of day of week from julian day count</s>
+<s f="jdmonthname" u="string jdmonthname(int juliandaycount, int mode)">Returns name of month for julian day count</s>
+<s f="jdtofrench" u="string jdtofrench(int juliandaycount)">Converts a julian day count to a french republic calendar date</s>
+<s f="jdtogregorian" u="string jdtogregorian(int juliandaycount)">Converts a julian day count to a gregorian calendar date</s>
+<s f="jdtojewish" u="string jdtojewish(int juliandaycount [, bool hebrew [, int fl]])">Converts a julian day count to a jewish calendar date</s>
+<s f="jdtojulian" u="string jdtojulian(int juliandaycount)">Convert a julian day count to a julian calendar date</s>
+<s f="jewishtojd" u="int jewishtojd(int month, int day, int year)">Converts a jewish calendar date to a julian day count</s>
+<s f="juliantojd" u="int juliantojd(int month, int day, int year)">Converts a julian calendar date to julian day count</s>
+<s f="easter_date" u="int easter_date([int year])">Return the timestamp of midnight on Easter of a given year (defaults to current year)</s>
+<s f="easter_days" u="int easter_days([int year, [int method]])">Return the number of days after March 21 that Easter falls on for a given year (defaults to current year)</s>
+<s f="com_create_guid" u="string com_create_guid()">Generate a globally unique identifier (GUID)</s>
+<s f="com_event_sink" u="bool com_event_sink(object comobject, object sinkobject [, mixed sinkinterface])">Connect events from a COM object to a PHP object</s>
+<s f="com_get_active_object" u="object com_get_active_object(string progid [, int code_page ])">Returns a handle to an already running instance of a COM object</s>
+<s f="com_load_typelib" u="bool com_load_typelib(string typelib_name [, int case_insensitive])">Loads a Typelibrary and registers its constants</s>
+<s f="com_message_pump" u="bool com_message_pump([int timeoutms])">Process COM messages, sleeping for up to timeoutms milliseconds</s>
+<s f="com_print_typeinfo" u="bool com_print_typeinfo(object comobject | string typelib, string dispinterface, bool wantsink)">Print out a PHP class definition for a dispatchable interface</s>
+<s f="COMPersistHelper::GetCurFile" u="string COMPersistHelper::GetCurFile()">Determines the filename into which an object will be saved, or false if none is set, via IPersistFile::GetCurFile</s>
+<s f="COMPersistHelper::GetMaxStreamSize" u="int COMPersistHelper::GetMaxStreamSize()">Gets maximum stream size required to store the object data, via IPersistStream::GetSizeMax (or IPersistStreamInit::GetSizeMax)</s>
+<s f="COMPersistHelper::InitNew" u="int COMPersistHelper::InitNew()">Initializes the object to a default state, via IPersistStreamInit::InitNew</s>
+<s f="COMPersistHelper::LoadFromFile" u="bool COMPersistHelper::LoadFromFile(string filename [, int flags])">Load object data from file, via IPersistFile::Load</s>
+<s f="COMPersistHelper::LoadFromStream" u="mixed COMPersistHelper::LoadFromStream(resource stream)">Initializes an object from the stream where it was previously saved, via IPersistStream::Load or OleLoadFromStream</s>
+<s f="COMPersistHelper::SaveToFile" u="bool COMPersistHelper::SaveToFile(string filename [, bool remember])">Persist object data to file, via IPersistFile::Save</s>
+<s f="COMPersistHelper::SaveToStream" u="int COMPersistHelper::SaveToStream(resource stream)">Saves the object to a stream, via IPersistStream::Save</s>
+<s f="COMPersistHelper::__construct" u="int COMPersistHelper::__construct([object com_object])">Creates a persistence helper object, usually associated with a com_object</s>
+<s f="variant_abs" u="mixed variant_abs(mixed left)">Returns the absolute value of a variant</s>
+<s f="variant_add" u="mixed variant_add(mixed left, mixed right)">&quot;Adds&quot; two variant values together and returns the result</s>
+<s f="variant_and" u="mixed variant_and(mixed left, mixed right)">performs a bitwise AND operation between two variants and returns the result</s>
+<s f="variant_cast" u="object variant_cast(object variant, int type)">Convert a variant into a new variant object of another type</s>
+<s f="variant_cat" u="mixed variant_cat(mixed left, mixed right)">concatenates two variant values together and returns the result</s>
+<s f="variant_cmp" u="int variant_cmp(mixed left, mixed right [, int lcid [, int flags]])">Compares two variants</s>
+<s f="variant_date_from_timestamp" u="object variant_date_from_timestamp(int timestamp)">Returns a variant date representation of a unix timestamp</s>
+<s f="variant_date_to_timestamp" u="int variant_date_to_timestamp(object variant)">Converts a variant date/time value to unix timestamp</s>
+<s f="variant_div" u="mixed variant_div(mixed left, mixed right)">Returns the result from dividing two variants</s>
+<s f="variant_eqv" u="mixed variant_eqv(mixed left, mixed right)">Performs a bitwise equivalence on two variants</s>
+<s f="variant_fix" u="mixed variant_fix(mixed left)">Returns the integer part ? of a variant</s>
+<s f="variant_get_type" u="int variant_get_type(object variant)">Returns the VT_XXX type code for a variant</s>
+<s f="variant_idiv" u="mixed variant_idiv(mixed left, mixed right)">Converts variants to integers and then returns the result from dividing them</s>
+<s f="variant_imp" u="mixed variant_imp(mixed left, mixed right)">Performs a bitwise implication on two variants</s>
+<s f="variant_int" u="mixed variant_int(mixed left)">Returns the integer portion of a variant</s>
+<s f="variant_mod" u="mixed variant_mod(mixed left, mixed right)">Divides two variants and returns only the remainder</s>
+<s f="variant_mul" u="mixed variant_mul(mixed left, mixed right)">multiplies the values of the two variants and returns the result</s>
+<s f="variant_neg" u="mixed variant_neg(mixed left)">Performs logical negation on a variant</s>
+<s f="variant_not" u="mixed variant_not(mixed left)">Performs bitwise not negation on a variant</s>
+<s f="variant_or" u="mixed variant_or(mixed left, mixed right)">Performs a logical disjunction on two variants</s>
+<s f="variant_pow" u="mixed variant_pow(mixed left, mixed right)">Returns the result of performing the power function with two variants</s>
+<s f="variant_round" u="mixed variant_round(mixed left, int decimals)">Rounds a variant to the specified number of decimal places</s>
+<s f="variant_set" u="void variant_set(object variant, mixed value)">Assigns a new value for a variant object</s>
+<s f="variant_set_type" u="void variant_set_type(object variant, int type)">Convert a variant into another type.  Variant is modified &quot;in-place&quot;</s>
+<s f="variant_sub" u="mixed variant_sub(mixed left, mixed right)">subtracts the value of the right variant from the left variant value and returns the result</s>
+<s f="variant_xor" u="mixed variant_xor(mixed left, mixed right)">Performs a logical exclusion on two variants</s>
+<s f="ctype_alnum" u="bool ctype_alnum(mixed c)">Checks for alphanumeric character(s)</s>
+<s f="ctype_alpha" u="bool ctype_alpha(mixed c)">Checks for alphabetic character(s)</s>
+<s f="ctype_cntrl" u="bool ctype_cntrl(mixed c)">Checks for control character(s)</s>
+<s f="ctype_digit" u="bool ctype_digit(mixed c)">Checks for numeric character(s)</s>
+<s f="ctype_graph" u="bool ctype_graph(mixed c)">Checks for any printable character(s) except space</s>
+<s f="ctype_lower" u="bool ctype_lower(mixed c)">Checks for lowercase character(s)</s>
+<s f="ctype_print" u="bool ctype_print(mixed c)">Checks for printable character(s)</s>
+<s f="ctype_punct" u="bool ctype_punct(mixed c)">Checks for any printable character which is not whitespace or an alphanumeric character</s>
+<s f="ctype_space" u="bool ctype_space(mixed c)">Checks for whitespace character(s)</s>
+<s f="ctype_upper" u="bool ctype_upper(mixed c)">Checks for uppercase character(s)</s>
+<s f="ctype_xdigit" u="bool ctype_xdigit(mixed c)">Checks for character(s) representing a hexadecimal digit</s>
+<s f="curl_close" u="void curl_close(resource ch)">Close a cURL session</s>
+<s f="curl_copy_handle" u="resource curl_copy_handle(resource ch)">Copy a cURL handle along with all of it's preferences</s>
+<s f="curl_errno" u="int curl_errno(resource ch)">Return an integer containing the last error number</s>
+<s f="curl_error" u="string curl_error(resource ch)">Return a string contain the last error for the current session</s>
+<s f="curl_exec" u="bool curl_exec(resource ch)">Perform a cURL session</s>
+<s f="curl_getinfo" u="mixed curl_getinfo(resource ch [, int option])">Get information regarding a specific transfer</s>
+<s f="curl_init" u="resource curl_init([string url])">Initialize a cURL session</s>
+<s f="curl_setopt" u="bool curl_setopt(resource ch, int option, mixed value)">Set an option for a cURL transfer</s>
+<s f="curl_setopt_array" u="bool curl_setopt_array(resource ch, array options)">Set an array of option for a cURL transfer</s>
+<s f="curl_version" u="array curl_version([int version])">Return cURL version information.</s>
+<s f="curl_multi_add_handle" u="int curl_multi_add_handle(resource mh, resource ch)">Add a normal cURL handle to a cURL multi handle</s>
+<s f="curl_multi_close" u="void curl_multi_close(resource mh)">Close a set of cURL handles</s>
+<s f="curl_multi_exec" u="int curl_multi_exec(resource mh, int &amp;still_running)">Run the sub-connections of the current cURL handle</s>
+<s f="curl_multi_getcontent" u="string curl_multi_getcontent(resource ch)">Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set</s>
+<s f="curl_multi_info_read" u="array curl_multi_info_read(resource mh [, long msgs_in_queue])">Get information about the current transfers</s>
+<s f="curl_multi_init" u="resource curl_multi_init(void)">Returns a new cURL multi handle</s>
+<s f="curl_multi_remove_handle" u="int curl_multi_remove_handle(resource mh, resource ch)">Remove a multi handle from a set of cURL handles</s>
+<s f="curl_multi_select" u="int curl_multi_select(resource mh[, double timeout])">Get all the sockets associated with the cURL extension, which can then be &quot;selected&quot;</s>
+<s f="checkdate" u="bool checkdate(int month, int day, int year)">Returns true(1) if it is a valid date in gregorian calendar</s>
+<s f="date" u="string date(string format [, long timestamp])">Format a local date/time</s>
+<s f="date_create" u="DateTime date_create([string time[, DateTimeZone object]])">Returns new DateTime object</s>
+<s f="date_date_set" u="void date_date_set(DateTime object, long year, long month, long day)">Sets the date.</s>
+<s f="date_default_timezone_get" u="string date_default_timezone_get()">Gets the default timezone used by all date/time functions in a script</s>
+<s f="date_default_timezone_set" u="bool date_default_timezone_set(string timezone_identifier)">Sets the default timezone used by all date/time functions in a script</s>
+<s f="date_format" u="string date_format(DateTime object, string format)">Returns date formatted according to given format</s>
+<s f="date_format_locale" u="string date_format_locale(DateTime object, string format)"></s>
+<s f="date_isodate_set" u="void date_isodate_set(DateTime object, long year, long week[, long day])">Sets the ISO date.</s>
+<s f="date_modify" u="void date_modify(DateTime object, string modify)">Alters the timestamp.</s>
+<s f="date_offset_get" u="long date_offset_get(DateTime object)">Returns the DST offset.</s>
+<s f="date_parse" u="array date_parse(string date)">Returns associative array with detailed info about given date</s>
+<s f="date_sun_info" u="array date_sun_info(long time, float latitude, float longitude)">Returns an array with information about sun set/rise and twilight begin/end</s>
+<s f="date_sunrise" u="mixed date_sunrise(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])">Returns time of sunrise for a given day and location</s>
+<s f="date_sunset" u="mixed date_sunset(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])">Returns time of sunset for a given day and location</s>
+<s f="date_time_set" u="void date_time_set(DateTime object, long hour, long minute[, long second])">Sets the time.</s>
+<s f="date_timezone_get" u="DateTimeZone date_timezone_get(DateTime object)">Return new DateTimeZone object relative to give DateTime</s>
+<s f="date_timezone_set" u="void date_timezone_set(DateTime object, DateTimeZone object)">Sets the timezone for the DateTime object.</s>
+<s f="getdate" u="array getdate([int timestamp])">Get date/time information</s>
+<s f="gmdate" u="string gmdate(string format [, long timestamp])">Format a GMT date/time</s>
+<s f="gmmktime" u="int gmmktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])">Get UNIX timestamp for a GMT date</s>
+<s f="gmstrftime" u="string gmstrftime(string format [, int timestamp])">Format a GMT/UCT time/date according to locale settings</s>
+<s f="idate" u="int idate(string format [, int timestamp])">Format a local time/date as integer</s>
+<s f="localtime" u="array localtime([int timestamp [, bool associative_array]])">Returns the results of the C system call localtime as an associative array if the associative_array argument is set to 1 other wise it is a regular array</s>
+<s f="mktime" u="int mktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])">Get UNIX timestamp for a date</s>
+<s f="strftime" u="string strftime(string format [, int timestamp])">Format a local time/date according to locale settings</s>
+<s f="strtotime" u="int strtotime(string time [, int now ])">Convert string representation of date and time to a timestamp</s>
+<s f="time" u="int time(void)">Return current UNIX timestamp</s>
+<s f="DateTime::__construct" u=" DateTime::__construct([string time[, DateTimeZone object]])">Creates new DateTime object</s>
+<s f="DateTimeZone::__construct" u=" DateTimeZone::__construct(string timezone)">Creates new DateTimeZone object.</s>
+<s f="timezone_abbreviations_list" u="array timezone_abbreviations_list()">Returns associative array containing dst, offset and the timezone name</s>
+<s f="timezone_identifiers_list" u="array timezone_identifiers_list()">Returns numerically index array with all timezone identifiers.</s>
+<s f="timezone_name_from_abbr" u="string timezone_name_from_abbr(string abbr[, long gmtOffset[, long isdst]])">Returns the timezone name from abbrevation</s>
+<s f="timezone_name_get" u="string timezone_name_get(DateTimeZone object)">Returns the name of the timezone.</s>
+<s f="timezone_offset_get" u="long timezone_offset_get(DateTimeZone object, DateTime object)">Returns the timezone offset.</s>
+<s f="timezone_open" u="DateTimeZone timezone_open(string timezone)">Returns new DateTimeZone object</s>
+<s f="timezone_transitions_get" u="array timezone_transitions_get(DateTimeZone object)">Returns numeracilly indexed array containing associative array for all transitions for the timezone.</s>
+<s f="dba_close" u="void dba_close(resource handle)">Closes database</s>
+<s f="dba_delete" u="bool dba_delete(string key, resource handle)">Deletes the entry associated with key    If inifile: remove all other key lines</s>
+<s f="dba_exists" u="bool dba_exists(string key, resource handle)">Checks, if the specified key exists</s>
+<s f="dba_fetch" u="string dba_fetch(string key, [int skip ,] resource handle)">Fetches the data associated with key</s>
+<s f="dba_firstkey" u="string dba_firstkey(resource handle)">Resets the internal key pointer and returns the first key</s>
+<s f="dba_handlers" u="array dba_handlers([bool full_info])">List configured database handlers</s>
+<s f="dba_insert" u="bool dba_insert(string key, string value, resource handle)">If not inifile: Insert value as key, return false, if key exists already     If inifile: Add vakue as key (next instance of key)</s>
+<s f="dba_list" u="array dba_list()">List opened databases</s>
+<s f="dba_nextkey" u="string dba_nextkey(resource handle)">Returns the next key</s>
+<s f="dba_open" u="resource dba_open(string path, string mode [, string handlername, string ...])">Opens path using the specified handler in mode</s>
+<s f="dba_optimize" u="bool dba_optimize(resource handle)">Optimizes (e.g. clean up, vacuum) database</s>
+<s f="dba_popen" u="resource dba_popen(string path, string mode [, string handlername, string ...])">Opens path using the specified handler in mode persistently</s>
+<s f="dba_replace" u="bool dba_replace(string key, string value, resource handle)">Inserts value as key, replaces key, if key exists already    If inifile: remove all other key lines</s>
+<s f="dba_sync" u="bool dba_sync(resource handle)">Synchronizes database</s>
+<s f="dbase_add_record" u="bool dbase_add_record(int identifier, array data)">Adds a record to the database</s>
+<s f="dbase_close" u="bool dbase_close(int identifier)">Closes an open dBase-format database file</s>
+<s f="dbase_create" u="bool dbase_create(string filename, array fields)">Creates a new dBase-format database file</s>
+<s f="dbase_delete_record" u="bool dbase_delete_record(int identifier, int record)">Marks a record to be deleted</s>
+<s f="dbase_get_header_info" u="array dbase_get_header_info(int database_handle)"></s>
+<s f="dbase_get_record" u="array dbase_get_record(int identifier, int record)">Returns an array representing a record from the database</s>
+<s f="dbase_get_record_with_names" u="array dbase_get_record_with_names(int identifier, int record)">Returns an associative array representing a record from the database</s>
+<s f="dbase_numfields" u="int dbase_numfields(int identifier)">Returns the number of fields (columns) in the database</s>
+<s f="dbase_numrecords" u="int dbase_numrecords(int identifier)">Returns the number of records in the database</s>
+<s f="dbase_open" u="int dbase_open(string name, int mode)">Opens a dBase-format database file</s>
+<s f="dbase_pack" u="bool dbase_pack(int identifier)">Packs the database (deletes records marked for deletion)</s>
+<s f="dbase_replace_record" u="bool dbase_replace_record(int identifier, array data, int recnum)">Replaces a record to the database</s>
+<s f="dom_attr_is_id" u="boolean dom_attr_is_id()">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId Since: DOM Level 3</s>
+<s f="dom_characterdata_append_data" u="void dom_characterdata_append_data(string arg)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F Since:</s>
+<s f="dom_characterdata_delete_data" u="void dom_characterdata_delete_data(int offset, int count)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781 Since:</s>
+<s f="dom_characterdata_insert_data" u="void dom_characterdata_insert_data(int offset, string arg)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F Since:</s>
+<s f="dom_characterdata_replace_data" u="void dom_characterdata_replace_data(int offset, int count, string arg)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB Since:</s>
+<s f="dom_characterdata_substring_data" u="string dom_characterdata_substring_data(int offset, int count)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF Since:</s>
+<s f="DOMDocument::registerNodeClass" u="boolean DOMDocument::registerNodeClass(string baseclass, string extendedclass)">Register extended class used to create base node type</s>
+<s f="dom_document_adopt_node" u="DOMNode dom_document_adopt_node(DOMNode source)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode Since: DOM Level 3</s>
+<s f="dom_document_create_attribute" u="DOMAttr dom_document_create_attribute(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198 Since:</s>
+<s f="dom_document_create_attribute_ns" u="DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS Since: DOM Level 2</s>
+<s f="dom_document_create_cdatasection" u="DOMCdataSection dom_document_create_cdatasection(string data)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8 Since:</s>
+<s f="dom_document_create_comment" u="DOMComment dom_document_create_comment(string data)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328 Since:</s>
+<s f="dom_document_create_document_fragment" u="DOMDocumentFragment dom_document_create_document_fragment()">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5 Since:</s>
+<s f="dom_document_create_element" u="DOMElement dom_document_create_element(string tagName [, string value])">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547 Since:</s>
+<s f="dom_document_create_element_ns" u="DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value])">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS Since: DOM Level 2</s>
+<s f="dom_document_create_entity_reference" u="DOMEntityReference dom_document_create_entity_reference(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE Since:</s>
+<s f="dom_document_create_processing_instruction" u="DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439 Since:</s>
+<s f="dom_document_create_text_node" u="DOMText dom_document_create_text_node(string data)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127 Since:</s>
+<s f="dom_document_get_element_by_id" u="DOMElement dom_document_get_element_by_id(string elementId)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId Since: DOM Level 2</s>
+<s f="dom_document_get_elements_by_tag_name" u="DOMNodeList dom_document_get_elements_by_tag_name(string tagname)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094 Since:</s>
+<s f="dom_document_get_elements_by_tag_name_ns" u="DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS Since: DOM Level 2</s>
+<s f="dom_document_import_node" u="DOMNode dom_document_import_node(DOMNode importedNode, boolean deep)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode Since: DOM Level 2</s>
+<s f="dom_document_load" u="DOMNode dom_document_load(string source [, int options])">URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load Since: DOM Level 3</s>
+<s f="dom_document_load_html" u="DOMNode dom_document_load_html(string source)">Since: DOM extended</s>
+<s f="dom_document_load_html_file" u="DOMNode dom_document_load_html_file(string source)">Since: DOM extended</s>
+<s f="dom_document_loadxml" u="DOMNode dom_document_loadxml(string source [, int options])">URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML Since: DOM Level 3</s>
+<s f="dom_document_normalize_document" u="void dom_document_normalize_document()">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument Since: DOM Level 3</s>
+<s f="dom_document_rename_node" u="DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode Since: DOM Level 3</s>
+<s f="dom_document_save" u="int dom_document_save(string file)">Convenience method to save to file</s>
+<s f="dom_document_save_html" u="string dom_document_save_html()">Convenience method to output as html</s>
+<s f="dom_document_save_html_file" u="int dom_document_save_html_file(string file)">Convenience method to save to file as html</s>
+<s f="dom_document_savexml" u="string dom_document_savexml([node n])">URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML Since: DOM Level 3</s>
+<s f="dom_document_validate" u="boolean dom_document_validate()">Since: DOM extended</s>
+<s f="dom_document_xinclude" u="int dom_document_xinclude([int options])">Substitutues xincludes in a DomDocument</s>
+<s f="dom_domconfiguration_can_set_parameter" u="boolean dom_domconfiguration_can_set_parameter(string name, domuserdata value)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-canSetParameter Since:</s>
+<s f="dom_domconfiguration_get_parameter" u="domdomuserdata dom_domconfiguration_get_parameter(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-getParameter Since:</s>
+<s f="dom_domimplementation_create_document" u="DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument Since: DOM Level 2</s>
+<s f="dom_domimplementation_create_document_type" u="DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType Since: DOM Level 2</s>
+<s f="dom_domimplementation_get_feature" u="DOMNode dom_domimplementation_get_feature(string feature, string version)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature Since: DOM Level 3</s>
+<s f="dom_domimplementation_has_feature" u="boolean dom_domimplementation_has_feature(string feature, string version)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5CED94D7 Since:</s>
+<s f="dom_domimplementationlist_item" u="domdomimplementation dom_domimplementationlist_item(int index)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList-item Since:</s>
+<s f="dom_domimplementationsource_get_domimplementation" u="domdomimplementation dom_domimplementationsource_get_domimplementation(string features)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpl Since:</s>
+<s f="dom_domimplementationsource_get_domimplementations" u="domimplementationlist dom_domimplementationsource_get_domimplementations(string features)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpls Since:</s>
+<s f="dom_domstringlist_item" u="domstring dom_domstringlist_item(int index)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList-item Since:</s>
+<s f="dom_element_get_attribute" u="string dom_element_get_attribute(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9 Since:</s>
+<s f="dom_element_get_attribute_node" u="DOMAttr dom_element_get_attribute_node(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8 Since:</s>
+<s f="dom_element_get_attribute_node_ns" u="DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS Since: DOM Level 2</s>
+<s f="dom_element_get_attribute_ns" u="string dom_element_get_attribute_ns(string namespaceURI, string localName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS Since: DOM Level 2</s>
+<s f="dom_element_get_elements_by_tag_name" u="DOMNodeList dom_element_get_elements_by_tag_name(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D Since:</s>
+<s f="dom_element_get_elements_by_tag_name_ns" u="DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942 Since: DOM Level 2</s>
+<s f="dom_element_has_attribute" u="boolean dom_element_has_attribute(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr Since: DOM Level 2</s>
+<s f="dom_element_has_attribute_ns" u="boolean dom_element_has_attribute_ns(string namespaceURI, string localName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS Since: DOM Level 2</s>
+<s f="dom_element_remove_attribute" u="void dom_element_remove_attribute(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9 Since:</s>
+<s f="dom_element_remove_attribute_node" u="DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198 Since:</s>
+<s f="dom_element_remove_attribute_ns" u="void dom_element_remove_attribute_ns(string namespaceURI, string localName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS Since: DOM Level 2</s>
+<s f="dom_element_set_attribute" u="void dom_element_set_attribute(string name, string value)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082 Since:</s>
+<s f="dom_element_set_attribute_node" u="DOMAttr dom_element_set_attribute_node(DOMAttr newAttr)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154 Since:</s>
+<s f="dom_element_set_attribute_node_ns" u="DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS Since: DOM Level 2</s>
+<s f="dom_element_set_attribute_ns" u="void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS Since: DOM Level 2</s>
+<s f="dom_element_set_id_attribute" u="void dom_element_set_id_attribute(string name, boolean isId)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttr Since: DOM Level 3</s>
+<s f="dom_element_set_id_attribute_node" u="void dom_element_set_id_attribute_node(attr idAttr, boolean isId)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode Since: DOM Level 3</s>
+<s f="dom_element_set_id_attribute_ns" u="void dom_element_set_id_attribute_ns(string namespaceURI, string localName, boolean isId)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNS Since: DOM Level 3</s>
+<s f="dom_namednodemap_get_named_item" u="DOMNode dom_namednodemap_get_named_item(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549 Since:</s>
+<s f="dom_namednodemap_get_named_item_ns" u="DOMNode dom_namednodemap_get_named_item_ns(string namespaceURI, string localName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getNamedItemNS Since: DOM Level 2</s>
+<s f="dom_namednodemap_item" u="DOMNode dom_namednodemap_item(int index)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9 Since:</s>
+<s f="dom_namednodemap_remove_named_item" u="DOMNode dom_namednodemap_remove_named_item(string name)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D58B193 Since:</s>
+<s f="dom_namednodemap_remove_named_item_ns" u="DOMNode dom_namednodemap_remove_named_item_ns(string namespaceURI, string localName)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-removeNamedItemNS Since: DOM Level 2</s>
+<s f="dom_namednodemap_set_named_item" u="DOMNode dom_namednodemap_set_named_item(DOMNode arg)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1025163788 Since:</s>
+<s f="dom_namednodemap_set_named_item_ns" u="DOMNode dom_namednodemap_set_named_item_ns(DOMNode arg)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-setNamedItemNS Since: DOM Level 2</s>
+<s f="dom_namelist_get_name" u="string dom_namelist_get_name(int index)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getName Since:</s>
+<s f="dom_namelist_get_namespace_uri" u="string dom_namelist_get_namespace_uri(int index)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getNamespaceURI Since:</s>
+<s f="DOMNode::C14N" u="string DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])">Canonicalize nodes to a string</s>
+<s f="DOMNode::C14NFile" u="int DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])">Canonicalize nodes to a file</s>
+<s f="DOMNode::getNodePath" u="int DOMNode::getNodePath()">Gets an xpath for a node</s>
+<s f="dom_node_append_child" u="DomNode dom_node_append_child(DomNode newChild)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107 Since:</s>
+<s f="dom_node_clone_node" u="DomNode dom_node_clone_node(boolean deep)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4 Since:</s>
+<s f="dom_node_compare_document_position" u="short dom_node_compare_document_position(DomNode other)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition Since: DOM Level 3</s>
+<s f="dom_node_get_feature" u="DomNode dom_node_get_feature(string feature, string version)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature Since: DOM Level 3</s>
+<s f="dom_node_get_user_data" u="DomUserData dom_node_get_user_data(string key)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData Since: DOM Level 3</s>
+<s f="dom_node_has_attributes" u="boolean dom_node_has_attributes()">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs Since: DOM Level 2</s>
+<s f="dom_node_has_child_nodes" u="boolean dom_node_has_child_nodes()">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187 Since:</s>
+<s f="dom_node_insert_before" u="domnode dom_node_insert_before(DomNode newChild, DomNode refChild)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727 Since:</s>
+<s f="dom_node_is_default_namespace" u="boolean dom_node_is_default_namespace(string namespaceURI)">URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace Since: DOM Level 3</s>
+<s f="dom_node_is_equal_node" u="boolean dom_node_is_equal_node(DomNode arg)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode Since: DOM Level 3</s>
+<s f="dom_node_is_same_node" u="boolean dom_node_is_same_node(DomNode other)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode Since: DOM Level 3</s>
+<s f="dom_node_lookup_namespace_uri" u="string dom_node_lookup_namespace_uri(string prefix)">URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI Since: DOM Level 3</s>
+<s f="dom_node_lookup_prefix" u="string dom_node_lookup_prefix(string namespaceURI)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix Since: DOM Level 3</s>
+<s f="dom_node_normalize" u="void dom_node_normalize()">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize Since:</s>
+<s f="dom_node_remove_child" u="DomNode dom_node_remove_child(DomNode oldChild)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066 Since:</s>
+<s f="dom_node_replace_child" u="DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307 Since:</s>
+<s f="dom_node_set_user_data" u="DomUserData dom_node_set_user_data(string key, DomUserData data, userdatahandler handler)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData Since: DOM Level 3</s>
+<s f="dom_nodelist_item" u="DOMNode dom_nodelist_item(int index)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136 Since:</s>
+<s f="dom_import_simplexml" u="somNode dom_import_simplexml(sxeobject node)">Get a simplexml_element object from dom to allow for processing</s>
+<s f="dom_string_extend_find_offset16" u="int dom_string_extend_find_offset16(int offset32)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset16 Since:</s>
+<s f="dom_string_extend_find_offset32" u="int dom_string_extend_find_offset32(int offset16)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset32 Since:</s>
+<s f="dom_text_is_whitespace_in_element_content" u="boolean dom_text_is_whitespace_in_element_content()">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-isWhitespaceInElementContent Since: DOM Level 3</s>
+<s f="dom_text_replace_whole_text" u="DOMText dom_text_replace_whole_text(string content)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-replaceWholeText Since: DOM Level 3</s>
+<s f="dom_text_split_text" u="DOMText dom_text_split_text(int offset)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-38853C1D Since:</s>
+<s f="exif_imagetype" u="int exif_imagetype(string imagefile)">Get the type of an image</s>
+<s f="exif_read_data" u="array exif_read_data(string filename [, sections_needed [, sub_arrays[, read_thumbnail]]])">Reads header data from the JPEG/TIFF image filename and optionally reads the internal thumbnails</s>
+<s f="exif_tagname" u="string exif_tagname(index)">Get headername for index or false if not defined</s>
+<s f="exif_thumbnail" u="string exif_thumbnail(string filename [, &amp;width, &amp;height [, &amp;imagetype]])">Reads the embedded thumbnail</s>
+<s f="fbsql_affected_rows" u="int fbsql_affected_rows([resource link_identifier])">Get the number of rows affected by the last statement</s>
+<s f="fbsql_autocommit" u="bool fbsql_autocommit(resource link_identifier [, bool OnOff])">Turns on auto-commit</s>
+<s f="fbsql_blob_size" u="int fbsql_blob_size(string blob_handle [, resource link_identifier])">Get the size of a BLOB identified by blob_handle</s>
+<s f="fbsql_change_user" u="int fbsql_change_user(string user, string password [, string database [, resource link_identifier]])">Change the user for a session</s>
+<s f="fbsql_clob_size" u="int fbsql_clob_size(string clob_handle [, resource link_identifier])">Get the size of a CLOB identified by clob_handle</s>
+<s f="fbsql_close" u="bool fbsql_close([resource link_identifier])">Close a connection to a database server</s>
+<s f="fbsql_commit" u="bool fbsql_commit([resource link_identifier])">Commit the transaction</s>
+<s f="fbsql_connect" u="resource fbsql_connect([string hostname [, string username [, string password]]])">Create a connection to a database server</s>
+<s f="fbsql_create_blob" u="string fbsql_create_blob(string blob_data [, resource link_identifier])">Create a BLOB in the database for use with an insert or update statement</s>
+<s f="fbsql_create_clob" u="string fbsql_create_clob(string clob_data [, resource link_identifier])">Create a CLOB in the database for use with an insert or update statement</s>
+<s f="fbsql_create_db" u="bool fbsql_create_db(string database_name [, resource link_identifier [, string database_options]])">Create a new database on the server</s>
+<s f="fbsql_data_seek" u="bool fbsql_data_seek(int result, int row_number)">Move the internal row counter to the specified row_number</s>
+<s f="fbsql_database" u="string fbsql_database(resource link_identifier [, string database])">Get or set the database name used with a connection</s>
+<s f="fbsql_database_password" u="string fbsql_database_password(resource link_identifier [, string database_password])">Get or set the databsae password used with a connection</s>
+<s f="fbsql_db_query" u="resource fbsql_db_query(string database_name, string query [, resource link_identifier])">Send one or more SQL statements to a specified database on the server</s>
+<s f="fbsql_db_status" u="int fbsql_db_status(string database_name [, resource link_identifier])">Gets the status (Stopped, Starting, Running, Stopping) for a given database</s>
+<s f="fbsql_drop_db" u="int fbsql_drop_db(string database_name [, resource link_identifier])">Drop a database on the server</s>
+<s f="fbsql_errno" u="int fbsql_errno([resource link_identifier])">Returns the last error code</s>
+<s f="fbsql_error" u="string fbsql_error([resource link_identifier])">Returns the last error string</s>
+<s f="fbsql_fetch_array" u="array fbsql_fetch_array(resource result [, int result_type])">Fetches a result row as an array (associative, numeric or both)</s>
+<s f="fbsql_fetch_assoc" u="object fbsql_fetch_assoc(resource result)">Detch a row of data. Returns an assoc array</s>
+<s f="fbsql_fetch_field" u="object fbsql_fetch_field(int result [, int field_index])">Get the field properties for a specified field_index</s>
+<s f="fbsql_fetch_lengths" u="array fbsql_fetch_lengths(int result)">Returns an array of the lengths of each column in the result set</s>
+<s f="fbsql_fetch_object" u="object fbsql_fetch_object(resource result [, int result_type])">Fetch a row of data. Returns an object</s>
+<s f="fbsql_fetch_row" u="array fbsql_fetch_row(resource result)">Fetch a row of data. Returns an indexed array</s>
+<s f="fbsql_field_flags" u="string fbsql_field_flags(int result [, int field_index])">???</s>
+<s f="fbsql_field_len" u="mixed fbsql_field_len(int result [, int field_index])">Get the column length for a specified field_index</s>
+<s f="fbsql_field_name" u="string fbsql_field_name(int result [, int field_index])">Get the column name for a specified field_index</s>
+<s f="fbsql_field_seek" u="bool fbsql_field_seek(int result [, int field_index])">???</s>
+<s f="fbsql_field_table" u="string fbsql_field_table(int result [, int field_index])">Get the table name for a specified field_index</s>
+<s f="fbsql_field_type" u="string fbsql_field_type(int result [, int field_index])">Get the field type for a specified field_index</s>
+<s f="fbsql_free_result" u="bool fbsql_free_result(resource result)">free the memory used to store a result</s>
+<s f="fbsql_get_autostart_info" u="array fbsql_get_autostart_info([resource link_identifier])">???</s>
+<s f="fbsql_hostname" u="string fbsql_hostname(resource link_identifier [, string host_name])">Get or set the host name used with a connection</s>
+<s f="fbsql_insert_id" u="int fbsql_insert_id([resource link_identifier])">Get the internal index for the last insert statement</s>
+<s f="fbsql_list_dbs" u="resource fbsql_list_dbs([resource link_identifier])">Retreive a list of all databases on the server</s>
+<s f="fbsql_list_fields" u="resource fbsql_list_fields(string database_name, string table_name [, resource link_identifier])">Retrieve a list of all fields for the specified database.table</s>
+<s f="fbsql_list_tables" u="resource fbsql_list_tables(string database [, int link_identifier])">Retreive a list of all tables from the specifoied database</s>
+<s f="fbsql_next_result" u="bool fbsql_next_result(int result)">Switch to the next result if multiple results are available</s>
+<s f="fbsql_num_fields" u="int fbsql_num_fields(int result)">Get number of fields in the result set</s>
+<s f="fbsql_num_rows" u="int fbsql_num_rows(int result)">Get number of rows</s>
+<s f="fbsql_password" u="string fbsql_password(resource link_identifier [, string password])">Get or set the user password used with a connection</s>
+<s f="fbsql_pconnect" u="resource fbsql_pconnect([string hostname [, string username [, string password]]])">Create a persistant connection to a database server</s>
+<s f="fbsql_query" u="resource fbsql_query(string query [, resource link_identifier [, long batch_size]])">Send one or more SQL statements to the server and execute them</s>
+<s f="fbsql_read_blob" u="string fbsql_read_blob(string blob_handle [, resource link_identifier])">Read the BLOB data identified by blob_handle</s>
+<s f="fbsql_read_clob" u="string fbsql_read_clob(string clob_handle [, resource link_identifier])">Read the CLOB data identified by clob_handle</s>
+<s f="fbsql_result" u="mixed fbsql_result(int result [, int row [, mixed field]])">???</s>
+<s f="fbsql_rollback" u="bool fbsql_rollback([resource link_identifier])">Rollback all statments since last commit</s>
+<s f="fbsql_rows_fetched" u="int fbsql_rows_fetched(resource result)">Get the number of rows affected by the last statement</s>
+<s f="fbsql_select_db" u="bool fbsql_select_db([string database_name [, resource link_identifier]])">Select the database to open</s>
+<s f="fbsql_set_characterset" u="void fbsql_set_characterset(resource link_identifier, long charcterset [, long in_out_both]])">Change input/output character set</s>
+<s f="fbsql_set_lob_mode" u="bool fbsql_set_lob_mode(resource result, int lob_mode)">Sets the mode for how LOB data re retreived (actual data or a handle)</s>
+<s f="fbsql_set_password" u="bool fbsql_set_password(resource link_identifier, string user, string password, string old_password)">Change the password for a given user</s>
+<s f="fbsql_set_transaction" u="void fbsql_set_transaction(resource link_identifier, int locking, int isolation)">Sets the transaction locking and isolation</s>
+<s f="fbsql_start_db" u="bool fbsql_start_db(string database_name [, resource link_identifier [, string database_options]])">Start a database on the server</s>
+<s f="fbsql_stop_db" u="bool fbsql_stop_db(string database_name [, resource link_identifier])">Stop a database on the server</s>
+<s f="fbsql_table_name" u="string fbsql_table_name(resource result, int index)">Retreive the table name for index after a call to fbsql_list_tables()</s>
+<s f="fbsql_username" u="string fbsql_username(resource link_identifier [, string username])">Get or set the host user used with a connection</s>
+<s f="fbsql_warnings" u="bool fbsql_warnings([int flag])">Enable or disable FrontBase warnings</s>
+<s f="fdf_add_doc_javascript" u="bool fdf_add_doc_javascript(resource fdfdoc, string scriptname, string script)">Add javascript code to the fdf file</s>
+<s f="fdf_add_template" u="bool fdf_add_template(resource fdfdoc, int newpage, string filename, string template, int rename)">Adds a template into the FDF document</s>
+<s f="fdf_close" u="void fdf_close(resource fdfdoc)">Closes the FDF document</s>
+<s f="fdf_create" u="resource fdf_create(void)">Creates a new FDF document</s>
+<s f="fdf_enum_values" u="bool fdf_enum_values(resource fdfdoc, callback function [, mixed userdata])">Call a user defined function for each document value</s>
+<s f="fdf_errno" u="int fdf_errno(void)">Gets error code for last operation</s>
+<s f="fdf_error" u="string fdf_error([int errno])">Gets error description for error code</s>
+<s f="fdf_get_ap" u="bool fdf_get_ap(resource fdfdoc, string fieldname, int face, string filename)">Gets the appearance of a field and creates a PDF document out of it.</s>
+<s f="fdf_get_attachment" u="array fdf_get_attachment(resource fdfdoc, string fieldname, string savepath)">Get attached uploaded file</s>
+<s f="fdf_get_encoding" u="string fdf_get_encoding(resource fdf)">Gets FDF file encoding scheme</s>
+<s f="fdf_get_file" u="string fdf_get_file(resource fdfdoc)">Gets the value of /F key</s>
+<s f="fdf_get_flags" u="int fdf_get_flags(resorce fdfdoc, string fieldname, int whichflags)">Gets the flags of a field</s>
+<s f="fdf_get_opt" u="mixed fdf_get_opt(resource fdfdof, string fieldname [, int element])">Gets a value from the opt array of a field</s>
+<s f="fdf_get_status" u="string fdf_get_status(resource fdfdoc)">Gets the value of /Status key</s>
+<s f="fdf_get_value" u="string fdf_get_value(resource fdfdoc, string fieldname [, int which])">Gets the value of a field as string</s>
+<s f="fdf_get_version" u="string fdf_get_version([resource fdfdoc])">Gets version number for FDF api or file</s>
+<s f="fdf_header" u="void fdf_header(void)">Set FDF specific HTTP headers</s>
+<s f="fdf_next_field_name" u="string fdf_next_field_name(resource fdfdoc [, string fieldname])">Gets the name of the next field name or the first field name</s>
+<s f="fdf_open" u="resource fdf_open(string filename)">Opens a new FDF document</s>
+<s f="fdf_open_string" u="resource fdf_open_string(string fdf_data)">Opens a new FDF document from string</s>
+<s f="fdf_remove_item" u="bool fdf_remove_item(resource fdfdoc, string fieldname, int item)">Sets target frame for form</s>
+<s f="fdf_save" u="bool fdf_save(resource fdfdoc [, string filename])">Writes out the FDF file</s>
+<s f="fdf_save_string" u="string fdf_save_string(resource fdfdoc)">Returns the FDF file as a string</s>
+<s f="fdf_set_ap" u="bool fdf_set_ap(resource fdfdoc, string fieldname, int face, string filename, int pagenr)">Sets the appearence of a field</s>
+<s f="fdf_set_encoding" u="bool fdf_set_encoding(resource fdf_document, string encoding)">Sets FDF encoding (either &quot;Shift-JIS&quot; or &quot;Unicode&quot;)</s>
+<s f="fdf_set_file" u="bool fdf_set_file(resource fdfdoc, string filename [, string target_frame])">Sets the value of /F key</s>
+<s f="fdf_set_flags" u="bool fdf_set_flags(resource fdfdoc, string fieldname, int whichflags, int newflags)">Sets flags for a field in the FDF document</s>
+<s f="fdf_set_javascript_action" u="bool fdf_set_javascript_action(resource fdfdoc, string fieldname, int whichtrigger, string script)">Sets the javascript action for a field</s>
+<s f="fdf_set_on_import_javascript" u="bool fdf_set_on_import_javascript(resource fdfdoc, string script, bool before_data_import)">Adds javascript code to be executed when Acrobat opens the FDF</s>
+<s f="fdf_set_opt" u="bool fdf_set_opt(resource fdfdoc, string fieldname, int element, string value, string name)">Sets a value in the opt array for a field</s>
+<s f="fdf_set_status" u="bool fdf_set_status(resource fdfdoc, string status)">Sets the value of /Status key</s>
+<s f="fdf_set_submit_form_action" u="bool fdf_set_submit_form_action(resource fdfdoc, string fieldname, int whichtrigger, string url, int flags)">Sets the submit form action for a field</s>
+<s f="fdf_set_target_frame" u="bool fdf_set_target_frame(resource fdfdoc, string target)">Sets target frame for form</s>
+<s f="fdf_set_value" u="bool fdf_set_value(resource fdfdoc, string fieldname, mixed value [, int isname])">Sets the value of a field</s>
+<s f="fdf_set_version" u="bool fdf_set_version(resourece fdfdoc, string version)">Sets FDF version for a file</s>
+<s f="filter_has_var" u="mixed filter_has_var(constant type, string variable_name)">* Returns true if the variable with the name 'name' exists in source.</s>
+<s f="filter_input" u="mixed filter_input(constant type, string variable_name [, long filter [, mixed options]])">* Returns the filtered variable 'name'* from source `type`.</s>
+<s f="filter_input_array" u="mixed filter_input_array(constant type, [, mixed options]])">* Returns an array with all arguments defined in 'definition'.</s>
+<s f="filter_var" u="mixed filter_var(mixed variable [, long filter [, mixed options]])">* Returns the filtered version of the vriable.</s>
+<s f="filter_var_array" u="mixed filter_var_array(array data, [, mixed options]])">* Returns an array with all arguments defined in 'definition'.</s>
+<s f="filter_id" u=" filter_id(string filtername)">* Returns the filter ID belonging to a named filter</s>
+<s f="ftp_alloc" u="bool ftp_alloc(resource stream, int size[, &amp;response])">Attempt to allocate space on the remote FTP server</s>
+<s f="ftp_cdup" u="bool ftp_cdup(resource stream)">Changes to the parent directory</s>
+<s f="ftp_chdir" u="bool ftp_chdir(resource stream, string directory)">Changes directories</s>
+<s f="ftp_chmod" u="int ftp_chmod(resource stream, int mode, string filename)">Sets permissions on a file</s>
+<s f="ftp_close" u="bool ftp_close(resource stream)">Closes the FTP stream</s>
+<s f="ftp_connect" u="resource ftp_connect(string host [, int port [, int timeout]])">Opens a FTP stream</s>
+<s f="ftp_delete" u="bool ftp_delete(resource stream, string file)">Deletes a file</s>
+<s f="ftp_exec" u="bool ftp_exec(resource stream, string command)">Requests execution of a program on the FTP server</s>
+<s f="ftp_fget" u="bool ftp_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos])">Retrieves a file from the FTP server and writes it to an open file</s>
+<s f="ftp_fput" u="bool ftp_fput(resource stream, string remote_file, resource fp, int mode[, int startpos])">Stores a file from an open file to the FTP server</s>
+<s f="ftp_get" u="bool ftp_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos])">Retrieves a file from the FTP server and writes it to a local file</s>
+<s f="ftp_get_option" u="mixed ftp_get_option(resource stream, int option)">Gets an FTP option</s>
+<s f="ftp_login" u="bool ftp_login(resource stream, string username, string password)">Logs into the FTP server</s>
+<s f="ftp_mdtm" u="int ftp_mdtm(resource stream, string filename)">Returns the last modification time of the file, or -1 on error</s>
+<s f="ftp_mkdir" u="string ftp_mkdir(resource stream, string directory)">Creates a directory and returns the absolute path for the new directory or false on error</s>
+<s f="ftp_nb_continue" u="int ftp_nb_continue(resource stream)">Continues retrieving/sending a file nbronously</s>
+<s f="ftp_nb_fget" u="int ftp_nb_fget(resource stream, resource fp, string remote_file, int mode[, int resumepos])">Retrieves a file from the FTP server asynchronly and writes it to an open file</s>
+<s f="ftp_nb_fput" u="int ftp_nb_fput(resource stream, string remote_file, resource fp, int mode[, int startpos])">Stores a file from an open file to the FTP server nbronly</s>
+<s f="ftp_nb_get" u="int ftp_nb_get(resource stream, string local_file, string remote_file, int mode[, int resume_pos])">Retrieves a file from the FTP server nbhronly and writes it to a local file</s>
+<s f="ftp_nb_put" u="int ftp_nb_put(resource stream, string remote_file, string local_file, int mode[, int startpos])">Stores a file on the FTP server</s>
+<s f="ftp_nlist" u="array ftp_nlist(resource stream, string directory)">Returns an array of filenames in the given directory</s>
+<s f="ftp_pasv" u="bool ftp_pasv(resource stream, bool pasv)">Turns passive mode on or off</s>
+<s f="ftp_put" u="bool ftp_put(resource stream, string remote_file, string local_file, int mode[, int startpos])">Stores a file on the FTP server</s>
+<s f="ftp_pwd" u="string ftp_pwd(resource stream)">Returns the present working directory</s>
+<s f="ftp_raw" u="array ftp_raw(resource stream, string command)">Sends a literal command to the FTP server</s>
+<s f="ftp_rawlist" u="array ftp_rawlist(resource stream, string directory [, bool recursive])">Returns a detailed listing of a directory as an array of output lines</s>
+<s f="ftp_rename" u="bool ftp_rename(resource stream, string src, string dest)">Renames the given file to a new path</s>
+<s f="ftp_rmdir" u="bool ftp_rmdir(resource stream, string directory)">Removes a directory</s>
+<s f="ftp_set_option" u="bool ftp_set_option(resource stream, int option, mixed value)">Sets an FTP option</s>
+<s f="ftp_site" u="bool ftp_site(resource stream, string cmd)">Sends a SITE command to the server</s>
+<s f="ftp_size" u="int ftp_size(resource stream, string filename)">Returns the size of the file, or -1 on error</s>
+<s f="ftp_ssl_connect" u="resource ftp_ssl_connect(string host [, int port [, int timeout]])">Opens a FTP-SSL stream</s>
+<s f="ftp_systype" u="string ftp_systype(resource stream)">Returns the system type identifier</s>
+<s f="gd_info" u="array gd_info()"></s>
+<s f="image2wbmp" u="bool image2wbmp(resource im [, string filename [, int threshold]])">Output WBMP image to browser or file</s>
+<s f="imagealphablending" u="bool imagealphablending(resource im, bool on)">Turn alpha blending mode on or off for the given image</s>
+<s f="imageantialias" u="bool imageantialias(resource im, bool on)">Should antialiased functions used or not</s>
+<s f="imagearc" u="bool imagearc(resource im, int cx, int cy, int w, int h, int s, int e, int col)">Draw a partial ellipse</s>
+<s f="imagechar" u="bool imagechar(resource im, int font, int x, int y, string c, int col)">Draw a character</s>
+<s f="imagecharup" u="bool imagecharup(resource im, int font, int x, int y, string c, int col)">Draw a character rotated 90 degrees counter-clockwise</s>
+<s f="imagecolorallocate" u="int imagecolorallocate(resource im, int red, int green, int blue)">Allocate a color for an image</s>
+<s f="imagecolorallocatealpha" u="int imagecolorallocatealpha(resource im, int red, int green, int blue, int alpha)">Allocate a color with an alpha level.  Works for true color and palette based images</s>
+<s f="imagecolorat" u="int imagecolorat(resource im, int x, int y)">Get the index of the color of a pixel</s>
+<s f="imagecolorclosest" u="int imagecolorclosest(resource im, int red, int green, int blue)">Get the index of the closest color to the specified color</s>
+<s f="imagecolorclosestalpha" u="int imagecolorclosestalpha(resource im, int red, int green, int blue, int alpha)">Find the closest matching colour with alpha transparency</s>
+<s f="imagecolorclosesthwb" u="int imagecolorclosesthwb(resource im, int red, int green, int blue)">Get the index of the color which has the hue, white and blackness nearest to the given color</s>
+<s f="imagecolordeallocate" u="bool imagecolordeallocate(resource im, int index)">De-allocate a color for an image</s>
+<s f="imagecolorexact" u="int imagecolorexact(resource im, int red, int green, int blue)">Get the index of the specified color</s>
+<s f="imagecolorexactalpha" u="int imagecolorexactalpha(resource im, int red, int green, int blue, int alpha)">Find exact match for colour with transparency</s>
+<s f="imagecolormatch" u="bool imagecolormatch(resource im1, resource im2)">Makes the colors of the palette version of an image more closely match the true color version</s>
+<s f="imagecolorresolve" u="int imagecolorresolve(resource im, int red, int green, int blue)">Get the index of the specified color or its closest possible alternative</s>
+<s f="imagecolorresolvealpha" u="int imagecolorresolvealpha(resource im, int red, int green, int blue, int alpha)">Resolve/Allocate a colour with an alpha level.  Works for true colour and palette based images</s>
+<s f="imagecolorset" u="void imagecolorset(resource im, int col, int red, int green, int blue)">Set the color for the specified palette index</s>
+<s f="imagecolorsforindex" u="array imagecolorsforindex(resource im, int col)">Get the colors for an index</s>
+<s f="imagecolorstotal" u="int imagecolorstotal(resource im)">Find out the number of colors in an image's palette</s>
+<s f="imagecolortransparent" u="int imagecolortransparent(resource im [, int col])">Define a color as transparent</s>
+<s f="imageconvolution" u="resource imageconvolution(resource src_im, array matrix3x3, double div, double offset)">Apply a 3x3 convolution matrix, using coefficient div and offset</s>
+<s f="imagecopy" u="bool imagecopy(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h)">Copy part of an image</s>
+<s f="imagecopymerge" u="bool imagecopymerge(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct)">Merge one part of an image with another</s>
+<s f="imagecopymergegray" u="bool imagecopymergegray(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct)">Merge one part of an image with another</s>
+<s f="imagecopyresampled" u="bool imagecopyresampled(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h)">Copy and resize part of an image using resampling to help ensure clarity</s>
+<s f="imagecopyresized" u="bool imagecopyresized(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h)">Copy and resize part of an image</s>
+<s f="imagecreate" u="resource imagecreate(int x_size, int y_size)">Create a new image</s>
+<s f="imagecreatefromgd" u="resource imagecreatefromgd(string filename)">Create a new image from GD file or URL</s>
+<s f="imagecreatefromgd2" u="resource imagecreatefromgd2(string filename)">Create a new image from GD2 file or URL</s>
+<s f="imagecreatefromgd2part" u="resource imagecreatefromgd2part(string filename, int srcX, int srcY, int width, int height)">Create a new image from a given part of GD2 file or URL</s>
+<s f="imagecreatefromgif" u="resource imagecreatefromgif(string filename)">Create a new image from GIF file or URL</s>
+<s f="imagecreatefromjpeg" u="resource imagecreatefromjpeg(string filename)">Create a new image from JPEG file or URL</s>
+<s f="imagecreatefrompng" u="resource imagecreatefrompng(string filename)">Create a new image from PNG file or URL</s>
+<s f="imagecreatefromstring" u="resource imagecreatefromstring(string image)">Create a new image from the image stream in the string</s>
+<s f="imagecreatefromwbmp" u="resource imagecreatefromwbmp(string filename)">Create a new image from WBMP file or URL</s>
+<s f="imagecreatefromxbm" u="resource imagecreatefromxbm(string filename)">Create a new image from XBM file or URL</s>
+<s f="imagecreatefromxpm" u="resource imagecreatefromxpm(string filename)">Create a new image from XPM file or URL</s>
+<s f="imagecreatetruecolor" u="resource imagecreatetruecolor(int x_size, int y_size)">Create a new true color image</s>
+<s f="imagedashedline" u="bool imagedashedline(resource im, int x1, int y1, int x2, int y2, int col)">Draw a dashed line</s>
+<s f="imagedestroy" u="bool imagedestroy(resource im)">Destroy an image</s>
+<s f="imageellipse" u="bool imageellipse(resource im, int cx, int cy, int w, int h, int color)">Draw an ellipse</s>
+<s f="imagefill" u="bool imagefill(resource im, int x, int y, int col)">Flood fill</s>
+<s f="imagefilledarc" u="bool imagefilledarc(resource im, int cx, int cy, int w, int h, int s, int e, int col, int style)">Draw a filled partial ellipse</s>
+<s f="imagefilledellipse" u="bool imagefilledellipse(resource im, int cx, int cy, int w, int h, int color)">Draw an ellipse</s>
+<s f="imagefilledpolygon" u="bool imagefilledpolygon(resource im, array point, int num_points, int col)">Draw a filled polygon</s>
+<s f="imagefilledrectangle" u="bool imagefilledrectangle(resource im, int x1, int y1, int x2, int y2, int col)">Draw a filled rectangle</s>
+<s f="imagefilltoborder" u="bool imagefilltoborder(resource im, int x, int y, int border, int col)">Flood fill to specific color</s>
+<s f="imagefilter" u="bool imagefilter(resource src_im, int filtertype, [args] )">Applies Filter an image using a custom angle</s>
+<s f="imagefontheight" u="int imagefontheight(int font)">Get font height</s>
+<s f="imagefontwidth" u="int imagefontwidth(int font)">Get font width</s>
+<s f="imageftbbox" u="array imageftbbox(float size, float angle, string font_file, string text [, array extrainfo])">Give the bounding box of a text using fonts via freetype2</s>
+<s f="imagefttext" u="array imagefttext(resource im, float size, float angle, int x, int y, int col, string font_file, string text [, array extrainfo])">Write text to the image using fonts via freetype2</s>
+<s f="imagegammacorrect" u="bool imagegammacorrect(resource im, float inputgamma, float outputgamma)">Apply a gamma correction to a GD image</s>
+<s f="imagegd" u="bool imagegd(resource im [, string filename])">Output GD image to browser or file</s>
+<s f="imagegd2" u="bool imagegd2(resource im [, string filename [, int chunk_size [, int type]]])">Output GD2 image to browser or file</s>
+<s f="imagegif" u="bool imagegif(resource im [, string filename])">Output GIF image to browser or file</s>
+<s f="imagegrabscreen" u="resource imagegrabscreen()">Grab a screenshot</s>
+<s f="imagegrabwindow" u="resource imagegrabwindow(int window_handle [, int client_area])">Grab a window or its client area using a windows handle (HWND property in COM instance)</s>
+<s f="imageinterlace" u="int imageinterlace(resource im [, int interlace])">Enable or disable interlace</s>
+<s f="imageistruecolor" u="bool imageistruecolor(resource im)">return true if the image uses truecolor</s>
+<s f="imagejpeg" u="bool imagejpeg(resource im [, string filename [, int quality]])">Output JPEG image to browser or file</s>
+<s f="imagelayereffect" u="bool imagelayereffect(resource im, int effect)">Set the alpha blending flag to use the bundled libgd layering effects</s>
+<s f="imageline" u="bool imageline(resource im, int x1, int y1, int x2, int y2, int col)">Draw a line</s>
+<s f="imageloadfont" u="int imageloadfont(string filename)">Load a new font</s>
+<s f="imagepalettecopy" u="void imagepalettecopy(resource dst, resource src)">Copy the palette from the src image onto the dst image</s>
+<s f="imagepng" u="bool imagepng(resource im [, string filename [, int quality]])">Output PNG image to browser or file</s>
+<s f="imagepolygon" u="bool imagepolygon(resource im, array point, int num_points, int col)">Draw a polygon</s>
+<s f="imagepsbbox" u="array imagepsbbox(string text, resource font, int size [, int space, int tightness, int angle])">Return the bounding box needed by a string if rasterized</s>
+<s f="imagepscopyfont" u="int imagepscopyfont(int font_index)">Make a copy of a font for purposes like extending or reenconding</s>
+<s f="imagepsencodefont" u="bool imagepsencodefont(resource font_index, string filename)">To change a fonts character encoding vector</s>
+<s f="imagepsextendfont" u="bool imagepsextendfont(resource font_index, float extend)">Extend or or condense (if extend &lt; 1) a font</s>
+<s f="imagepsfreefont" u="bool imagepsfreefont(resource font_index)">Free memory used by a font</s>
+<s f="imagepsloadfont" u="resource imagepsloadfont(string pathname)">Load a new font from specified file</s>
+<s f="imagepsslantfont" u="bool imagepsslantfont(resource font_index, float slant)">Slant a font</s>
+<s f="imagepstext" u="array imagepstext(resource image, string text, resource font, int size, int foreground, int background, int xcoord, int ycoord [, int space, int tightness, float angle, int antialias])">Rasterize a string over an image</s>
+<s f="imagerectangle" u="bool imagerectangle(resource im, int x1, int y1, int x2, int y2, int col)">Draw a rectangle</s>
+<s f="imagerotate" u="resource imagerotate(resource src_im, float angle, int bgdcolor [, int ignoretransparent])">Rotate an image using a custom angle</s>
+<s f="imagesavealpha" u="bool imagesavealpha(resource im, bool on)">Include alpha channel to a saved image</s>
+<s f="imagesetbrush" u="bool imagesetbrush(resource image, resource brush)">Set the brush image to $brush when filling $image with the &quot;IMG_COLOR_BRUSHED&quot; color</s>
+<s f="imagesetpixel" u="bool imagesetpixel(resource im, int x, int y, int col)">Set a single pixel</s>
+<s f="imagesetstyle" u="bool imagesetstyle(resource im, array styles)">Set the line drawing styles for use with imageline and IMG_COLOR_STYLED.</s>
+<s f="imagesetthickness" u="bool imagesetthickness(resource im, int thickness)">Set line thickness for drawing lines, ellipses, rectangles, polygons etc.</s>
+<s f="imagesettile" u="bool imagesettile(resource image, resource tile)">Set the tile image to $tile when filling $image with the &quot;IMG_COLOR_TILED&quot; color</s>
+<s f="imagestring" u="bool imagestring(resource im, int font, int x, int y, string str, int col)">Draw a string horizontally</s>
+<s f="imagestringup" u="bool imagestringup(resource im, int font, int x, int y, string str, int col)">Draw a string vertically - rotated 90 degrees counter-clockwise</s>
+<s f="imagesx" u="int imagesx(resource im)">Get image width</s>
+<s f="imagesy" u="int imagesy(resource im)">Get image height</s>
+<s f="imagetruecolortopalette" u="void imagetruecolortopalette(resource im, bool ditherFlag, int colorsWanted)">Convert a true colour image to a palette based image with a number of colours, optionally using dithering.</s>
+<s f="imagettfbbox" u="array imagettfbbox(float size, float angle, string font_file, string text)">Give the bounding box of a text using TrueType fonts</s>
+<s f="imagettftext" u="array imagettftext(resource im, float size, float angle, int x, int y, int col, string font_file, string text)">Write text to the image using a TrueType font</s>
+<s f="imagetypes" u="int imagetypes(void)">Return the types of images supported in a bitfield - 1=GIF, 2=JPEG, 4=PNG, 8=WBMP, 16=XPM</s>
+<s f="imagewbmp" u="bool imagewbmp(resource im [, string filename, [, int foreground]])">Output WBMP image to browser or file</s>
+<s f="imagexbm" u="int imagexbm(int im, string filename [, int foreground])">Output XBM image to browser or file</s>
+<s f="bindtextdomain" u="string bindtextdomain(string domain_name, string dir)">Bind to the text domain domain_name, looking for translations in dir. Returns the current domain</s>
+<s f="dcgettext" u="binary dcgettext(string domain_name, string msgid, int category)">Return the translation of msgid for domain_name and category, or msgid unaltered if a translation does not exist</s>
+<s f="dgettext" u="binary dgettext(string domain_name, string msgid)">Return the translation of msgid for domain_name, or msgid unaltered if a translation does not exist</s>
+<s f="gettext" u="binary gettext(string msgid)">Return the translation of msgid for the current domain, or msgid unaltered if a translation does not exist</s>
+<s f="ngettext" u="binary ngettext(string msgid1, string msgid2, int count)">Plural version of gettext()</s>
+<s f="textdomain" u="string textdomain(string domain)">Set the textdomain to &quot;domain&quot;. Returns the current domain</s>
+<s f="gmp_abs" u="resource gmp_abs(resource a)">Calculates absolute value</s>
+<s f="gmp_add" u="resource gmp_add(resource a, resource b)">Add a and b</s>
+<s f="gmp_and" u="resource gmp_and(resource a, resource b)">Calculates logical AND of a and b</s>
+<s f="gmp_clrbit" u="void gmp_clrbit(resource &amp;a, int index)">Clears bit in a</s>
+<s f="gmp_cmp" u="int gmp_cmp(resource a, resource b)">Compares two numbers</s>
+<s f="gmp_com" u="resource gmp_com(resource a)">Calculates one's complement of a</s>
+<s f="gmp_div_q" u="resource gmp_div_q(resource a, resource b [, int round])">Divide a by b, returns quotient only</s>
+<s f="gmp_div_qr" u="array gmp_div_qr(resource a, resource b [, int round])">Divide a by b, returns quotient and reminder</s>
+<s f="gmp_div_r" u="resource gmp_div_r(resource a, resource b [, int round])">Divide a by b, returns reminder only</s>
+<s f="gmp_divexact" u="resource gmp_divexact(resource a, resource b)">Divide a by b using exact division algorithm</s>
+<s f="gmp_fact" u="resource gmp_fact(int a)">Calculates factorial function</s>
+<s f="gmp_gcd" u="resource gmp_gcd(resource a, resource b)">Computes greatest common denominator (gcd) of a and b</s>
+<s f="gmp_gcdext" u="array gmp_gcdext(resource a, resource b)">Computes G, S, and T, such that AS + BT = G = `gcd' (A, B)</s>
+<s f="gmp_hamdist" u="int gmp_hamdist(resource a, resource b)">Calculates hamming distance between a and b</s>
+<s f="gmp_init" u="resource gmp_init(mixed number [, int base])">Initializes GMP number</s>
+<s f="gmp_intval" u="int gmp_intval(resource gmpnumber)">Gets signed long value of GMP number</s>
+<s f="gmp_invert" u="resource gmp_invert(resource a, resource b)">Computes the inverse of a modulo b</s>
+<s f="gmp_jacobi" u="int gmp_jacobi(resource a, resource b)">Computes Jacobi symbol</s>
+<s f="gmp_legendre" u="int gmp_legendre(resource a, resource b)">Computes Legendre symbol</s>
+<s f="gmp_mod" u="resource gmp_mod(resource a, resource b)">Computes a modulo b</s>
+<s f="gmp_mul" u="resource gmp_mul(resource a, resource b)">Multiply a and b</s>
+<s f="gmp_neg" u="resource gmp_neg(resource a)">Negates a number</s>
+<s f="gmp_nextprime" u="resource gmp_nextprime(resource a)">Finds next prime of a</s>
+<s f="gmp_or" u="resource gmp_or(resource a, resource b)">Calculates logical OR of a and b</s>
+<s f="gmp_perfect_square" u="bool gmp_perfect_square(resource a)">Checks if a is an exact square</s>
+<s f="gmp_popcount" u="int gmp_popcount(resource a)">Calculates the population count of a</s>
+<s f="gmp_pow" u="resource gmp_pow(resource base, int exp)">Raise base to power exp</s>
+<s f="gmp_powm" u="resource gmp_powm(resource base, resource exp, resource mod)">Raise base to power exp and take result modulo mod</s>
+<s f="gmp_prob_prime" u="int gmp_prob_prime(resource a[, int reps])">Checks if a is &quot;probably prime&quot;</s>
+<s f="gmp_random" u="resource gmp_random([int limiter])">Gets random number</s>
+<s f="gmp_scan0" u="int gmp_scan0(resource a, int start)">Finds first zero bit</s>
+<s f="gmp_scan1" u="int gmp_scan1(resource a, int start)">Finds first non-zero bit</s>
+<s f="gmp_setbit" u="void gmp_setbit(resource &amp;a, int index[, bool set_clear])">Sets or clear bit in a</s>
+<s f="gmp_sign" u="int gmp_sign(resource a)">Gets the sign of the number</s>
+<s f="gmp_sqrt" u="resource gmp_sqrt(resource a)">Takes integer part of square root of a</s>
+<s f="gmp_sqrtrem" u="array gmp_sqrtrem(resource a)">Square root with remainder</s>
+<s f="gmp_strval" u="string gmp_strval(resource gmpnumber [, int base])">Gets string representation of GMP number</s>
+<s f="gmp_sub" u="resource gmp_sub(resource a, resource b)">Subtract b from a</s>
+<s f="gmp_testbit" u="bool gmp_testbit(resource a, int index)">Tests if bit is set in a</s>
+<s f="gmp_xor" u="resource gmp_xor(resource a, resource b)">Calculates logical exclusive OR of a and b</s>
+<s f="hash" u="string hash(string algo, string data[, bool raw_output = false])">Generate a hash of a given input string Returns lowercase hexits by default</s>
+<s f="hash_algos" u="array hash_algos(void)">Return a list of registered hashing algorithms</s>
+<s f="hash_file" u="string hash_file(string algo, string filename[, bool raw_output = false])">Generate a hash of a given file Returns lowercase hexits by default</s>
+<s f="hash_final" u="string hash_final(resource context[, bool raw_output=false])">Output resulting digest</s>
+<s f="hash_hmac" u="string hash_hmac(string algo, string data, string key[, bool raw_output = false])">Generate a hash of a given input string with a key using HMAC Returns lowercase hexits by default</s>
+<s f="hash_hmac_file" u="string hash_hmac_file(string algo, string filename, string key[, bool raw_output = false])">Generate a hash of a given file with a key using HMAC Returns lowercase hexits by default</s>
+<s f="hash_init" u="resource hash_init(string algo[, int options, string key])">Initialize a hashing context</s>
+<s f="hash_update" u="bool hash_update(resource context, string data)">Pump data into the hashing algorithm</s>
+<s f="hash_update_file" u="bool hash_update_file(resource context, string filename[, resource context])">Pump data into the hashing algorithm from a file</s>
+<s f="hash_update_stream" u="int hash_update_stream(resource context, resource handle[, integer length])">Pump data into the hashing algorithm from an open stream</s>
+<s f="iconv" u="string iconv(string in_charset, string out_charset, string str)">Returns str converted to the out_charset character set</s>
+<s f="iconv_get_encoding" u="mixed iconv_get_encoding([string type])">Get internal encoding and output encoding for ob_iconv_handler()</s>
+<s f="iconv_mime_decode" u="string iconv_mime_decode(string encoded_string [, int mode, string charset])">Decodes a mime header field</s>
+<s f="iconv_mime_decode_headers" u="array iconv_mime_decode_headers(string headers [, int mode, string charset])">Decodes multiple mime header fields</s>
+<s f="iconv_mime_encode" u="string iconv_mime_encode(string field_name, string field_value [, array preference])">Composes a mime header field with field_name and field_value in a specified scheme</s>
+<s f="iconv_set_encoding" u="bool iconv_set_encoding(string type, string charset)">Sets internal encoding and output encoding for ob_iconv_handler()</s>
+<s f="iconv_strlen" u="int iconv_strlen(string str [, string charset])">Returns the character count of str</s>
+<s f="iconv_strpos" u="int iconv_strpos(string haystack, string needle [, int offset [, string charset]])">Finds position of first occurrence of needle within part of haystack beginning with offset</s>
+<s f="iconv_strrpos" u="int iconv_strrpos(string haystack, string needle [, string charset])">Finds position of last occurrence of needle within part of haystack beginning with offset</s>
+<s f="iconv_substr" u="string iconv_substr(string str, int offset, [int length, string charset])">Returns specified part of a string</s>
+<s f="imap_8bit" u="string imap_8bit(string text)">Convert an 8-bit string to a quoted-printable string</s>
+<s f="imap_alerts" u="array imap_alerts(void)">Returns an array of all IMAP alerts that have been generated since the last page load or since the last imap_alerts() call, whichever came last. The alert stack is cleared after imap_alerts() is called.</s>
+<s f="imap_append" u="bool imap_append(resource stream_id, string folder, string message [, string options])">Append a new message to a specified mailbox</s>
+<s f="imap_base64" u="string imap_base64(string text)">Decode BASE64 encoded text</s>
+<s f="imap_binary" u="string imap_binary(string text)">Convert an 8bit string to a base64 string</s>
+<s f="imap_body" u="string imap_body(resource stream_id, int msg_no [, int options])">Read the message body</s>
+<s f="imap_bodystruct" u="object imap_bodystruct(resource stream_id, int msg_no, string section)">Read the structure of a specified body section of a specific message</s>
+<s f="imap_check" u="object imap_check(resource stream_id)">Get mailbox properties</s>
+<s f="imap_clearflag_full" u="bool imap_clearflag_full(resource stream_id, string sequence, string flag [, int options])">Clears flags on messages</s>
+<s f="imap_close" u="bool imap_close(resource stream_id [, int options])">Close an IMAP stream</s>
+<s f="imap_createmailbox" u="bool imap_createmailbox(resource stream_id, string mailbox)">Create a new mailbox</s>
+<s f="imap_delete" u="bool imap_delete(resource stream_id, int msg_no [, int options])">Mark a message for deletion</s>
+<s f="imap_deletemailbox" u="bool imap_deletemailbox(resource stream_id, string mailbox)">Delete a mailbox</s>
+<s f="imap_errors" u="array imap_errors(void)">Returns an array of all IMAP errors generated since the last page load, or since the last imap_errors() call, whichever came last. The error stack is cleared after imap_errors() is called.</s>
+<s f="imap_expunge" u="bool imap_expunge(resource stream_id)">Permanently delete all messages marked for deletion</s>
+<s f="imap_fetch_overview" u="array imap_fetch_overview(resource stream_id, int msg_no [, int options])">Read an overview of the information in the headers of the given message sequence</s>
+<s f="imap_fetchbody" u="string imap_fetchbody(resource stream_id, int msg_no, string section [, int options])">Get a specific body section</s>
+<s f="imap_fetchheader" u="string imap_fetchheader(resource stream_id, int msg_no [, int options])">Get the full unfiltered header for a message</s>
+<s f="imap_fetchstructure" u="object imap_fetchstructure(resource stream_id, int msg_no [, int options])">Read the full structure of a message</s>
+<s f="imap_get_quota" u="array imap_get_quota(resource stream_id, string qroot)">Returns the quota set to the mailbox account qroot</s>
+<s f="imap_get_quotaroot" u="array imap_get_quotaroot(resource stream_id, string mbox)">Returns the quota set to the mailbox account mbox</s>
+<s f="imap_getacl" u="array imap_getacl(resource stream_id, string mailbox)">Gets the ACL for a given mailbox</s>
+<s f="imap_getmailboxes" u="array imap_getmailboxes(resource stream_id, string ref, string pattern)">Reads the list of mailboxes and returns a full array of objects containing name, attributes, and delimiter</s>
+<s f="imap_getsubscribed" u="array imap_getsubscribed(resource stream_id, string ref, string pattern)">Return a list of subscribed mailboxes, in the same format as imap_getmailboxes()</s>
+<s f="imap_headerinfo" u="object imap_headerinfo(resource stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])">Read the headers of the message</s>
+<s f="imap_headers" u="array imap_headers(resource stream_id)">Returns headers for all messages in a mailbox</s>
+<s f="imap_last_error" u="string imap_last_error(void)">Returns the last error that was generated by an IMAP function. The error stack is NOT cleared after this call.</s>
+<s f="imap_list" u="array imap_list(resource stream_id, string ref, string pattern)">Read the list of mailboxes</s>
+<s f="imap_lsub" u="array imap_lsub(resource stream_id, string ref, string pattern)">Return a list of subscribed mailboxes</s>
+<s f="imap_mail" u="bool imap_mail(string to, string subject, string message [, string additional_headers [, string cc [, string bcc [, string rpath]]]])">Send an email message</s>
+<s f="imap_mail_compose" u="string imap_mail_compose(array envelope, array body)">Create a MIME message based on given envelope and body sections</s>
+<s f="imap_mail_copy" u="bool imap_mail_copy(resource stream_id, int msg_no, string mailbox [, int options])">Copy specified message to a mailbox</s>
+<s f="imap_mail_move" u="bool imap_mail_move(resource stream_id, int msg_no, string mailbox [, int options])">Move specified message to a mailbox</s>
+<s f="imap_mailboxmsginfo" u="object imap_mailboxmsginfo(resource stream_id)">Returns info about the current mailbox</s>
+<s f="imap_mime_header_decode" u="array imap_mime_header_decode(string str)">Decode mime header element in accordance with RFC 2047 and return array of objects containing 'charset' encoding and decoded 'text'</s>
+<s f="imap_msgno" u="int imap_msgno(resource stream_id, int unique_msg_id)">Get the sequence number associated with a UID</s>
+<s f="imap_num_msg" u="int imap_num_msg(resource stream_id)">Gives the number of messages in the current mailbox</s>
+<s f="imap_num_recent" u="int imap_num_recent(resource stream_id)">Gives the number of recent messages in current mailbox</s>
+<s f="imap_open" u="resource imap_open(string mailbox, string user, string password [, int options [, int n_retries]])">Open an IMAP stream to a mailbox</s>
+<s f="imap_ping" u="bool imap_ping(resource stream_id)">Check if the IMAP stream is still active</s>
+<s f="imap_qprint" u="string imap_qprint(string text)">Convert a quoted-printable string to an 8-bit string</s>
+<s f="imap_renamemailbox" u="bool imap_renamemailbox(resource stream_id, string old_name, string new_name)">Rename a mailbox</s>
+<s f="imap_reopen" u="bool imap_reopen(resource stream_id, string mailbox [, int options [, int n_retries]])">Reopen an IMAP stream to a new mailbox</s>
+<s f="imap_rfc822_parse_adrlist" u="array imap_rfc822_parse_adrlist(string address_string, string default_host)">Parses an address string</s>
+<s f="imap_rfc822_parse_headers" u="object imap_rfc822_parse_headers(string headers [, string default_host])">Parse a set of mail headers contained in a string, and return an object similar to imap_headerinfo()</s>
+<s f="imap_rfc822_write_address" u="string imap_rfc822_write_address(string mailbox, string host, string personal)">Returns a properly formatted email address given the mailbox, host, and personal info</s>
+<s f="imap_savebody" u="bool imap_savebody(resource stream_id, string|resource file, int msg_no[, string section = &quot;&quot;[, int options = 0]])">Save a specific body section to a file</s>
+<s f="imap_scan" u="array imap_scan(resource stream_id, string ref, string pattern, string content)">Read list of mailboxes containing a certain string</s>
+<s f="imap_search" u="array imap_search(resource stream_id, string criteria [, int options [, string charset]])">Return a list of messages matching the given criteria</s>
+<s f="imap_set_quota" u="bool imap_set_quota(resource stream_id, string qroot, int mailbox_size)">Will set the quota for qroot mailbox</s>
+<s f="imap_setacl" u="bool imap_setacl(resource stream_id, string mailbox, string id, string rights)">Sets the ACL for a given mailbox</s>
+<s f="imap_setflag_full" u="bool imap_setflag_full(resource stream_id, string sequence, string flag [, int options])">Sets flags on messages</s>
+<s f="imap_sort" u="array imap_sort(resource stream_id, int criteria, int reverse [, int options [, string search_criteria [, string charset]]])">Sort an array of message headers, optionally including only messages that meet specified criteria.</s>
+<s f="imap_status" u="object imap_status(resource stream_id, string mailbox, int options)">Get status info from a mailbox</s>
+<s f="imap_subscribe" u="bool imap_subscribe(resource stream_id, string mailbox)">Subscribe to a mailbox</s>
+<s f="imap_thread" u="array imap_thread(resource stream_id [, int options])">Return threaded by REFERENCES tree</s>
+<s f="imap_timeout" u="mixed imap_timeout(int timeout_type [, int timeout])">Set or fetch imap timeout</s>
+<s f="imap_uid" u="int imap_uid(resource stream_id, int msg_no)">Get the unique message id associated with a standard sequential message number</s>
+<s f="imap_undelete" u="bool imap_undelete(resource stream_id, int msg_no)">Remove the delete flag from a message</s>
+<s f="imap_unsubscribe" u="bool imap_unsubscribe(resource stream_id, string mailbox)">Unsubscribe from a mailbox</s>
+<s f="imap_utf7_decode" u="string imap_utf7_decode(string buf)">Decode a modified UTF-7 string</s>
+<s f="imap_utf7_encode" u="string imap_utf7_encode(string buf)">Encode a string in modified UTF-7</s>
+<s f="imap_utf8" u="string imap_utf8(string mime_encoded_text)">Convert a mime-encoded text to UTF-8</s>
+<s f="ibase_blob_add" u="bool ibase_blob_add(resource blob_handle, string data)">Add data into created blob</s>
+<s f="ibase_blob_cancel" u="bool ibase_blob_cancel(resource blob_handle)">Cancel creating blob</s>
+<s f="ibase_blob_close" u="string ibase_blob_close(resource blob_handle)">Close blob</s>
+<s f="ibase_blob_create" u="resource ibase_blob_create([resource link_identifier])">Create blob for adding data</s>
+<s f="ibase_blob_echo" u="bool ibase_blob_echo([ resource link_identifier, ] string blob_id)">Output blob contents to browser</s>
+<s f="ibase_blob_get" u="string ibase_blob_get(resource blob_handle, int len)">Get len bytes data from open blob</s>
+<s f="ibase_blob_import" u="string ibase_blob_import([ resource link_identifier, ] resource file)">Create blob, copy file in it, and close it</s>
+<s f="ibase_blob_info" u="array ibase_blob_info([ resource link_identifier, ] string blob_id)">Return blob length and other useful info</s>
+<s f="ibase_blob_open" u="resource ibase_blob_open([ resource link_identifier, ] string blob_id)">Open blob for retrieving data parts</s>
+<s f="ibase_free_event_handler" u="bool ibase_free_event_handler(resource event)">Frees the event handler set by ibase_set_event_handler()</s>
+<s f="ibase_set_event_handler" u="resource ibase_set_event_handler([resource link_identifier,] callback handler, string event [, string event [, ...]])">Register the callback for handling each of the named events</s>
+<s f="ibase_wait_event" u="string ibase_wait_event([resource link_identifier,] string event [, string event [, ...]])">Waits for any one of the passed Interbase events to be posted by the database, and returns its name</s>
+<s f="ibase_affected_rows" u="int ibase_affected_rows( [ resource link_identifier ] )">Returns the number of rows affected by the previous INSERT, UPDATE or DELETE statement</s>
+<s f="ibase_execute" u="mixed ibase_execute(resource query [, mixed bind_arg [, mixed bind_arg [, ...]]])">Execute a previously prepared query</s>
+<s f="ibase_fetch_assoc" u="array ibase_fetch_assoc(resource result [, int fetch_flags])">Fetch a row  from the results of a query</s>
+<s f="ibase_fetch_object" u="object ibase_fetch_object(resource result [, int fetch_flags])">Fetch a object from the results of a query</s>
+<s f="ibase_fetch_row" u="array ibase_fetch_row(resource result [, int fetch_flags])">Fetch a row  from the results of a query</s>
+<s f="ibase_field_info" u="array ibase_field_info(resource query_result, int field_number)">Get information about a field</s>
+<s f="ibase_free_query" u="bool ibase_free_query(resource query)">Free memory used by a query</s>
+<s f="ibase_free_result" u="bool ibase_free_result(resource result)">Free the memory used by a result</s>
+<s f="ibase_name_result" u="bool ibase_name_result(resource result, string name)">Assign a name to a result for use with ... WHERE CURRENT OF &lt;name&gt; statements</s>
+<s f="ibase_num_fields" u="int ibase_num_fields(resource query_result)">Get the number of fields in result</s>
+<s f="ibase_num_params" u="int ibase_num_params(resource query)">Get the number of params in a prepared query</s>
+<s f="ibase_num_rows" u="int ibase_num_rows( resource result_identifier )">Return the number of rows that are available in a result</s>
+<s f="ibase_param_info" u="array ibase_param_info(resource query, int field_number)">Get information about a parameter</s>
+<s f="ibase_prepare" u="resource ibase_prepare([resource link_identifier, ] string query)">Prepare a query for later execution</s>
+<s f="ibase_query" u="mixed ibase_query([resource link_identifier, [ resource link_identifier, ]] string query [, mixed bind_arg [, mixed bind_arg [, ...]]])">Execute a query</s>
+<s f="ibase_add_user" u="bool ibase_add_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])">Add a user to security database</s>
+<s f="ibase_backup" u="mixed ibase_backup(resource service_handle, string source_db, string dest_file [, int options [, bool verbose]])">Initiates a backup task in the service manager and returns immediately</s>
+<s f="ibase_db_info" u="string ibase_db_info(resource service_handle, string db, int action [, int argument])">Request statistics about a database</s>
+<s f="ibase_delete_user" u="bool ibase_delete_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])">Delete a user from security database</s>
+<s f="ibase_maintain_db" u="bool ibase_maintain_db(resource service_handle, string db, int action [, int argument])">Execute a maintenance command on the database server</s>
+<s f="ibase_modify_user" u="bool ibase_modify_user(resource service_handle, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])">Modify a user in security database</s>
+<s f="ibase_restore" u="mixed ibase_restore(resource service_handle, string source_file, string dest_db [, int options [, bool verbose]])">Initiates a restore task in the service manager and returns immediately</s>
+<s f="ibase_server_info" u="string ibase_server_info(resource service_handle, int action)">Request information about a database server</s>
+<s f="ibase_service_attach" u="resource ibase_service_attach(string host, string dba_username, string dba_password)">Connect to the service manager</s>
+<s f="ibase_service_detach" u="bool ibase_service_detach(resource service_handle)">Disconnect from the service manager</s>
+<s f="ibase_close" u="bool ibase_close([resource link_identifier])">Close an InterBase connection</s>
+<s f="ibase_commit" u="bool ibase_commit( resource link_identifier )">Commit transaction</s>
+<s f="ibase_commit_ret" u="bool ibase_commit_ret( resource link_identifier )">Commit transaction and retain the transaction context</s>
+<s f="ibase_connect" u="resource ibase_connect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])">Open a connection to an InterBase database</s>
+<s f="ibase_drop_db" u="bool ibase_drop_db([resource link_identifier])">Drop an InterBase database</s>
+<s f="ibase_errcode" u="int ibase_errcode(void)">Return error code</s>
+<s f="ibase_errmsg" u="string ibase_errmsg(void)">Return error message</s>
+<s f="ibase_gen_id" u="int ibase_gen_id(string generator [, int increment [, resource link_identifier ]])">Increments the named generator and returns its new value</s>
+<s f="ibase_pconnect" u="resource ibase_pconnect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])">Open a persistent connection to an InterBase database</s>
+<s f="ibase_rollback" u="bool ibase_rollback( resource link_identifier )">Rollback transaction</s>
+<s f="ibase_rollback_ret" u="bool ibase_rollback_ret( resource link_identifier )">Rollback transaction and retain the transaction context</s>
+<s f="ibase_trans" u="resource ibase_trans([int trans_args [, resource link_identifier [, ... ], int trans_args [, resource link_identifier [, ... ]] [, ...]]])">Start a transaction over one or several databases</s>
+<s f="json_decode" u="mixed json_decode(string json [, bool assoc])">Decodes the JSON representation into a PHP value</s>
+<s f="json_encode" u="string json_encode(mixed data)">Returns the JSON representation of a value</s>
+<s f="ldap_8859_to_t61" u="string ldap_8859_to_t61(string value)">Translate 8859 characters to t61 characters</s>
+<s f="ldap_add" u="bool ldap_add(resource link, string dn, array entry)">Add entries to LDAP directory</s>
+<s f="ldap_bind" u="bool ldap_bind(resource link [, string dn, string password])">Bind to LDAP directory</s>
+<s f="ldap_compare" u="bool ldap_compare(resource link, string dn, string attr, string value)">Determine if an entry has a specific value for one of its attributes</s>
+<s f="ldap_connect" u="resource ldap_connect([string host [, int port]])">Connect to an LDAP server</s>
+<s f="ldap_count_entries" u="int ldap_count_entries(resource link, resource result)">Count the number of entries in a search result</s>
+<s f="ldap_delete" u="bool ldap_delete(resource link, string dn)">Delete an entry from a directory</s>
+<s f="ldap_dn2ufn" u="string ldap_dn2ufn(string dn)">Convert DN to User Friendly Naming format</s>
+<s f="ldap_err2str" u="string ldap_err2str(int errno)">Convert error number to error string</s>
+<s f="ldap_errno" u="int ldap_errno(resource link)">Get the current ldap error number</s>
+<s f="ldap_error" u="string ldap_error(resource link)">Get the current ldap error string</s>
+<s f="ldap_explode_dn" u="array ldap_explode_dn(string dn, int with_attrib)">Splits DN into its component parts</s>
+<s f="ldap_first_attribute" u="string ldap_first_attribute(resource link, resource result_entry, int ber)">Return first attribute</s>
+<s f="ldap_first_entry" u="resource ldap_first_entry(resource link, resource result)">Return first result id</s>
+<s f="ldap_first_reference" u="resource ldap_first_reference(resource link, resource result)">Return first reference</s>
+<s f="ldap_free_result" u="bool ldap_free_result(resource result)">Free result memory</s>
+<s f="ldap_get_attributes" u="array ldap_get_attributes(resource link, resource result_entry)">Get attributes from a search result entry</s>
+<s f="ldap_get_dn" u="string ldap_get_dn(resource link, resource result_entry)">Get the DN of a result entry</s>
+<s f="ldap_get_entries" u="array ldap_get_entries(resource link, resource result)">Get all result entries</s>
+<s f="ldap_get_option" u="bool ldap_get_option(resource link, int option, mixed retval)">Get the current value of various session-wide parameters</s>
+<s f="ldap_get_values_len" u="array ldap_get_values_len(resource link, resource result_entry, string attribute)">Get all values with lengths from a result entry</s>
+<s f="ldap_list" u="resource ldap_list(resource link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])">Single-level search</s>
+<s f="ldap_mod_add" u="bool ldap_mod_add(resource link, string dn, array entry)">Add attribute values to current</s>
+<s f="ldap_mod_del" u="bool ldap_mod_del(resource link, string dn, array entry)">Delete attribute values</s>
+<s f="ldap_mod_replace" u="bool ldap_mod_replace(resource link, string dn, array entry)">Replace attribute values with new ones</s>
+<s f="ldap_next_attribute" u="string ldap_next_attribute(resource link, resource result_entry, resource ber)">Get the next attribute in result</s>
+<s f="ldap_next_entry" u="resource ldap_next_entry(resource link, resource result_entry)">Get next result entry</s>
+<s f="ldap_next_reference" u="resource ldap_next_reference(resource link, resource reference_entry)">Get next reference</s>
+<s f="ldap_parse_reference" u="bool ldap_parse_reference(resource link, resource reference_entry, array referrals)">Extract information from reference entry</s>
+<s f="ldap_parse_result" u="bool ldap_parse_result(resource link, resource result, int errcode, string matcheddn, string errmsg, array referrals)">Extract information from result</s>
+<s f="ldap_read" u="resource ldap_read(resource link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])">Read an entry</s>
+<s f="ldap_sasl_bind" u="bool ldap_sasl_bind(resource link [, string binddn, string password, string sasl_mech, string sasl_realm, string sasl_authz_id, string props])">Bind to LDAP directory using SASL</s>
+<s f="ldap_search" u="resource ldap_search(resource link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])">Search LDAP tree under base_dn</s>
+<s f="ldap_set_option" u="bool ldap_set_option(resource link, int option, mixed newval)">Set the value of various session-wide parameters</s>
+<s f="ldap_set_rebind_proc" u="bool ldap_set_rebind_proc(resource link, string callback)">Set a callback function to do re-binds on referral chasing.</s>
+<s f="ldap_sort" u="bool ldap_sort(resource link, resource result, string sortfilter)">Sort LDAP result entries</s>
+<s f="ldap_start_tls" u="bool ldap_start_tls(resource link)">Start TLS</s>
+<s f="ldap_t61_to_8859" u="string ldap_t61_to_8859(string value)">Translate t61 characters to 8859 characters</s>
+<s f="ldap_unbind" u="bool ldap_unbind(resource link)">Unbind from LDAP directory</s>
+<s f="libxml_clear_errors" u="void libxml_clear_errors()">Clear last error from libxml</s>
+<s f="libxml_get_errors" u="object libxml_get_errors()">Retrieve array of errors</s>
+<s f="libxml_get_last_error" u="object libxml_get_last_error()">Retrieve last error from libxml</s>
+<s f="libxml_set_streams_context" u="void libxml_set_streams_context(resource streams_context)">Set the streams context for the next libxml document load or write</s>
+<s f="libxml_use_internal_errors" u="void libxml_use_internal_errors([boolean use_errors])">Disable libxml errors and allow user to fetch error information as needed</s>
+<s f="mb_check_encoding" u="bool mb_check_encoding([string var[, string encoding]])">Check if the string is valid for the specified encoding</s>
+<s f="mb_convert_case" u="string mb_convert_case(string sourcestring, int mode [, string encoding])">Returns a case-folded version of sourcestring</s>
+<s f="mb_convert_encoding" u="string mb_convert_encoding(string str, string to-encoding [, mixed from-encoding])">Returns converted string in desired encoding</s>
+<s f="mb_convert_kana" u="string mb_convert_kana(string str [, string option] [, string encoding])">Conversion between full-width character and half-width character (Japanese)</s>
+<s f="mb_convert_variables" u="string mb_convert_variables(string to-encoding, mixed from-encoding [, mixed ...])">Converts the string resource in variables to desired encoding</s>
+<s f="mb_decode_mimeheader" u="string mb_decode_mimeheader(string string)">Decodes the MIME &quot;encoded-word&quot; in the string</s>
+<s f="mb_decode_numericentity" u="string mb_decode_numericentity(string string, array convmap [, string encoding])">Converts HTML numeric entities to character code</s>
+<s f="mb_detect_encoding" u="string mb_detect_encoding(string str [, mixed encoding_list [, bool strict]])">Encodings of the given string is returned (as a string)</s>
+<s f="mb_encode_mimeheader" u="string mb_encode_mimeheader(string str [, string charset [, string transfer-encoding [, string linefeed [, int indent]]]])">Converts the string to MIME &quot;encoded-word&quot; in the format of =?charset?(B|Q)?encoded_string?=</s>
+<s f="mb_encode_numericentity" u="string mb_encode_numericentity(string string, array convmap [, string encoding])">Converts specified characters to HTML numeric entities</s>
+<s f="mb_get_info" u="mixed mb_get_info([string type])">Returns the current settings of mbstring</s>
+<s f="mb_http_input" u="mixed mb_http_input([string type])">Returns the input encoding</s>
+<s f="mb_http_output" u="string mb_http_output([string encoding])">Sets the current output_encoding or returns the current output_encoding as a string</s>
+<s f="mb_internal_encoding" u="string mb_internal_encoding([string encoding])">Sets the current internal encoding or Returns the current internal encoding as a string</s>
+<s f="mb_language" u="string mb_language([string language])">Sets the current language or Returns the current language as a string</s>
+<s f="mb_list_encodings" u="mixed mb_list_encodings([string alias_encoding])">Returns an array of all supported entity encodings or Returns the entity encoding as a string</s>
+<s f="mb_list_encodings_alias_names" u="array mb_list_encodings_alias_names([string encoding])">Returns an array of all supported alias encodings</s>
+<s f="mb_list_mime_names" u="mixed mb_list_mime_names([string encoding])">Returns an array or string of all supported mime names</s>
+<s f="mb_output_handler" u="string mb_output_handler(string contents, int status)">Returns string in output buffer converted to the http_output encoding</s>
+<s f="mb_parse_str" u="bool mb_parse_str(string encoded_string [, array result])">Parses GET/POST/COOKIE data and sets global variables</s>
+<s f="mb_preferred_mime_name" u="string mb_preferred_mime_name(string encoding)">Return the preferred MIME name (charset) as a string</s>
+<s f="mb_send_mail" u="int mb_send_mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])">*  Sends an email message with MIME scheme</s>
+<s f="mb_strcut" u="string mb_strcut(string str, int start [, int length [, string encoding]])">Returns part of a string</s>
+<s f="mb_strimwidth" u="string mb_strimwidth(string str, int start, int width [, string trimmarker [, string encoding]])">Trim the string in terminal width</s>
+<s f="mb_stripos" u="int mb_stripos(string haystack, string needle [, int offset [, string encoding]])">Finds position of first occurrence of a string within another, case insensitive</s>
+<s f="mb_stristr" u="string mb_stristr(string haystack, string needle[, bool part[, string encoding]])">Finds first occurrence of a string within another, case insensitive</s>
+<s f="mb_strlen" u="int mb_strlen(string str [, string encoding])">Get character numbers of a string</s>
+<s f="mb_strpos" u="int mb_strpos(string haystack, string needle [, int offset [, string encoding]])">Find position of first occurrence of a string within another</s>
+<s f="mb_strrchr" u="string mb_strrchr(string haystack, string needle[, bool part[, string encoding]])">Finds the last occurrence of a character in a string within another</s>
+<s f="mb_strrichr" u="string mb_strrichr(string haystack, string needle[, bool part[, string encoding]])">Finds the last occurrence of a character in a string within another, case insensitive</s>
+<s f="mb_strripos" u="int mb_strripos(string haystack, string needle [, int offset [, string encoding]])">Finds position of last occurrence of a string within another, case insensitive</s>
+<s f="mb_strrpos" u="int mb_strrpos(string haystack, string needle [, int offset [, string encoding]])">Find position of last occurrence of a string within another</s>
+<s f="mb_strstr" u="string mb_strstr(string haystack, string needle[, bool part[, string encoding]])">Finds first occurrence of a string within another</s>
+<s f="mb_strtolower" u="string mb_strtolower(string sourcestring [, string encoding])">*  Returns a lowercased version of sourcestring</s>
+<s f="mb_strtoupper" u="string mb_strtoupper(string sourcestring [, string encoding])">*  Returns a uppercased version of sourcestring</s>
+<s f="mb_strwidth" u="int mb_strwidth(string str [, string encoding])">Gets terminal width of a string</s>
+<s f="mb_substitute_character" u="mixed mb_substitute_character([mixed substchar])">Sets the current substitute_character or returns the current substitute_character</s>
+<s f="mb_substr" u="string mb_substr(string str, int start [, int length [, string encoding]])">Returns part of a string</s>
+<s f="mb_substr_count" u="int mb_substr_count(string haystack, string needle [, string encoding])">Count the number of substring occurrences</s>
+<s f="mb_ereg" u="int mb_ereg(string pattern, string string [, array registers])">Regular expression match for multibyte string</s>
+<s f="mb_ereg_match" u="bool mb_ereg_match(string pattern, string string [,string option])">Regular expression match for multibyte string</s>
+<s f="mb_ereg_replace" u="string mb_ereg_replace(string pattern, string replacement, string string [, string option])">Replace regular expression for multibyte string</s>
+<s f="mb_ereg_search" u="bool mb_ereg_search([string pattern[, string option]])">Regular expression search for multibyte string</s>
+<s f="mb_ereg_search_getpos" u="int mb_ereg_search_getpos(void)">Get search start position</s>
+<s f="mb_ereg_search_getregs" u="array mb_ereg_search_getregs(void)">Get matched substring of the last time</s>
+<s f="mb_ereg_search_init" u="bool mb_ereg_search_init(string string [, string pattern[, string option]])">Initialize string and regular expression for search.</s>
+<s f="mb_ereg_search_pos" u="array mb_ereg_search_pos([string pattern[, string option]])">Regular expression search for multibyte string</s>
+<s f="mb_ereg_search_regs" u="array mb_ereg_search_regs([string pattern[, string option]])">Regular expression search for multibyte string</s>
+<s f="mb_ereg_search_setpos" u="bool mb_ereg_search_setpos(int position)">Set search start position</s>
+<s f="mb_eregi" u="int mb_eregi(string pattern, string string [, array registers])">Case-insensitive regular expression match for multibyte string</s>
+<s f="mb_eregi_replace" u="string mb_eregi_replace(string pattern, string replacement, string string)">Case insensitive replace regular expression for multibyte string</s>
+<s f="mb_regex_encoding" u="string mb_regex_encoding([string encoding])">Returns the current encoding for regex as a string.</s>
+<s f="mb_regex_set_options" u="string mb_regex_set_options([string options])">Set or get the default options for mbregex functions</s>
+<s f="mb_split" u="array mb_split(string pattern, string string [, int limit])">split multibyte string into array by regular expression</s>
+<s f="mcrypt_cbc" u="string mcrypt_cbc(int cipher, string key, string data, int mode, string iv)">CBC crypt/decrypt data using key key with cipher cipher starting with iv</s>
+<s f="mcrypt_cfb" u="string mcrypt_cfb(int cipher, string key, string data, int mode, string iv)">CFB crypt/decrypt data using key key with cipher cipher starting with iv</s>
+<s f="mcrypt_create_iv" u="binary mcrypt_create_iv(int size, int source)">Create an initialization vector (IV)</s>
+<s f="mcrypt_decrypt" u="string mcrypt_decrypt(string cipher, string key, string data, string mode, string iv)">OFB crypt/decrypt data using key key with cipher cipher starting with iv</s>
+<s f="mcrypt_ecb" u="string mcrypt_ecb(int cipher, string key, string data, int mode, string iv)">ECB crypt/decrypt data using key key with cipher cipher starting with iv</s>
+<s f="mcrypt_enc_get_algorithms_name" u="string mcrypt_enc_get_algorithms_name(resource td)">Returns the name of the algorithm specified by the descriptor td</s>
+<s f="mcrypt_enc_get_block_size" u="int mcrypt_enc_get_block_size(resource td)">Returns the block size of the cipher specified by the descriptor td</s>
+<s f="mcrypt_enc_get_iv_size" u="int mcrypt_enc_get_iv_size(resource td)">Returns the size of the IV in bytes of the algorithm specified by the descriptor td</s>
+<s f="mcrypt_enc_get_key_size" u="int mcrypt_enc_get_key_size(resource td)">Returns the maximum supported key size in bytes of the algorithm specified by the descriptor td</s>
+<s f="mcrypt_enc_get_modes_name" u="string mcrypt_enc_get_modes_name(resource td)">Returns the name of the mode specified by the descriptor td</s>
+<s f="mcrypt_enc_get_supported_key_sizes" u="array mcrypt_enc_get_supported_key_sizes(resource td)">This function decrypts the crypttext</s>
+<s f="mcrypt_enc_is_block_algorithm" u="bool mcrypt_enc_is_block_algorithm(resource td)">Returns TRUE if the alrogithm is a block algorithms</s>
+<s f="mcrypt_enc_is_block_algorithm_mode" u="bool mcrypt_enc_is_block_algorithm_mode(resource td)">Returns TRUE if the mode is for use with block algorithms</s>
+<s f="mcrypt_enc_is_block_mode" u="bool mcrypt_enc_is_block_mode(resource td)">Returns TRUE if the mode outputs blocks</s>
+<s f="mcrypt_enc_self_test" u="int mcrypt_enc_self_test(resource td)">This function runs the self test on the algorithm specified by the descriptor td</s>
+<s f="mcrypt_encrypt" u="string mcrypt_encrypt(string cipher, string key, string data, string mode, string iv)">OFB crypt/decrypt data using key key with cipher cipher starting with iv</s>
+<s f="mcrypt_generic" u="binary mcrypt_generic(resource td, binary data)">This function encrypts the plaintext</s>
+<s f="mcrypt_generic_deinit" u="bool mcrypt_generic_deinit(resource td)">This function terminates encrypt specified by the descriptor td</s>
+<s f="mcrypt_generic_init" u="int mcrypt_generic_init(resource td, binary key, binary iv)">This function initializes all buffers for the specific module</s>
+<s f="mcrypt_get_block_size" u="int mcrypt_get_block_size(string cipher, string module)">Get the key size of cipher</s>
+<s f="mcrypt_get_cipher_name" u="string mcrypt_get_cipher_name(string cipher)">Get the name of cipher</s>
+<s f="mcrypt_get_iv_size" u="int mcrypt_get_iv_size(string cipher, string module)">Get the IV size of cipher (Usually the same as the blocksize)</s>
+<s f="mcrypt_get_key_size" u="int mcrypt_get_key_size(string cipher, string module)">Get the key size of cipher</s>
+<s f="mcrypt_list_algorithms" u="array mcrypt_list_algorithms([string lib_dir])">List all algorithms in &quot;module_dir&quot;</s>
+<s f="mcrypt_list_modes" u="array mcrypt_list_modes([string lib_dir])">List all modes &quot;module_dir&quot;</s>
+<s f="mcrypt_module_close" u="bool mcrypt_module_close(resource td)">Free the descriptor td</s>
+<s f="mcrypt_module_get_algo_block_size" u="int mcrypt_module_get_algo_block_size(string algorithm [, string lib_dir])">Returns the block size of the algorithm</s>
+<s f="mcrypt_module_get_algo_key_size" u="int mcrypt_module_get_algo_key_size(string algorithm [, string lib_dir])">Returns the maximum supported key size of the algorithm</s>
+<s f="mcrypt_module_get_supported_key_sizes" u="array mcrypt_module_get_supported_key_sizes(string algorithm [, string lib_dir])">This function decrypts the crypttext</s>
+<s f="mcrypt_module_is_block_algorithm" u="bool mcrypt_module_is_block_algorithm(string algorithm [, string lib_dir])">Returns TRUE if the algorithm is a block algorithm</s>
+<s f="mcrypt_module_is_block_algorithm_mode" u="bool mcrypt_module_is_block_algorithm_mode(string mode [, string lib_dir])">Returns TRUE if the mode is for use with block algorithms</s>
+<s f="mcrypt_module_is_block_mode" u="bool mcrypt_module_is_block_mode(string mode [, string lib_dir])">Returns TRUE if the mode outputs blocks of bytes</s>
+<s f="mcrypt_module_open" u="resource mcrypt_module_open(string cipher, string cipher_directory, string mode, string mode_directory)">Opens the module of the algorithm and the mode to be used</s>
+<s f="mcrypt_module_self_test" u="bool mcrypt_module_self_test(string algorithm [, string lib_dir])">Does a self test of the module &quot;module&quot;</s>
+<s f="mcrypt_ofb" u="string mcrypt_ofb(int cipher, string key, string data, int mode, string iv)">OFB crypt/decrypt data using key key with cipher cipher starting with iv</s>
+<s f="mdecrypt_generic" u="binary mdecrypt_generic(resource td, binary data)">This function decrypts the plaintext</s>
+<s f="mhash" u="binary mhash(int hash, binary data [, binary key])">Hash data with hash</s>
+<s f="mhash_count" u="int mhash_count(void)">Gets the number of available hashes</s>
+<s f="mhash_get_block_size" u="int mhash_get_block_size(int hash)">Gets the block size of hash</s>
+<s f="mhash_get_hash_name" u="string mhash_get_hash_name(int hash)">Gets the name of hash</s>
+<s f="mhash_get_keygen_name" u="string mhash_get_keygen_name(int keygen)">Get the name of the keygen algorithm</s>
+<s f="mhash_get_keygen_salt_size" u="bool mhash_get_keygen_salt_size(int keygen)">Get the required size of the salt for the keygen algorithm</s>
+<s f="mhash_keygen" u="binary mhash_keygen(int type, int hash1, int hash2, binary password[, binary salt[, int max_key_size = 128[, int bytes_count = 0]])">Generate a key</s>
+<s f="mhash_keygen_count" u="int mhash_keygen_count()">Get the number of available keygen algorithms</s>
+<s f="mhash_keygen_s2k" u="binary mhash_keygen_s2k(int hash, binary input_password, binary salt, int bytes)">Generates a key using hash functions</s>
+<s f="mhash_keygen_uses_count" u="bool mhash_keygen_uses_count(int keygen)">Whether the keygen algorithm uses the bytes_count parameter</s>
+<s f="mhash_keygen_uses_hash" u="bool mhash_keygen_uses_hash(int keygen)">Whether the keygen algorithm uses a hash algorithm</s>
+<s f="mhash_keygen_uses_salt" u="bool mhash_keygen_uses_salt(int keygen)">Whether the keygen algorithm requires a salt</s>
+<s f="mime_content_type" u="string mime_content_type(string filename|resource stream)">Return content-type for file</s>
+<s f="ming_keypress" u="int ming_keypress(string str)">Returns the action flag for keyPress(char)</s>
+<s f="ming_setscale" u="void ming_setscale(int scale)">Set scale (?)</s>
+<s f="ming_useconstants" u="void ming_useconstants(int use)">Use constant pool (?)</s>
+<s f="ming_useswfversion" u="void ming_useswfversion(int version)">Use SWF version (?)</s>
+<s f="swfaction::__construct" u="void swfaction::__construct(string)">Creates a new SWFAction object, compiling the given script</s>
+<s f="swfbitmap::__construct" u="void swfbitmap::__construct(mixed file [, mixed maskfile])">Creates a new SWFBitmap object from jpg (with optional mask) or dbl file</s>
+<s f="swfbitmap::getHeight" u="float swfbitmap::getHeight()">Returns the height of this bitmap</s>
+<s f="swfbitmap::getWidth" u="float swfbitmap::getWidth()">Returns the width of this bitmap</s>
+<s f="swfbutton::__construct" u="void swfbutton::__construct()">Creates a new SWFButton object</s>
+<s f="swfbutton::addASound" u="SWFSoundInstance swfbutton::addASound(SWFSound sound, int flags)">associates a sound with a button transition  NOTE: the transitions are all wrong _UP, _OVER, _DOWN _HIT</s>
+<s f="swfbutton::addAction" u="void swfbutton::addAction(object SWFAction, int flags)">Sets the action to perform when conditions described in flags is met</s>
+<s f="swfbutton::addShape" u="void swfbutton::addShape(object SWFCharacter, int flags)">Sets the character to display for the condition described in flags</s>
+<s f="swfbutton::setAction" u="void swfbutton::setAction(object SWFAction)">Sets the action to perform when button is pressed</s>
+<s f="swfbutton::setDown" u="void swfbutton::setDown(object SWFCharacter)">Sets the character for this button's down state</s>
+<s f="swfbutton::setHit" u="void swfbutton::setHit(object SWFCharacter)">Sets the character for this button's hit test state</s>
+<s f="swfbutton::setMenu" u="void swfbutton::setMenu(int flag)">enable track as menu button behaviour</s>
+<s f="swfbutton::setOver" u="void swfbutton::setOver(object SWFCharacter)">Sets the character for this button's over state</s>
+<s f="swfbutton::setUp" u="void swfbutton::setUp(object SWFCharacter)">Sets the character for this button's up state</s>
+<s f="swfdisplayitem::addAction" u="void swfdisplayitem::addAction(object SWFAction, int flags)">Adds this SWFAction to the given SWFSprite instance</s>
+<s f="swfdisplayitem::addColor" u="void swfdisplayitem::addColor(int r, int g, int b [, int a])">Sets the add color part of this SWFDisplayItem's CXform to (r, g, b [, a]), a defaults to 0</s>
+<s f="swfdisplayitem::endMask" u="void swfdisplayitem::endMask()">another way of defining a MASK layer</s>
+<s f="swfdisplayitem::move" u="void swfdisplayitem::move(float dx, float dy)">Displaces this SWFDisplayItem by (dx, dy) in movie coordinates</s>
+<s f="swfdisplayitem::moveTo" u="void swfdisplayitem::moveTo(int x, int y)">Moves this SWFDisplayItem to movie coordinates (x, y)</s>
+<s f="swfdisplayitem::multColor" u="void swfdisplayitem::multColor(float r, float g, float b [, float a])">Sets the multiply color part of this SWFDisplayItem's CXform to (r, g, b [, a]), a defaults to 1.0</s>
+<s f="swfdisplayitem::rotate" u="void swfdisplayitem::rotate(float degrees)">Rotates this SWFDisplayItem the given (clockwise) degrees from its current orientation</s>
+<s f="swfdisplayitem::rotateTo" u="void swfdisplayitem::rotateTo(float degrees)">Rotates this SWFDisplayItem the given (clockwise) degrees from its original orientation</s>
+<s f="swfdisplayitem::scale" u="void swfdisplayitem::scale(float xScale, float yScale)">Multiplies this SWFDisplayItem's current x scale by xScale, its y scale by yScale</s>
+<s f="swfdisplayitem::scaleTo" u="void swfdisplayitem::scaleTo(float xScale [, float yScale])">Scales this SWFDisplayItem by xScale in the x direction, yScale in the y, or both to xScale if only one arg</s>
+<s f="swfdisplayitem::setDepth" u="void swfdisplayitem::setDepth(int depth)">Sets this SWFDisplayItem's z-depth to depth.  Items with higher depth values are drawn on top of those with lower values</s>
+<s f="swfdisplayitem::setMaskLevel" u="void swfdisplayitem::setMaskLevel(int level)">defines a MASK layer at level</s>
+<s f="swfdisplayitem::setMatrix" u="void swfdisplayitem::setMatrix(float a, float b, float c, float d, float x, float y)">Sets the item's transform matrix</s>
+<s f="swfdisplayitem::setName" u="void swfdisplayitem::setName(string name)">Sets this SWFDisplayItem's name to name</s>
+<s f="swfdisplayitem::setRatio" u="void swfdisplayitem::setRatio(float ratio)">Sets this SWFDisplayItem's ratio to ratio.  Obviously only does anything if displayitem was created from an SWFMorph</s>
+<s f="swfdisplayitem::skewX" u="void swfdisplayitem::skewX(float xSkew)">Adds xSkew to this SWFDisplayItem's x skew value</s>
+<s f="swfdisplayitem::skewXTo" u="void swfdisplayitem::skewXTo(float xSkew)">Sets this SWFDisplayItem's x skew value to xSkew</s>
+<s f="swfdisplayitem::skewY" u="void swfdisplayitem::skewY(float ySkew)">Adds ySkew to this SWFDisplayItem's y skew value</s>
+<s f="swfdisplayitem::skewYTo" u="void swfdisplayitem::skewYTo(float ySkew)">Sets this SWFDisplayItem's y skew value to ySkew</s>
+<s f="swffill::__construct" u="void swffill::__construct()">Creates a new SWFFill object</s>
+<s f="swffill::moveTo" u="void swffill::moveTo(float x, float y)">Moves this SWFFill to shape coordinates (x,y)</s>
+<s f="swffill::rotateTo" u="void swffill::rotateTo(float degrees)">Rotates this SWFFill the given (clockwise) degrees from its original orientation</s>
+<s f="swffill::scaleTo" u="void swffill::scaleTo(float xScale [, float yScale])">Scales this SWFFill by xScale in the x direction, yScale in the y, or both to xScale if only one arg</s>
+<s f="swffill::skewXTo" u="void swffill::skewXTo(float xSkew)">Sets this SWFFill's x skew value to xSkew</s>
+<s f="swffill::skewYTo" u="void swffill::skewYTo(float ySkew)">Sets this SWFFill's y skew value to ySkew</s>
+<s f="swffont::__construct" u="void swffont::__construct(string filename)">Creates a new SWFFont object from given file</s>
+<s f="swffont::addChars" u="void swffont::addChars(string)">adds characters to a font required within textfields</s>
+<s f="swffont::getAscent" u="float swffont::getAscent()">Returns the ascent of the font, or 0 if not available</s>
+<s f="swffont::getDescent" u="float swffont::getDescent()">Returns the descent of the font, or 0 if not available</s>
+<s f="swffont::getLeading" u="float swffont::getLeading()">Returns the leading of the font, or 0 if not available</s>
+<s f="swffont::getShape" u="string swffont::getShape(code)">Returns the glyph shape of a char as a text string</s>
+<s f="swffont::getUTF8Width" u="int swffont::getUTF8Width(string)">Calculates the width of the given string in this font at full height</s>
+<s f="swffont::getWideWidth" u="int swffont::getWideWidth(string)">Calculates the width of the given string in this font at full height</s>
+<s f="swffont::getWidth" u="float swffont::getWidth(string str)">Calculates the width of the given string in this font at full height</s>
+<s f="swffontcha::raddChars" u="void swffontcha::raddChars(string)">adds characters to a font for exporting font</s>
+<s f="swffontchar::addChars" u="void swffontchar::addChars(string)">adds characters to a font for exporting font</s>
+<s f="swfgradient::__construct" u="void swfgradient::__construct()">Creates a new SWFGradient object</s>
+<s f="swfgradient::addEntry" u="void swfgradient::addEntry(float ratio, int r, int g, int b [, int a])">Adds given entry to the gradient</s>
+<s f="swfmorph::__construct" u="void swfmorph::__construct()">Creates a new SWFMorph object</s>
+<s f="swfmorph::getShape1" u="object swfmorph::getShape1()">Return's this SWFMorph's start shape object</s>
+<s f="swfmorph::getShape2" u="object swfmorph::getShape2()">Return's this SWFMorph's start shape object</s>
+<s f="swfmovie::__construct" u="void swfmovie::__construct(int version)">Creates swfmovie object according to the passed version</s>
+<s f="swfmovie::add" u="object swfmovie::add(object SWFBlock)"></s>
+<s f="swfmovie::labelframe" u="void swfmovie::labelframe(string label)">Labels frame</s>
+<s f="swfmovie::namedanchor" u="void swfmovie::namedanchor(string name)"></s>
+<s f="swfmovie::nextframe" u="void swfmovie::nextframe()"></s>
+<s f="swfmovie::output" u="int swfmovie::output([int compression])"></s>
+<s f="swfmovie::protect" u="void swfmovie::protect([ string pasword])"></s>
+<s f="swfmovie::remove" u="void swfmovie::remove(object SWFBlock)"></s>
+<s f="swfmovie::save" u="int swfmovie::save(mixed where [, int compression])">Saves the movie. 'where' can be stream and the movie will be saved there otherwise it is treated as string and written in file with that name</s>
+<s f="swfmovie::saveToFile" u="int swfmovie::saveToFile(stream x [, int compression])"></s>
+<s f="swfmovie::setBackground" u="void swfmovie::setBackground(int r, int g, int b)">Sets background color (r,g,b)</s>
+<s f="swfmovie::setDimension" u="void swfmovie::setDimension(float x, float y)">Sets movie dimension</s>
+<s f="swfmovie::setFrames" u="void swfmovie::setFrames(int frames)">Sets number of frames</s>
+<s f="swfmovie::setRate" u="void swfmovie::setRate(float rate)">Sets movie rate</s>
+<s f="swfmovie::streamMP3" u="int swfmovie::streamMP3(mixed file [, float skip])">Sets sound stream of the SWF movie. The parameter can be stream or string. Retuens the number of frames.</s>
+<s f="swfprebuiltclip_init" u="void swfprebuiltclip_init([file])">Returns a SWFPrebuiltClip object</s>
+<s f="swfshape::__construct" u="void swfshape::__construct()">Creates a new SWFShape object</s>
+<s f="swfshape::addfill" u="object swfshape::addfill(mixed arg1, int arg2, [int b [, int a]])">Returns a fill object, for use with swfshape_setleftfill and swfshape_setrightfill. If 1 or 2 parameter(s) is (are) passed first should be object (from gradient class) and the second int (flags). Gradient fill is performed. If 3 or 4 parameters are passed : r, g, b [, a]. Solid fill is performed.</s>
+<s f="swfshape::drawarc" u="void swfshape::drawarc(float r, float startAngle, float endAngle)">Draws an arc of radius r centered at the current location, from angle startAngle to angle endAngle measured clockwise from 12 o'clock</s>
+<s f="swfshape::drawcircle" u="void swfshape::drawcircle(float r)">Draws a circle of radius r centered at the current location, in a counter-clockwise fashion</s>
+<s f="swfshape::drawcubic" u="void swfshape::drawcubic(float bx, float by, float cx, float cy, float dx, float dy)">Draws a cubic bezier curve using the current position and the three given points as control points</s>
+<s f="swfshape::drawcubic" u="void swfshape::drawcubic(float bx, float by, float cx, float cy, float dx, float dy)">Draws a cubic bezier curve using the current position and the three given points as control points</s>
+<s f="swfshape::drawcurve" u="void swfshape::drawcurve(float adx, float ady, float bdx, float bdy [, float cdx, float cdy])">Draws a curve from the current pen position (x, y) to the point (x+bdx, y+bdy) in the current line style, using point (x+adx, y+ady) as a control point or draws a cubic bezier to point (x+cdx, x+cdy) with control points (x+adx, y+ady) and (x+bdx, y+bdy)</s>
+<s f="swfshape::drawcurveto" u="void swfshape::drawcurveto(float ax, float ay, float bx, float by [, float dx, float dy])">Draws a curve from the current pen position (x,y) to the point (bx, by) in the current line style, using point (ax, ay) as a control point. Or draws a cubic bezier to point (dx, dy) with control points (ax, ay) and (bx, by)</s>
+<s f="swfshape::drawglyph" u="void swfshape::drawglyph(SWFFont font, string character [, int size])">Draws the first character in the given string into the shape using the glyph definition from the given font</s>
+<s f="swfshape::drawline" u="void swfshape::drawline(float dx, float dy)">Draws a line from the current pen position (x, y) to the point (x+dx, y+dy) in the current line style</s>
+<s f="swfshape::drawlineto" u="void swfshape::drawlineto(float x, float y)">Draws a line from the current pen position to shape coordinates (x, y) in the current line style</s>
+<s f="swfshape::movepen" u="void swfshape::movepen(float x, float y)">Moves the pen from its current location by vector (x, y)</s>
+<s f="swfshape::movepento" u="void swfshape::movepento(float x, float y)">Moves the pen to shape coordinates (x, y)</s>
+<s f="swfshape::setleftfill" u="void swfshape::setleftfill(int arg1 [, int g ,int b [,int a]])">Sets the left side fill style to fill in case only one parameter is passed. When 3 or 4 parameters are passed they are treated as : int r, int g, int b, int a . Solid fill is performed in this case before setting left side fill type.</s>
+<s f="swfshape::setleftfill" u="void swfshape::setleftfill(int arg1 [, int g ,int b [,int a]])">Sets the right side fill style to fill in case only one parameter is passed. When 3 or 4 parameters are passed they are treated as : int r, int g, int b, int a . Solid fill is performed in this case before setting right side fill type.</s>
+<s f="swfshape::setline" u="void swfshape::setline(int width, int r, int g, int b [, int a])">Sets the current line style for this SWFShape</s>
+<s f="swfsound::__construct" u="void swfsound::__construct(string filename, int flags)">Creates a new SWFSound object from given file</s>
+<s f="swfsprite::__construct" u="void swfsprite::__construct()">Creates a new SWFSprite object</s>
+<s f="swfsprite::add" u="object swfsprite::add(object SWFCharacter)">Adds the character to the sprite, returns a displayitem object</s>
+<s f="swfsprite::labelFrame" u="void swfsprite::labelFrame(string label)">Labels frame</s>
+<s f="swfsprite::nextFrame" u="void swfsprite::nextFrame()">Moves the sprite to the next frame</s>
+<s f="swfsprite::remove" u="void swfsprite::remove(object SWFDisplayItem)">Remove the named character from the sprite's display list</s>
+<s f="swfsprite::setFrames" u="void swfsprite::setFrames(int frames)">Sets the number of frames in this SWFSprite</s>
+<s f="swftext::__construct" u="void swftext::__construct()">Creates new SWFText object</s>
+<s f="swftext::addString" u="void swftext::addString(string text)">Writes the given text into this SWFText object at the current pen position, using the current font, height, spacing, and color</s>
+<s f="swftext::addUTF8String" u="void swftext::addUTF8String(string text)">Writes the given text into this SWFText object at the current pen position,    using the current font, height, spacing, and color</s>
+<s f="swftext::addWideString" u="void swftext::addWideString(string text)">Writes the given text into this SWFText object at the current pen position,    using the current font, height, spacing, and color</s>
+<s f="swftext::getAscent" u="float swftext::getAscent()">Returns the ascent of the current font at its current size, or 0 if not available</s>
+<s f="swftext::getDescent" u="float swftext::getDescent()">Returns the descent of the current font at its current size, or 0 if not available</s>
+<s f="swftext::getLeading" u="float swftext::getLeading()">Returns the leading of the current font at its current size, or 0 if not available</s>
+<s f="swftext::getUTF8Width" u="double swftext::getUTF8Width(string)">calculates the width of the given string in this text objects current font and size</s>
+<s f="swftext::getWideWidth" u="double swftext::getWideWidth(string)">calculates the width of the given string in this text objects current font and size</s>
+<s f="swftext::getWidth" u="float swftext::getWidth(string str)">Calculates the width of the given string in this text objects current font and size</s>
+<s f="swftext::moveTo" u="void swftext::moveTo(float x, float y)">Moves this SWFText object's current pen position to (x, y) in text coordinates</s>
+<s f="swftext::setColor" u="void swftext::setColor(int r, int g, int b [, int a])">Sets this SWFText object's current color to the given color</s>
+<s f="swftext::setFont" u="void swftext::setFont(object font)">Sets this SWFText object's current font to given font</s>
+<s f="swftext::setHeight" u="void swftext::setHeight(float height)">Sets this SWFText object's current height to given height</s>
+<s f="swftext::setSpacing" u="void swftext::setSpacing(float spacing)">Sets this SWFText object's current letterspacing to given spacing</s>
+<s f="swftextfield::__construct" u="void swftextfield::__construct([int flags])">Creates a new SWFTextField object</s>
+<s f="swftextfield::addChars" u="void swftextfield::addChars(string)">adds characters to a font that will be available within a textfield</s>
+<s f="swftextfield::addString" u="void swftextfield::addString(string str)">Adds the given string to this textfield</s>
+<s f="swftextfield::align" u="void swftextfield::align(int alignment)">Sets the alignment of this textfield</s>
+<s f="swftextfield::setBounds" u="void swftextfield::setBounds(float width, float height)">Sets the width and height of this textfield</s>
+<s f="swftextfield::setColor" u="void swftextfield::setColor(int r, int g, int b [, int a])">Sets the color of this textfield</s>
+<s f="swftextfield::setFont" u="void swftextfield::setFont(object font)">Sets the font for this textfield</s>
+<s f="swftextfield::setHeight" u="void swftextfield::setHeight(float height)">Sets the font height of this textfield</s>
+<s f="swftextfield::setIndentation" u="void swftextfield::setIndentation(float indentation)">Sets the indentation of the first line of this textfield</s>
+<s f="swftextfield::setLeftMargin" u="void swftextfield::setLeftMargin(float margin)">Sets the left margin of this textfield</s>
+<s f="swftextfield::setLineSpacing" u="void swftextfield::setLineSpacing(float space)">Sets the line spacing of this textfield</s>
+<s f="swftextfield::setMargins" u="void swftextfield::setMargins(float left, float right)">Sets both margins of this textfield</s>
+<s f="swftextfield::setName" u="void swftextfield::setName(string var_name)">Sets the variable name of this textfield</s>
+<s f="swftextfield::setPadding" u="void swftextfield::setPadding(float padding)">Sets the padding of this textfield</s>
+<s f="swftextfield::setRightMargin" u="void swftextfield::setRightMargin(float margin)">Sets the right margin of this textfield</s>
+<s f="swfvideostream_init" u="void swfvideostream_init([file])">Returns a SWVideoStream object</s>
+<s f="msql_affected_rows" u="int msql_affected_rows(resource query)">Return number of affected rows</s>
+<s f="msql_close" u="bool msql_close([resource link_identifier])">Close an mSQL connection</s>
+<s f="msql_connect" u="int msql_connect([string hostname[:port]] [, string username] [, string password])">Open a connection to an mSQL Server</s>
+<s f="msql_create_db" u="bool msql_create_db(string database_name [, resource link_identifier])">Create an mSQL database</s>
+<s f="msql_data_seek" u="bool msql_data_seek(resource query, int row_number)">Move internal result pointer</s>
+<s f="msql_db_query" u="resource msql_db_query(string database_name, string query [, resource link_identifier])">Send an SQL query to mSQL</s>
+<s f="msql_drop_db" u="bool msql_drop_db(string database_name [, resource link_identifier])">Drop (delete) an mSQL database</s>
+<s f="msql_error" u="string msql_error(void)">Returns the text of the error message from previous mSQL operation</s>
+<s f="msql_fetch_array" u="array msql_fetch_array(resource query [, int result_type])">Fetch a result row as an associative array</s>
+<s f="msql_fetch_field" u="object msql_fetch_field(resource query [, int field_offset])">Get column information from a result and return as an object</s>
+<s f="msql_fetch_object" u="object msql_fetch_object(resource query [, resource result_type])">Fetch a result row as an object</s>
+<s f="msql_fetch_row" u="array msql_fetch_row(resource query)">Get a result row as an enumerated array</s>
+<s f="msql_field_flags" u="string msql_field_flags(resource query, int field_offset)">Get the flags associated with the specified field in a result</s>
+<s f="msql_field_len" u="int msql_field_len(int query, int field_offet)">Returns the length of the specified field</s>
+<s f="msql_field_name" u="string msql_field_name(resource query, int field_index)">Get the name of the specified field in a result</s>
+<s f="msql_field_seek" u="bool msql_field_seek(resource query, int field_offset)">Set result pointer to a specific field offset</s>
+<s f="msql_field_table" u="string msql_field_table(resource query, int field_offset)">Get name of the table the specified field is in</s>
+<s f="msql_field_type" u="string msql_field_type(resource query, int field_offset)">Get the type of the specified field in a result</s>
+<s f="msql_free_result" u="bool msql_free_result(resource query)">Free result memory</s>
+<s f="msql_list_dbs" u="resource msql_list_dbs([resource link_identifier])">List databases available on an mSQL server</s>
+<s f="msql_list_fields" u="resource msql_list_fields(string database_name, string table_name [, resource link_identifier])">List mSQL result fields</s>
+<s f="msql_list_tables" u="resource msql_list_tables(string database_name [, resource link_identifier])">List tables in an mSQL database</s>
+<s f="msql_num_fields" u="int msql_num_fields(resource query)">Get number of fields in a result</s>
+<s f="msql_num_rows" u="int msql_num_rows(resource query)">Get number of rows in a result</s>
+<s f="msql_pconnect" u="int msql_pconnect([string hostname[:port]] [, string username] [, string password])">Open a persistent connection to an mSQL Server</s>
+<s f="msql_query" u="resource msql_query(string query [, resource link_identifier])">Send an SQL query to mSQL</s>
+<s f="msql_result" u="string msql_result(int query, int row [, mixed field])">Get result data</s>
+<s f="msql_select_db" u="bool msql_select_db(string database_name [, resource link_identifier])">Select an mSQL database</s>
+<s f="mssql_bind" u="bool mssql_bind(resource stmt, string param_name, mixed var, int type [, int is_output [, int is_null [, int maxlen]]])">Adds a parameter to a stored procedure or a remote stored procedure</s>
+<s f="mssql_close" u="bool mssql_close([resource conn_id])">Closes a connection to a MS-SQL server</s>
+<s f="mssql_connect" u="int mssql_connect([string servername [, string username [, string password [, bool new_link]]]])">Establishes a connection to a MS-SQL server</s>
+<s f="mssql_data_seek" u="bool mssql_data_seek(resource result_id, int offset)">Moves the internal row pointer of the MS-SQL result associated with the specified result identifier to pointer to the specified row number</s>
+<s f="mssql_execute" u="mixed mssql_execute(resource stmt [, bool skip_results = false])">Executes a stored procedure on a MS-SQL server database</s>
+<s f="mssql_fetch_array" u="array mssql_fetch_array(resource result_id [, int result_type])">Returns an associative array of the current row in the result set specified by result_id</s>
+<s f="mssql_fetch_assoc" u="array mssql_fetch_assoc(resource result_id)">Returns an associative array of the current row in the result set specified by result_id</s>
+<s f="mssql_fetch_batch" u="int mssql_fetch_batch(resource result_index)">Returns the next batch of records</s>
+<s f="mssql_fetch_field" u="object mssql_fetch_field(resource result_id [, int offset])">Gets information about certain fields in a query result</s>
+<s f="mssql_fetch_object" u="object mssql_fetch_object(resource result_id [, int result_type])">Returns a psuedo-object of the current row in the result set specified by result_id</s>
+<s f="mssql_fetch_row" u="array mssql_fetch_row(resource result_id)">Returns an array of the current row in the result set specified by result_id</s>
+<s f="mssql_field_length" u="int mssql_field_length(resource result_id [, int offset])">Get the length of a MS-SQL field</s>
+<s f="mssql_field_name" u="string mssql_field_name(resource result_id [, int offset])">Returns the name of the field given by offset in the result set given by result_id</s>
+<s f="mssql_field_seek" u="bool mssql_field_seek(int result_id, int offset)">Seeks to the specified field offset</s>
+<s f="mssql_field_type" u="string mssql_field_type(resource result_id [, int offset])">Returns the type of a field</s>
+<s f="mssql_free_result" u="bool mssql_free_result(resource result_index)">Free a MS-SQL result index</s>
+<s f="mssql_free_statement" u="bool mssql_free_statement(resource result_index)">Free a MS-SQL statement index</s>
+<s f="mssql_get_last_message" u="string mssql_get_last_message(void)">Gets the last message from the MS-SQL server</s>
+<s f="mssql_guid_string" u="string mssql_guid_string(string binary [,int short_format])">Converts a 16 byte binary GUID to a string</s>
+<s f="mssql_init" u="int mssql_init(string sp_name [, resource conn_id])">Initializes a stored procedure or a remote stored procedure</s>
+<s f="mssql_min_error_severity" u="void mssql_min_error_severity(int severity)">Sets the lower error severity</s>
+<s f="mssql_min_message_severity" u="void mssql_min_message_severity(int severity)">Sets the lower message severity</s>
+<s f="mssql_next_result" u="bool mssql_next_result(resource result_id)">Move the internal result pointer to the next result</s>
+<s f="mssql_num_fields" u="int mssql_num_fields(resource mssql_result_index)">Returns the number of fields fetched in from the result id specified</s>
+<s f="mssql_num_rows" u="int mssql_num_rows(resource mssql_result_index)">Returns the number of rows fetched in from the result id specified</s>
+<s f="mssql_pconnect" u="int mssql_pconnect([string servername [, string username [, string password [, bool new_link]]]])">Establishes a persistent connection to a MS-SQL server</s>
+<s f="mssql_query" u="resource mssql_query(string query [, resource conn_id [, int batch_size]])">Perform an SQL query on a MS-SQL server database</s>
+<s f="mssql_result" u="string mssql_result(resource result_id, int row, mixed field)">Returns the contents of one cell from a MS-SQL result set</s>
+<s f="mssql_rows_affected" u="int mssql_rows_affected(resource conn_id)">Returns the number of records affected by the query</s>
+<s f="mssql_select_db" u="bool mssql_select_db(string database_name [, resource conn_id])">Select a MS-SQL database</s>
+<s f="mysql_affected_rows" u="int mysql_affected_rows([int link_identifier])">Gets number of affected rows in previous MySQL operation</s>
+<s f="mysql_client_encoding" u="string mysql_client_encoding([int link_identifier])">Returns the default character set for the current connection</s>
+<s f="mysql_close" u="bool mysql_close([int link_identifier])">Close a MySQL connection</s>
+<s f="mysql_connect" u="resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]])">Opens a connection to a MySQL Server</s>
+<s f="mysql_create_db" u="bool mysql_create_db(string database_name [, int link_identifier])">Create a MySQL database</s>
+<s f="mysql_data_seek" u="bool mysql_data_seek(resource result, int row_number)">Move internal result pointer</s>
+<s f="mysql_db_query" u="resource mysql_db_query(string database_name, string query [, int link_identifier])">Sends an SQL query to MySQL</s>
+<s f="mysql_drop_db" u="bool mysql_drop_db(string database_name [, int link_identifier])">Drops (delete) a MySQL database</s>
+<s f="mysql_errno" u="int mysql_errno([int link_identifier])">Returns the number of the error message from previous MySQL operation</s>
+<s f="mysql_error" u="string mysql_error([int link_identifier])">Returns the text of the error message from previous MySQL operation</s>
+<s f="mysql_escape_string" u="string mysql_escape_string(string to_be_escaped)">Escape string for mysql query</s>
+<s f="mysql_fetch_array" u="array mysql_fetch_array(resource result [, int result_type])">Fetch a result row as an array (associative, numeric or both)</s>
+<s f="mysql_fetch_assoc" u="array mysql_fetch_assoc(resource result)">Fetch a result row as an associative array</s>
+<s f="mysql_fetch_field" u="object mysql_fetch_field(resource result [, int field_offset])">Gets column information from a result and return as an object</s>
+<s f="mysql_fetch_lengths" u="array mysql_fetch_lengths(resource result)">Gets max data size of each column in a result</s>
+<s f="mysql_fetch_object" u="object mysql_fetch_object(resource result [, string class_name [, NULL|array ctor_params]])">Fetch a result row as an object</s>
+<s f="mysql_fetch_row" u="array mysql_fetch_row(resource result)">Gets a result row as an enumerated array</s>
+<s f="mysql_field_flags" u="string mysql_field_flags(resource result, int field_offset)">Gets the flags associated with the specified field in a result</s>
+<s f="mysql_field_len" u="int mysql_field_len(resource result, int field_offset)">Returns the length of the specified field</s>
+<s f="mysql_field_name" u="string mysql_field_name(resource result, int field_index)">Gets the name of the specified field in a result</s>
+<s f="mysql_field_seek" u="bool mysql_field_seek(resource result, int field_offset)">Sets result pointer to a specific field offset</s>
+<s f="mysql_field_table" u="string mysql_field_table(resource result, int field_offset)">Gets name of the table the specified field is in</s>
+<s f="mysql_field_type" u="string mysql_field_type(resource result, int field_offset)">Gets the type of the specified field in a result</s>
+<s f="mysql_free_result" u="bool mysql_free_result(resource result)">Free result memory</s>
+<s f="mysql_get_client_info" u="string mysql_get_client_info(void)">Returns a string that represents the client library version</s>
+<s f="mysql_get_host_info" u="string mysql_get_host_info([int link_identifier])">Returns a string describing the type of connection in use, including the server host name</s>
+<s f="mysql_get_proto_info" u="int mysql_get_proto_info([int link_identifier])">Returns the protocol version used by current connection</s>
+<s f="mysql_get_server_info" u="string mysql_get_server_info([int link_identifier])">Returns a string that represents the server version number</s>
+<s f="mysql_info" u="string mysql_info([int link_identifier])">Returns a string containing information about the most recent query</s>
+<s f="mysql_insert_id" u="int mysql_insert_id([int link_identifier])">Gets the ID generated from the previous INSERT operation</s>
+<s f="mysql_list_dbs" u="resource mysql_list_dbs([int link_identifier])">List databases available on a MySQL server</s>
+<s f="mysql_list_fields" u="resource mysql_list_fields(string database_name, string table_name [, int link_identifier])">List MySQL result fields</s>
+<s f="mysql_list_processes" u="resource mysql_list_processes([int link_identifier])">Returns a result set describing the current server threads</s>
+<s f="mysql_list_tables" u="resource mysql_list_tables(string database_name [, int link_identifier])">List tables in a MySQL database</s>
+<s f="mysql_num_fields" u="int mysql_num_fields(resource result)">Gets number of fields in a result</s>
+<s f="mysql_num_rows" u="int mysql_num_rows(resource result)">Gets number of rows in a result</s>
+<s f="mysql_pconnect" u="resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]])">Opens a persistent connection to a MySQL Server</s>
+<s f="mysql_ping" u="bool mysql_ping([int link_identifier])">Ping a server connection. If no connection then reconnect.</s>
+<s f="mysql_query" u="resource mysql_query(string query [, int link_identifier])">Sends an SQL query to MySQL</s>
+<s f="mysql_real_escape_string" u="string mysql_real_escape_string(string to_be_escaped [, int link_identifier])">Escape special characters in a string for use in a SQL statement, taking into account the current charset of the connection</s>
+<s f="mysql_result" u="mixed mysql_result(resource result, int row [, mixed field])">Gets result data</s>
+<s f="mysql_select_db" u="bool mysql_select_db(string database_name [, int link_identifier])">Selects a MySQL database</s>
+<s f="mysql_set_charset" u="bool mysql_set_charset(string csname [, int link_identifier])">sets client character set</s>
+<s f="mysql_stat" u="string mysql_stat([int link_identifier])">Returns a string containing status information</s>
+<s f="mysql_thread_id" u="int mysql_thread_id([int link_identifier])">Returns the thread id of current connection</s>
+<s f="mysql_unbuffered_query" u="resource mysql_unbuffered_query(string query [, int link_identifier])">Sends an SQL query to MySQL, without fetching and buffering the result rows</s>
+<s f="mysqli_affected_rows" u="mixed mysqli_affected_rows(object link)">Get number of affected rows in previous MySQL operation</s>
+<s f="mysqli_autocommit" u="bool mysqli_autocommit(object link, bool mode)">Turn auto commit on or of</s>
+<s f="mysqli_change_user" u="bool mysqli_change_user(object link, string user, string password, string database)">Change logged-in user of the active connection</s>
+<s f="mysqli_character_set_name" u="string mysqli_character_set_name(object link)">Returns the name of the character set used for this connection</s>
+<s f="mysqli_close" u="bool mysqli_close(object link)">Close connection</s>
+<s f="mysqli_commit" u="bool mysqli_commit(object link)">Commit outstanding actions and close transaction</s>
+<s f="mysqli_data_seek" u="bool mysqli_data_seek(object result, int offset)">Move internal result pointer</s>
+<s f="mysqli_debug" u="void mysqli_debug(string debug)"></s>
+<s f="mysqli_dump_debug_info" u="bool mysqli_dump_debug_info(object link)"></s>
+<s f="mysqli_errno" u="int mysqli_errno(object link)">Returns the numerical value of the error message from previous MySQL operation</s>
+<s f="mysqli_error" u="string mysqli_error(object link)">Returns the text of the error message from previous MySQL operation</s>
+<s f="mysqli_field_count" u="int mysqli_field_count(object link)">Fetch the number of fields returned by the last query for the given link</s>
+<s f="mysqli_field_seek" u="int mysqli_field_seek(object result, int fieldnr)">Set result pointer to a specified field offset</s>
+<s f="mysqli_field_tell" u="int mysqli_field_tell(object result)">Get current field offset of result pointer</s>
+<s f="mysqli_free_result" u="void mysqli_free_result(object result)">Free query result memory for the given result handle</s>
+<s f="mysqli_get_client_info" u="string mysqli_get_client_info(void)">Get MySQL client info</s>
+<s f="mysqli_get_client_version" u="int mysqli_get_client_version(void)">Get MySQL client info</s>
+<s f="mysqli_get_proto_info" u="int mysqli_get_proto_info(object link)">Get MySQL protocol information</s>
+<s f="mysqli_get_server_info" u="string mysqli_get_server_info(object link)">Get MySQL server info</s>
+<s f="mysqli_get_server_version" u="int mysqli_get_server_version(object link)">Return the MySQL version for the server referenced by the given link</s>
+<s f="mysqli_info" u="string mysqli_info(object link)">Get information about the most recent query</s>
+<s f="mysqli_init" u="resource mysqli_init(void)">Initialize mysqli and return a resource for use with mysql_real_connect</s>
+<s f="mysqli_insert_id" u="mixed mysqli_insert_id(object link)">Get the ID generated from the previous INSERT operation</s>
+<s f="mysqli_kill" u="bool mysqli_kill(object link, int processid)">Kill a mysql process on the server</s>
+<s f="mysqli_more_results" u="bool mysqli_more_results(object link)">check if there any more query results from a multi query</s>
+<s f="mysqli_next_result" u="bool mysqli_next_result(object link)">read next result from multi_query</s>
+<s f="mysqli_num_fields" u="int mysqli_num_fields(object result)">Get number of fields in result</s>
+<s f="mysqli_num_rows" u="mixed mysqli_num_rows(object result)">Get number of rows in result</s>
+<s f="mysqli_options" u="bool mysqli_options(object link, int flags, mixed values)">Set options</s>
+<s f="mysqli_ping" u="bool mysqli_ping(object link)">Ping a server connection or reconnect if there is no connection</s>
+<s f="mysqli_prepare" u="mixed mysqli_prepare(object link, string query)">Prepare a SQL statement for execution</s>
+<s f="mysqli_real_connect" u="bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])">Open a connection to a mysql server</s>
+<s f="mysqli_real_escape_string" u="string mysqli_real_escape_string(object link, string escapestr)">Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection</s>
+<s f="mysqli_real_query" u="bool mysqli_real_query(object link, string query)">Binary-safe version of mysql_query()</s>
+<s f="mysqli_rollback" u="bool mysqli_rollback(object link)">Undo actions from current transaction</s>
+<s f="mysqli_select_db" u="bool mysqli_select_db(object link, string dbname)">Select a MySQL database</s>
+<s f="mysqli_set_local_infile_default" u="void mysqli_set_local_infile_default(object link)">unsets user defined handler for load local infile command</s>
+<s f="mysqli_set_local_infile_handler" u="bool mysqli_set_local_infile_handler(object link, callback read_func)">Set callback functions for LOAD DATA LOCAL INFILE</s>
+<s f="mysqli_sqlstate" u="string mysqli_sqlstate(object link)">Returns the SQLSTATE error from previous MySQL operation</s>
+<s f="mysqli_ssl_set" u="bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher])"></s>
+<s f="mysqli_stat" u="mixed mysqli_stat(object link)">Get current system status</s>
+<s f="mysqli_stmt_affected_rows" u="mixed mysqli_stmt_affected_rows(object stmt)">Return the number of rows affected in the last query for the given link</s>
+<s f="mysqli_stmt_attr_get" u="int mysqli_stmt_attr_get(object stmt, long attr)"></s>
+<s f="mysqli_stmt_attr_set" u="int mysqli_stmt_attr_set(object stmt, long attr, long mode)"></s>
+<s f="mysqli_stmt_bind_param" u="bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....])">Bind variables to a prepared statement as parameters</s>
+<s f="mysqli_stmt_bind_result" u="bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...])">Bind variables to a prepared statement for result storage</s>
+<s f="mysqli_stmt_close" u="bool mysqli_stmt_close(object stmt)">Close statement</s>
+<s f="mysqli_stmt_data_seek" u="void mysqli_stmt_data_seek(object stmt, int offset)">Move internal result pointer</s>
+<s f="mysqli_stmt_errno" u="int mysqli_stmt_errno(object stmt)"></s>
+<s f="mysqli_stmt_error" u="string mysqli_stmt_error(object stmt)"></s>
+<s f="mysqli_stmt_execute" u="bool mysqli_stmt_execute(object stmt)">Execute a prepared statement</s>
+<s f="mysqli_stmt_fetch" u="mixed mysqli_stmt_fetch(object stmt)">Fetch results from a prepared statement into the bound variables</s>
+<s f="mysqli_stmt_field_count" u="int mysqli_stmt_field_count(object stmt)">Return the number of result columns for the given statement</s>
+<s f="mysqli_stmt_free_result" u="void mysqli_stmt_free_result(object stmt)">Free stored result memory for the given statement handle</s>
+<s f="mysqli_stmt_init" u="mixed mysqli_stmt_init(object link)">Initialize statement object</s>
+<s f="mysqli_stmt_insert_id" u="mixed mysqli_stmt_insert_id(object stmt)">Get the ID generated from the previous INSERT operation</s>
+<s f="mysqli_stmt_num_rows" u="mixed mysqli_stmt_num_rows(object stmt)">Return the number of rows in statements result set</s>
+<s f="mysqli_stmt_param_count" u="int mysqli_stmt_param_count(object stmt)">Return the number of parameter for the given statement</s>
+<s f="mysqli_stmt_prepare" u="bool mysqli_stmt_prepare(object stmt, string query)">prepare server side statement with query</s>
+<s f="mysqli_stmt_reset" u="bool mysqli_stmt_reset(object stmt)">reset a prepared statement</s>
+<s f="mysqli_stmt_result_metadata" u="mixed mysqli_stmt_result_metadata(object stmt)">return result set from statement</s>
+<s f="mysqli_stmt_send_long_data" u="bool mysqli_stmt_send_long_data(object stmt, int param_nr, string data)"></s>
+<s f="mysqli_stmt_sqlstate" u="string mysqli_stmt_sqlstate(object stmt)"></s>
+<s f="mysqli_stmt_store_result" u="bool mysqli_stmt_store_result(stmt)"></s>
+<s f="mysqli_store_result" u="object mysqli_store_result(object link)">Buffer result set on client</s>
+<s f="mysqli_thread_id" u="int mysqli_thread_id(object link)">Return the current thread ID</s>
+<s f="mysqli_thread_safe" u="bool mysqli_thread_safe(void)">Return whether thread safety is given or not</s>
+<s f="mysqli_use_result" u="mixed mysqli_use_result(object link)">Directly retrieve query results - do not buffer results on client side</s>
+<s f="mysqli_embedded_server_end" u="void mysqli_embedded_server_end(void)"></s>
+<s f="mysqli_embedded_server_start" u="bool mysqli_embedded_server_start(bool start, array arguments, array groups)">initialize and start embedded server</s>
+<s f="mysqli_connect" u="object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]])">Open a connection to a mysql server</s>
+<s f="mysqli_connect_errno" u="int mysqli_connect_errno(void)">Returns the numerical value of the error message from last connect command</s>
+<s f="mysqli_connect_error" u="string mysqli_connect_error(void)">Returns the text of the error message from previous MySQL operation</s>
+<s f="mysqli_get_charset" u="object mysqli_get_charset(object link)">returns a character set object</s>
+<s f="mysqli_multi_query" u="bool mysqli_multi_query(object link, string query)">allows to execute multiple queries</s>
+<s f="mysqli_set_charset" u="bool mysqli_set_charset(object link, string csname)">sets client character set</s>
+<s f="mysqli_disable_reads_from_master" u="void mysqli_disable_reads_from_master(object link)"></s>
+<s f="mysqli_disable_rpl_parse" u="void mysqli_disable_rpl_parse(object link)"></s>
+<s f="mysqli_enable_reads_from_master" u="void mysqli_enable_reads_from_master(object link)"></s>
+<s f="mysqli_enable_rpl_parse" u="void mysqli_enable_rpl_parse(object link)"></s>
+<s f="mysqli_master_query" u="bool mysqli_master_query(object link, string query)">Enforce execution of a query on the master in a master/slave setup</s>
+<s f="mysqli_rpl_parse_enabled" u="int mysqli_rpl_parse_enabled(object link)"></s>
+<s f="mysqli_rpl_probe" u="bool mysqli_rpl_probe(object link)"></s>
+<s f="mysqli_rpl_query_type" u="int mysqli_rpl_query_type(string query)"></s>
+<s f="mysqli_send_query" u="bool mysqli_send_query(object link, string query)"></s>
+<s f="mysqli_slave_query" u="bool mysqli_slave_query(object link, string query)">Enforce execution of a query on a slave in a master/slave setup</s>
+<s f="mysqli_report" u="bool mysqli_report(int flags)">sets report level</s>
+<s f="oci_bind_array_by_name" u="bool oci_bind_array_by_name(resource stmt, string name, array &amp;var, int max_table_length [, int max_item_length [, int type ]])">Bind a PHP array to an Oracle PL/SQL type by name</s>
+<s f="oci_bind_by_name" u="bool oci_bind_by_name(resource stmt, string name, mixed &amp;var, [, int maxlength [, int type]])">Bind a PHP variable to an Oracle placeholder by name</s>
+<s f="oci_cancel" u="bool oci_cancel(resource stmt)">Cancel reading from a cursor</s>
+<s f="oci_close" u="bool oci_close(resource connection)">Disconnect from database</s>
+<s f="oci_collection_append" u="bool oci_collection_append(string value)">Append an object to the collection</s>
+<s f="oci_collection_assign" u="bool oci_collection_assign(object from)">Assign a collection from another existing collection</s>
+<s f="oci_collection_element_assign" u="bool oci_collection_element_assign(int index, string val)">Assign element val to collection at index ndx</s>
+<s f="oci_collection_element_get" u="string oci_collection_element_get(int ndx)">Retrieve the value at collection index ndx</s>
+<s f="oci_collection_max" u="int oci_collection_max()">Return the max value of a collection. For a varray this is the maximum length of the array</s>
+<s f="oci_collection_size" u="int oci_collection_size()">Return the size of a collection</s>
+<s f="oci_collection_trim" u="bool oci_collection_trim(int num)">Trim num elements from the end of a collection</s>
+<s f="oci_commit" u="bool oci_commit(resource connection)">Commit the current context</s>
+<s f="oci_connect" u="resource oci_connect(string user, string pass [, string db [, string charset [, int session_mode ]])">Connect to an Oracle database and log on. Returns a new session.</s>
+<s f="oci_define_by_name" u="bool oci_define_by_name(resource stmt, string name, mixed &amp;var [, int type])">Define a PHP variable to an Oracle column by name</s>
+<s f="oci_error" u="array oci_error([resource stmt|connection|global])">Return the last error of stmt|connection|global. If no error happened returns false.</s>
+<s f="oci_execute" u="bool oci_execute(resource stmt [, int mode])">Execute a parsed statement</s>
+<s f="oci_fetch" u="bool oci_fetch(resource stmt)">Prepare a new row of data for reading</s>
+<s f="oci_fetch_all" u="int oci_fetch_all(resource stmt, array &amp;output[, int skip[, int maxrows[, int flags]]])">Fetch all rows of result data into an array</s>
+<s f="oci_fetch_array" u="array oci_fetch_array( resource stmt [, int mode ])">Fetch a result row as an array</s>
+<s f="oci_fetch_assoc" u="array oci_fetch_assoc( resource stmt )">Fetch a result row as an associative array</s>
+<s f="oci_fetch_object" u="object oci_fetch_object( resource stmt )">Fetch a result row as an object</s>
+<s f="oci_fetch_row" u="array oci_fetch_row( resource stmt )">Fetch a result row as an enumerated array</s>
+<s f="oci_field_is_null" u="bool oci_field_is_null(resource stmt, int col)">Tell whether a column is NULL</s>
+<s f="oci_field_name" u="string oci_field_name(resource stmt, int col)">Tell the name of a column</s>
+<s f="oci_field_precision" u="int oci_field_precision(resource stmt, int col)">Tell the precision of a column</s>
+<s f="oci_field_scale" u="int oci_field_scale(resource stmt, int col)">Tell the scale of a column</s>
+<s f="oci_field_size" u="int oci_field_size(resource stmt, int col)">Tell the maximum data size of a column</s>
+<s f="oci_field_type" u="mixed oci_field_type(resource stmt, int col)">Tell the data type of a column</s>
+<s f="oci_field_type_raw" u="int oci_field_type_raw(resource stmt, int col)">Tell the raw oracle data type of a column</s>
+<s f="oci_free_collection" u="bool oci_free_collection()">Deletes collection object</s>
+<s f="oci_free_descriptor" u="bool oci_free_descriptor()">Deletes large object description</s>
+<s f="oci_free_statement" u="bool oci_free_statement(resource stmt)">Free all resources associated with a statement</s>
+<s f="oci_internal_debug" u="void oci_internal_debug(int onoff)">Toggle internal debugging output for the OCI extension</s>
+<s f="oci_lob_append" u="bool oci_lob_append( object lob )">Appends data from a LOB to another LOB</s>
+<s f="oci_lob_close" u="bool oci_lob_close()">Closes lob descriptor</s>
+<s f="oci_lob_copy" u="bool oci_lob_copy( object lob_to, object lob_from [, int length ] )">Copies data from a LOB to another LOB</s>
+<s f="oci_lob_eof" u="bool oci_lob_eof()">Checks if EOF is reached</s>
+<s f="oci_lob_erase" u="int oci_lob_erase( [ int offset [, int length ] ] )">Erases a specified portion of the internal LOB, starting at a specified offset</s>
+<s f="oci_lob_export" u="bool oci_lob_export([string filename [, int start [, int length]]])">Writes a large object into a file</s>
+<s f="oci_lob_flush" u="bool oci_lob_flush( [ int flag ] )">Flushes the LOB buffer</s>
+<s f="oci_lob_import" u="bool oci_lob_import( string filename )">Loads file into a LOB</s>
+<s f="oci_lob_is_equal" u="bool oci_lob_is_equal( object lob1, object lob2 )">Tests to see if two LOB/FILE locators are equal</s>
+<s f="oci_lob_load" u="string oci_lob_load()">Loads a large object</s>
+<s f="oci_lob_read" u="string oci_lob_read( int length )">Reads particular part of a large object</s>
+<s f="oci_lob_rewind" u="bool oci_lob_rewind()">Rewind pointer of a LOB</s>
+<s f="oci_lob_save" u="bool oci_lob_save( string data [, int offset ])">Saves a large object</s>
+<s f="oci_lob_seek" u="bool oci_lob_seek( int offset [, int whence ])">Moves the pointer of a LOB</s>
+<s f="oci_lob_size" u="int oci_lob_size()">Returns size of a large object</s>
+<s f="oci_lob_tell" u="int oci_lob_tell()">Tells LOB pointer position</s>
+<s f="oci_lob_truncate" u="bool oci_lob_truncate( [ int length ])">Truncates a LOB</s>
+<s f="oci_lob_write" u="int oci_lob_write( string string [, int length ])">Writes data to current position of a LOB</s>
+<s f="oci_lob_write_temporary" u="bool oci_lob_write_temporary(string var [, int lob_type])">Writes temporary blob</s>
+<s f="oci_new_collection" u="object oci_new_collection(resource connection, string tdo [, string schema])">Initialize a new collection</s>
+<s f="oci_new_connect" u="resource oci_new_connect(string user, string pass [, string db])">Connect to an Oracle database and log on. Returns a new session.</s>
+<s f="oci_new_cursor" u="resource oci_new_cursor(resource connection)">Return a new cursor (Statement-Handle) - use this to bind ref-cursors!</s>
+<s f="oci_new_descriptor" u="object oci_new_descriptor(resource connection [, int type])">Initialize a new empty descriptor LOB/FILE (LOB is default)</s>
+<s f="oci_num_fields" u="int oci_num_fields(resource stmt)">Return the number of result columns in a statement</s>
+<s f="oci_num_rows" u="int oci_num_rows(resource stmt)">Return the row count of an OCI statement</s>
+<s f="oci_parse" u="resource oci_parse(resource connection, string query)">Parse a query and return a statement</s>
+<s f="oci_password_change" u="bool oci_password_change(resource connection, string username, string old_password, string new_password)">Changes the password of an account</s>
+<s f="oci_pconnect" u="resource oci_pconnect(string user, string pass [, string db [, string charset ]])">Connect to an Oracle database using a persistent connection and log on. Returns a new session.</s>
+<s f="oci_result" u="string oci_result(resource stmt, mixed column)">Return a single column of result data</s>
+<s f="oci_rollback" u="bool oci_rollback(resource connection)">Rollback the current context</s>
+<s f="oci_server_version" u="string oci_server_version(resource connection)">Return a string containing server version information</s>
+<s f="oci_set_prefetch" u="bool oci_set_prefetch(resource stmt, int prefetch_rows)">Sets the number of rows to be prefetched on execute to prefetch_rows for stmt</s>
+<s f="oci_statement_type" u="string oci_statement_type(resource stmt)">Return the query type of an OCI statement</s>
+<s f="ocifetchinto" u="int ocifetchinto(resource stmt, array &amp;output [, int mode])">Fetch a row of result data into an array</s>
+<s f="ocigetbufferinglob" u="bool ocigetbufferinglob()">Returns current state of buffering for a LOB</s>
+<s f="ocisetbufferinglob" u="bool ocisetbufferinglob( boolean flag )">Enables/disables buffering for a LOB</s>
+<s f="birdstep_autocommit" u="bool birdstep_autocommit(int index)"></s>
+<s f="birdstep_close" u="bool birdstep_close(int id)"></s>
+<s f="birdstep_commit" u="bool birdstep_commit(int index)"></s>
+<s f="birdstep_connect" u="int birdstep_connect(string server, string user, string pass)"></s>
+<s f="birdstep_exec" u="int birdstep_exec(int index, string exec_str)"></s>
+<s f="birdstep_fetch" u="bool birdstep_fetch(int index)"></s>
+<s f="birdstep_fieldname" u="string birdstep_fieldname(int index, int col)"></s>
+<s f="birdstep_fieldnum" u="int birdstep_fieldnum(int index)"></s>
+<s f="birdstep_freeresult" u="bool birdstep_freeresult(int index)"></s>
+<s f="birdstep_off_autocommit" u="bool birdstep_off_autocommit(int index)"></s>
+<s f="birdstep_result" u="mixed birdstep_result(int index, int col)"></s>
+<s f="birdstep_rollback" u="bool birdstep_rollback(int index)"></s>
+<s f="odbc_autocommit" u="mixed odbc_autocommit(resource connection_id [, int OnOff])">Toggle autocommit mode or get status</s>
+<s f="odbc_binmode" u="bool odbc_binmode(int result_id, int mode)">Handle binary column data</s>
+<s f="odbc_close" u="void odbc_close(resource connection_id)">Close an ODBC connection</s>
+<s f="odbc_close_all" u="void odbc_close_all(void)">Close all ODBC connections</s>
+<s f="odbc_columnprivileges" u="resource odbc_columnprivileges(resource connection_id, string catalog, string schema, string table, string column)">Returns a result identifier that can be used to fetch a list of columns and associated privileges for the specified table</s>
+<s f="odbc_columns" u="resource odbc_columns(resource connection_id [, string qualifier [, string owner [, string table_name [, string column_name]]]])">Returns a result identifier that can be used to fetch a list of column names in specified tables</s>
+<s f="odbc_commit" u="bool odbc_commit(resource connection_id)">Commit an ODBC transaction</s>
+<s f="odbc_connect" u="resource odbc_connect(string DSN, string user, string password [, int cursor_option])">Connect to a datasource</s>
+<s f="odbc_cursor" u="string odbc_cursor(resource result_id)">Get cursor name</s>
+<s f="odbc_data_source" u="array odbc_data_source(resource connection_id, int fetch_type)">Return information about the currently connected data source</s>
+<s f="odbc_error" u="string odbc_error([resource connection_id])">Get the last error code</s>
+<s f="odbc_errormsg" u="string odbc_errormsg([resource connection_id])">Get the last error message</s>
+<s f="odbc_exec" u="resource odbc_exec(resource connection_id, string query [, int flags])">Prepare and execute an SQL statement</s>
+<s f="odbc_execute" u="bool odbc_execute(resource result_id [, array parameters_array])">Execute a prepared statement</s>
+<s f="odbc_fetch_array" u="array odbc_fetch_array(int result [, int rownumber])">Fetch a result row as an associative array</s>
+<s f="odbc_fetch_into" u="int odbc_fetch_into(resource result_id, array result_array, [, int rownumber])">Fetch one result row into an array</s>
+<s f="odbc_fetch_object" u="object odbc_fetch_object(int result [, int rownumber])">Fetch a result row as an object</s>
+<s f="odbc_fetch_row" u="bool odbc_fetch_row(resource result_id [, int row_number])">Fetch a row</s>
+<s f="odbc_field_len" u="int odbc_field_len(resource result_id, int field_number)">Get the length (precision) of a column</s>
+<s f="odbc_field_name" u="string odbc_field_name(resource result_id, int field_number)">Get a column name</s>
+<s f="odbc_field_num" u="int odbc_field_num(resource result_id, string field_name)">Return column number</s>
+<s f="odbc_field_scale" u="int odbc_field_scale(resource result_id, int field_number)">Get the scale of a column</s>
+<s f="odbc_field_type" u="string odbc_field_type(resource result_id, int field_number)">Get the datatype of a column</s>
+<s f="odbc_foreignkeys" u="resource odbc_foreignkeys(resource connection_id, string pk_qualifier, string pk_owner, string pk_table, string fk_qualifier, string fk_owner, string fk_table)">Returns a result identifier to either a list of foreign keys in the specified table or a list of foreign keys in other tables that refer to the primary key in the specified table</s>
+<s f="odbc_free_result" u="bool odbc_free_result(resource result_id)">Free resources associated with a result</s>
+<s f="odbc_gettypeinfo" u="resource odbc_gettypeinfo(resource connection_id [, int data_type])">Returns a result identifier containing information about data types supported by the data source</s>
+<s f="odbc_longreadlen" u="bool odbc_longreadlen(int result_id, int length)">Handle LONG columns</s>
+<s f="odbc_next_result" u="bool odbc_next_result(resource result_id)">Checks if multiple results are avaiable</s>
+<s f="odbc_num_fields" u="int odbc_num_fields(resource result_id)">Get number of columns in a result</s>
+<s f="odbc_num_rows" u="int odbc_num_rows(resource result_id)">Get number of rows in a result</s>
+<s f="odbc_pconnect" u="resource odbc_pconnect(string DSN, string user, string password [, int cursor_option])">Establish a persistent connection to a datasource</s>
+<s f="odbc_prepare" u="resource odbc_prepare(resource connection_id, string query)">Prepares a statement for execution</s>
+<s f="odbc_primarykeys" u="resource odbc_primarykeys(resource connection_id, string qualifier, string owner, string table)">Returns a result identifier listing the column names that comprise the primary key for a table</s>
+<s f="odbc_procedurecolumns" u="resource odbc_procedurecolumns(resource connection_id [, string qualifier, string owner, string proc, string column])">Returns a result identifier containing the list of input and output parameters, as well as the columns that make up the result set for the specified procedures</s>
+<s f="odbc_procedures" u="resource odbc_procedures(resource connection_id [, string qualifier, string owner, string name])">Returns a result identifier containg the list of procedure names in a datasource</s>
+<s f="odbc_result" u="mixed odbc_result(resource result_id, mixed field)">Get result data</s>
+<s f="odbc_result_all" u="int odbc_result_all(resource result_id [, string format])">Print result as HTML table</s>
+<s f="odbc_rollback" u="bool odbc_rollback(resource connection_id)">Rollback a transaction</s>
+<s f="odbc_setoption" u="bool odbc_setoption(resource conn_id|result_id, int which, int option, int value)">Sets connection or statement options</s>
+<s f="odbc_specialcolumns" u="resource odbc_specialcolumns(resource connection_id, int type, string qualifier, string owner, string table, int scope, int nullable)">Returns a result identifier containing either the optimal set of columns that uniquely identifies a row in the table or columns that are automatically updated when any value in the row is updated by a transaction</s>
+<s f="odbc_statistics" u="resource odbc_statistics(resource connection_id, string qualifier, string owner, string name, int unique, int accuracy)">Returns a result identifier that contains statistics about a single table and the indexes associated with the table</s>
+<s f="odbc_tableprivileges" u="resource odbc_tableprivileges(resource connection_id, string qualifier, string owner, string name)">Returns a result identifier containing a list of tables and the privileges associated with each table</s>
+<s f="odbc_tables" u="resource odbc_tables(resource connection_id [, string qualifier [, string owner [, string name [, string table_types]]]])">Call the SQLTables function</s>
+<s f="solid_fetch_prev" u="bool solid_fetch_prev(resource result_id)"></s>
+<s f="openssl_csr_export" u="bool openssl_csr_export(resource csr, string &amp;out [, bool notext=true])">Exports a CSR to file or a var</s>
+<s f="openssl_csr_export_to_file" u="bool openssl_csr_export_to_file(resource csr, string outfilename [, bool notext=true])">Exports a CSR to file</s>
+<s f="openssl_csr_get_public_key" u="mixed openssl_csr_get_public_key(mixed csr)">Returns the subject of a CERT or FALSE on error</s>
+<s f="openssl_csr_get_subject" u="mixed openssl_csr_get_subject(mixed csr)">Returns the subject of a CERT or FALSE on error</s>
+<s f="openssl_csr_new" u="bool openssl_csr_new(array dn, resource &amp;privkey [, array configargs, array extraattribs])">Generates a privkey and CSR</s>
+<s f="openssl_csr_sign" u="resource openssl_csr_sign(mixed csr, mixed x509, mixed priv_key, long days [, array config_args [, long serial]])">Signs a cert with another CERT</s>
+<s f="openssl_error_string" u="mixed openssl_error_string(void)">Returns a description of the last error, and alters the index of the error messages. Returns false when the are no more messages</s>
+<s f="openssl_open" u="bool openssl_open(string data, &amp;string opendata, string ekey, mixed privkey)">Opens data</s>
+<s f="openssl_pkcs12_export" u="bool openssl_pkcs12_export(mixed x509, string &amp;out, mixed priv_key, string pass[, array args])">Creates and exports a PKCS12 to a var</s>
+<s f="openssl_pkcs12_export_to_file" u="bool openssl_pkcs12_export_to_file(mixed x509, string filename, mixed priv_key, string pass[, array args])">Creates and exports a PKCS to file</s>
+<s f="openssl_pkcs12_read" u="bool openssl_pkcs12_read(string PKCS12, array &amp;certs, string pass)">Parses a PKCS12 to an array</s>
+<s f="openssl_pkcs7_decrypt" u="bool openssl_pkcs7_decrypt(string infilename, string outfilename, mixed recipcert [, mixed recipkey])">Decrypts the S/MIME message in the file name infilename and output the results to the file name outfilename.  recipcert is a CERT for one of the recipients. recipkey specifies the private key matching recipcert, if recipcert does not include the key</s>
+<s f="openssl_pkcs7_encrypt" u="bool openssl_pkcs7_encrypt(string infile, string outfile, mixed recipcerts, array headers [, long flags [, long cipher]])">Encrypts the message in the file named infile with the certificates in recipcerts and output the result to the file named outfile</s>
+<s f="openssl_pkcs7_sign" u="bool openssl_pkcs7_sign(string infile, string outfile, mixed signcert, mixed signkey, array headers [, long flags [, string extracertsfilename]])">Signs the MIME message in the file named infile with signcert/signkey and output the result to file name outfile. headers lists plain text headers to exclude from the signed portion of the message, and should include to, from and subject as a minimum</s>
+<s f="openssl_pkcs7_verify" u="bool openssl_pkcs7_verify(string filename, long flags [, string signerscerts [, array cainfo [, string extracerts [, string content]]]])">Verifys that the data block is intact, the signer is who they say they are, and returns the CERTs of the signers</s>
+<s f="openssl_pkey_export" u="bool openssl_pkey_export(mixed key, &amp;mixed out [, string passphrase [, array config_args]])">Gets an exportable representation of a key into a string or file</s>
+<s f="openssl_pkey_export_to_file" u="bool openssl_pkey_export_to_file(mixed key, string outfilename [, string passphrase, array config_args)">Gets an exportable representation of a key into a file</s>
+<s f="openssl_pkey_free" u="void openssl_pkey_free(int key)">Frees a key</s>
+<s f="openssl_pkey_get_details" u="resource openssl_pkey_get_details(resource key)">returns an array with the key details (bits, pkey, type)</s>
+<s f="openssl_pkey_get_private" u="int openssl_pkey_get_private(string key [, string passphrase])">Gets private keys</s>
+<s f="openssl_pkey_get_public" u="int openssl_pkey_get_public(mixed cert)">Gets public key from X.509 certificate</s>
+<s f="openssl_pkey_new" u="resource openssl_pkey_new([array configargs])">Generates a new private key</s>
+<s f="openssl_private_decrypt" u="bool openssl_private_decrypt(string data, string decrypted, mixed key [, int padding])">Decrypts data with private key</s>
+<s f="openssl_private_encrypt" u="bool openssl_private_encrypt(string data, string crypted, mixed key [, int padding])">Encrypts data with private key</s>
+<s f="openssl_public_decrypt" u="bool openssl_public_decrypt(string data, string crypted, resource key [, int padding])">Decrypts data with public key</s>
+<s f="openssl_public_encrypt" u="bool openssl_public_encrypt(string data, string crypted, mixed key [, int padding])">Encrypts data with public key</s>
+<s f="openssl_seal" u="int openssl_seal(string data, &amp;string sealdata, &amp;array ekeys, array pubkeys)">Seals data</s>
+<s f="openssl_sign" u="bool openssl_sign(string data, &amp;string signature, mixed key[, int signature_alg])">Signs data</s>
+<s f="openssl_verify" u="int openssl_verify(string data, string signature, mixed key [, int signature_algo])">Verifys data</s>
+<s f="openssl_x509_check_private_key" u="bool openssl_x509_check_private_key(mixed cert, mixed key)">Checks if a private key corresponds to a CERT</s>
+<s f="openssl_x509_checkpurpose" u="int openssl_x509_checkpurpose(mixed x509cert, int purpose, array cainfo [, string untrustedfile])">Checks the CERT to see if it can be used for the purpose in purpose. cainfo holds information about trusted CAs</s>
+<s f="openssl_x509_export" u="bool openssl_x509_export(mixed x509, string &amp;out [, bool notext = true])">Exports a CERT to file or a var</s>
+<s f="openssl_x509_export_to_file" u="bool openssl_x509_export_to_file(mixed x509, string outfilename [, bool notext = true])">Exports a CERT to file or a var</s>
+<s f="openssl_x509_free" u="void openssl_x509_free(resource x509)">Frees X.509 certificates</s>
+<s f="openssl_x509_parse" u="array openssl_x509_parse(mixed x509 [, bool shortnames=true])">Returns an array of the fields/values of the CERT</s>
+<s f="openssl_x509_read" u="resource openssl_x509_read(mixed cert)">Reads X.509 certificates</s>
+<s f="pcntl_alarm" u="int pcntl_alarm(int seconds)">Set an alarm clock for delivery of a signal</s>
+<s f="pcntl_exec" u="bool pcntl_exec(string path [, array args [, array envs]])">Executes specified program in current process space as defined by exec(2)</s>
+<s f="pcntl_fork" u="int pcntl_fork(void)">Forks the currently running process following the same behavior as the UNIX fork() system call</s>
+<s f="pcntl_getpriority" u="int pcntl_getpriority([int pid [, int process_identifier]])">Get the priority of any process</s>
+<s f="pcntl_setpriority" u="bool pcntl_setpriority(int priority [, int pid [, int process_identifier]])">Change the priority of any process</s>
+<s f="pcntl_signal" u="bool pcntl_signal(int signo, callback handle [, bool restart_syscalls])">Assigns a system signal handler to a PHP function</s>
+<s f="pcntl_wait" u="int pcntl_wait(int &amp;status)">Waits on or returns the status of a forked child as defined by the waitpid() system call</s>
+<s f="pcntl_waitpid" u="int pcntl_waitpid(int pid, int &amp;status, int options)">Waits on or returns the status of a forked child as defined by the waitpid() system call</s>
+<s f="pcntl_wexitstatus" u="int pcntl_wexitstatus(int status)">Returns the status code of a child's exit</s>
+<s f="pcntl_wifexited" u="bool pcntl_wifexited(int status)">Returns true if the child status code represents a successful exit</s>
+<s f="pcntl_wifsignaled" u="bool pcntl_wifsignaled(int status)">Returns true if the child status code represents a process that was terminated due to a signal</s>
+<s f="pcntl_wifstopped" u="bool pcntl_wifstopped(int status)">Returns true if the child status code represents a stopped process (WUNTRACED must have been used with waitpid)</s>
+<s f="pcntl_wstopsig" u="int pcntl_wstopsig(int status)">Returns the number of the signal that caused the process to stop who's status code is passed</s>
+<s f="pcntl_wtermsig" u="int pcntl_wtermsig(int status)">Returns the number of the signal that terminated the process who's status code is passed</s>
+<s f="preg_grep" u="array preg_grep(string regex, array input [, int flags])">Searches array and returns entries which match regex</s>
+<s f="preg_last_error" u="int preg_last_error()">Returns the error code of the last regexp execution.</s>
+<s f="preg_match" u="int preg_match(string pattern, string subject [, array subpatterns [, int flags [, int offset]]])">Perform a Perl-style regular expression match</s>
+<s f="preg_match_all" u="int preg_match_all(string pattern, string subject, array subpatterns [, int flags [, int offset]])">Perform a Perl-style global regular expression match</s>
+<s f="preg_quote" u="string preg_quote(string str [, string delim_char])">Quote regular expression characters plus an optional character</s>
+<s f="preg_replace" u="string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]])">Perform Perl-style regular expression replacement.</s>
+<s f="preg_replace_callback" u="string preg_replace_callback(mixed regex, mixed callback, mixed subject [, int limit [, count]])">Perform Perl-style regular expression replacement using replacement callback.</s>
+<s f="preg_split" u="array preg_split(string pattern, string subject [, int limit [, int flags]])">Split string into an array using a perl-style regular expression as a delimiter</s>
+<s f="pdo_drivers" u="array pdo_drivers()">Return array of available PDO drivers</s>
+<s f="PDO::__construct" u="void PDO::__construct(string dsn, string username, string passwd [, array options])"></s>
+<s f="PDO::__sleep" u="int PDO::__sleep()">Prevents serialization of a PDO instance</s>
+<s f="PDO::__wakeup" u="int PDO::__wakeup()">Prevents use of a PDO instance that has been unserialized</s>
+<s f="PDO::beginTransaction" u="bool PDO::beginTransaction()">Initiates a transaction</s>
+<s f="PDO::commit" u="bool PDO::commit()">Commit a transaction</s>
+<s f="PDO::errorCode" u="string PDO::errorCode()">Fetch the error code associated with the last operation on the database handle</s>
+<s f="PDO::errorInfo" u="int PDO::errorInfo()">Fetch extended error information associated with the last operation on the database handle</s>
+<s f="PDO::exec" u="long PDO::exec(string query)">Execute a query that does not return a row set, returning the number of affected rows</s>
+<s f="PDO::getAttribute" u="mixed PDO::getAttribute(long attribute)">Get an attribute</s>
+<s f="PDO::lastInsertId" u="string PDO::lastInsertId([string seqname])">Returns the id of the last row that we affected on this connection.  Some databases require a sequence or table name to be passed in.  Not always meaningful.</s>
+<s f="PDO::prepare" u="object PDO::prepare(string statment [, array options])">Prepares a statement for execution and returns a statement object</s>
+<s f="PDO::query" u="object PDO::query(string sql [, PDOStatement::setFetchMode() args])">Prepare and execute $sql; returns the statement object for iteration</s>
+<s f="PDO::quote" u="string PDO::quote(string string [, int paramtype])">quotes string for use in a query.  The optional paramtype acts as a hint for drivers that have alternate quoting styles.  The default value is PDO_PARAM_STR</s>
+<s f="PDO::rollBack" u="bool PDO::rollBack()">roll back a transaction</s>
+<s f="PDO::setAttribute" u="bool PDO::setAttribute(long attribute, mixed value)">Set an attribute</s>
+<s f="pdo_drivers" u="array pdo_drivers()">Return array of available PDO drivers</s>
+<s f="PDOStatement::__sleep" u="int PDOStatement::__sleep()">Prevents serialization of a PDOStatement instance</s>
+<s f="PDOStatement::__wakeup" u="int PDOStatement::__wakeup()">Prevents use of a PDOStatement instance that has been unserialized</s>
+<s f="PDOStatement::bindColumn" u="bool PDOStatement::bindColumn(mixed $column, mixed &amp;$param [, int $type [, int $maxlen [, mixed $driverdata]]])">bind a column to a PHP variable.  On each row fetch $param will contain the value of the corresponding column.  $column is the 1-based offset of the column, or the column name.  For portability, don't call this before execute().</s>
+<s f="PDOStatement::bindParam" u="bool PDOStatement::bindParam(mixed $paramno, mixed &amp;$param [, int $type [, int $maxlen [, mixed $driverdata]]])">bind a parameter to a PHP variable.  $paramno is the 1-based position of the placeholder in the SQL statement (but can be the parameter name for drivers that support named placeholders).  This isn't supported by all drivers.  It should be called prior to execute().</s>
+<s f="PDOStatement::bindValue" u="bool PDOStatement::bindValue(mixed $paramno, mixed $param [, int $type ])">bind an input parameter to the value of a PHP variable.  $paramno is the 1-based position of the placeholder in the SQL statement (but can be the parameter name for drivers that support named placeholders).  It should be called prior to execute().</s>
+<s f="PDOStatement::closeCursor" u="bool PDOStatement::closeCursor()">Closes the cursor, leaving the statement ready for re-execution.</s>
+<s f="PDOStatement::columnCount" u="int PDOStatement::columnCount()">Returns the number of columns in the result set</s>
+<s f="PDOStatement::debugDumpParams" u="void PDOStatement::debugDumpParams()">A utility for internals hackers to debug parameter internals</s>
+<s f="PDOStatement::errorCode" u="string PDOStatement::errorCode()">Fetch the error code associated with the last operation on the statement handle</s>
+<s f="PDOStatement::errorInfo" u="array PDOStatement::errorInfo()">Fetch extended error information associated with the last operation on the statement handle</s>
+<s f="PDOStatement::execute" u="bool PDOStatement::execute([array $bound_input_params])">Execute a prepared statement, optionally binding parameters</s>
+<s f="PDOStatement::fetch" u="mixed PDOStatement::fetch([int $how = PDO_FETCH_BOTH [, int $orientation [, int $offset]]])">Fetches the next row and returns it, or false if there are no more rows</s>
+<s f="PDOStatement::fetchAll" u="array PDOStatement::fetchAll([int $how = PDO_FETCH_BOTH [, string class_name [, NULL|array ctor_args]]])">Returns an array of all of the results.</s>
+<s f="PDOStatement::fetchColumn" u="string PDOStatement::fetchColumn([int column_number])">Returns a data of the specified column in the result set.</s>
+<s f="PDOStatement::fetchObject" u="mixed PDOStatement::fetchObject(string class_name [, NULL|array ctor_args])">Fetches the next row and returns it as an object.</s>
+<s f="PDOStatement::getAttribute" u="mixed PDOStatement::getAttribute(long attribute)">Get an attribute</s>
+<s f="PDOStatement::getColumnMeta" u="array PDOStatement::getColumnMeta(int $column)">Returns meta data for a numbered column</s>
+<s f="PDOStatement::nextRowset" u="bool PDOStatement::nextRowset()">Advances to the next rowset in a multi-rowset statement handle. Returns true if it succeded, false otherwise</s>
+<s f="PDOStatement::rowCount" u="int PDOStatement::rowCount()">Returns the number of rows in a result set, or the number of rows affected by the last execute().  It is not always meaningful.</s>
+<s f="PDOStatement::setAttribute" u="bool PDOStatement::setAttribute(long attribute, mixed value)">Set an attribute</s>
+<s f="PDOStatement::setFetchMode" u="bool PDOStatement::setFetchMode(int mode [mixed* params])">Changes the default fetch mode for subsequent fetches (params have different meaning for different fetch modes)</s>
+<s f="pg_affected_rows" u="int pg_affected_rows(resource result)">Returns the number of affected tuples</s>
+<s f="pg_cancel_query" u="bool pg_cancel_query(resource connection)">Cancel request</s>
+<s f="pg_client_encoding" u="string pg_client_encoding([resource connection])">Get the current client encoding</s>
+<s f="pg_close" u="bool pg_close([resource connection])">Close a PostgreSQL connection</s>
+<s f="pg_connect" u="resource pg_connect(string connection_string[, int connect_type] | [string host, string port [, string options [, string tty,]]] string database)">Open a PostgreSQL connection</s>
+<s f="pg_connection_busy" u="bool pg_connection_busy(resource connection)">Get connection is busy or not</s>
+<s f="pg_connection_reset" u="bool pg_connection_reset(resource connection)">Reset connection (reconnect)</s>
+<s f="pg_connection_status" u="int pg_connection_status(resource connnection)">Get connection status</s>
+<s f="pg_convert" u="array pg_convert(resource db, string table, array values[, int options])">Check and convert values for PostgreSQL SQL statement</s>
+<s f="pg_copy_from" u="bool pg_copy_from(resource connection, string table_name , array rows [, string delimiter [, string null_as]])">Copy table from array</s>
+<s f="pg_copy_to" u="array pg_copy_to(resource connection, string table_name [, string delimiter [, string null_as]])">Copy table to array</s>
+<s f="pg_dbname" u="string pg_dbname([resource connection])">Get the database name</s>
+<s f="pg_delete" u="mixed pg_delete(resource db, string table, array ids[, int options])">Delete records has ids (id=&gt;value)</s>
+<s f="pg_end_copy" u="bool pg_end_copy([resource connection])">Sync with backend. Completes the Copy command</s>
+<s f="pg_escape_bytea" u="string pg_escape_bytea([resource connection,] string data)">Escape binary for bytea type</s>
+<s f="pg_escape_string" u="string pg_escape_string([resource connection,] string data)">Escape string for text/char type</s>
+<s f="pg_execute" u="resource pg_execute([resource connection,] string stmtname, array params)">Execute a prepared query</s>
+<s f="pg_fetch_all" u="array pg_fetch_all(resource result)">Fetch all rows into array</s>
+<s f="pg_fetch_all_columns" u="array pg_fetch_all_columns(resource result [, int column_number])">Fetch all rows into array</s>
+<s f="pg_fetch_array" u="array pg_fetch_array(resource result [, int row [, int result_type]])">Fetch a row as an array</s>
+<s f="pg_fetch_assoc" u="array pg_fetch_assoc(resource result [, int row])">Fetch a row as an assoc array</s>
+<s f="pg_fetch_object" u="object pg_fetch_object(resource result [, int row [, string class_name [, NULL|array ctor_params]]])">Fetch a row as an object</s>
+<s f="pg_fetch_result" u="mixed pg_fetch_result(resource result, [int row_number,] mixed field_name)">Returns values from a result identifier</s>
+<s f="pg_fetch_row" u="array pg_fetch_row(resource result [, int row [, int result_type]])">Get a row as an enumerated array</s>
+<s f="pg_field_is_null" u="int pg_field_is_null(resource result, [int row,] mixed field_name_or_number)">Test if a field is NULL</s>
+<s f="pg_field_name" u="string pg_field_name(resource result, int field_number)">Returns the name of the field</s>
+<s f="pg_field_num" u="int pg_field_num(resource result, string field_name)">Returns the field number of the named field</s>
+<s f="pg_field_prtlen" u="int pg_field_prtlen(resource result, [int row,] mixed field_name_or_number)">Returns the printed length</s>
+<s f="pg_field_size" u="int pg_field_size(resource result, int field_number)">Returns the internal size of the field</s>
+<s f="pg_field_table" u="mixed pg_field_table(resource result, int field_number[, bool oid_only])">Returns the name of the table field belongs to, or table's oid if oid_only is true</s>
+<s f="pg_field_type" u="string pg_field_type(resource result, int field_number)">Returns the type name for the given field</s>
+<s f="pg_field_type_oid" u="string pg_field_type_oid(resource result, int field_number)">Returns the type oid for the given field</s>
+<s f="pg_free_result" u="bool pg_free_result(resource result)">Free result memory</s>
+<s f="pg_get_notify" u="array pg_get_notify([resource connection[, result_type]])">Get asynchronous notification</s>
+<s f="pg_get_pid" u="int pg_get_pid([resource connection)">Get backend(server) pid</s>
+<s f="pg_get_result" u="resource pg_get_result(resource connection)">Get asynchronous query result</s>
+<s f="pg_host" u="string pg_host([resource connection])">Returns the host name associated with the connection</s>
+<s f="pg_insert" u="mixed pg_insert(resource db, string table, array values[, int options])">Insert values (filed=&gt;value) to table</s>
+<s f="pg_last_error" u="string pg_last_error([resource connection])">Get the error message string</s>
+<s f="pg_last_notice" u="string pg_last_notice(resource connection)">Returns the last notice set by the backend</s>
+<s f="pg_last_oid" u="string pg_last_oid(resource result)">Returns the last object identifier</s>
+<s f="pg_lo_close" u="bool pg_lo_close(resource large_object)">Close a large object</s>
+<s f="pg_lo_create" u="int pg_lo_create([resource connection])">Create a large object</s>
+<s f="pg_lo_export" u="bool pg_lo_export([resource connection, ] int objoid, string filename)">Export large object direct to filesystem</s>
+<s f="pg_lo_import" u="int pg_lo_import([resource connection, ] string filename)">Import large object direct from filesystem</s>
+<s f="pg_lo_open" u="resource pg_lo_open([resource connection,] int large_object_oid, string mode)">Open a large object and return fd</s>
+<s f="pg_lo_read" u="string pg_lo_read(resource large_object [, int len])">Read a large object</s>
+<s f="pg_lo_read_all" u="int pg_lo_read_all(resource large_object)">Read a large object and send straight to browser</s>
+<s f="pg_lo_seek" u="bool pg_lo_seek(resource large_object, int offset [, int whence])">Seeks position of large object</s>
+<s f="pg_lo_tell" u="int pg_lo_tell(resource large_object)">Returns current position of large object</s>
+<s f="pg_lo_unlink" u="bool pg_lo_unlink([resource connection,] string large_object_oid)">Delete a large object</s>
+<s f="pg_lo_write" u="int pg_lo_write(resource large_object, string buf [, int len])">Write a large object</s>
+<s f="pg_meta_data" u="array pg_meta_data(resource db, string table)">Get meta_data</s>
+<s f="pg_num_fields" u="int pg_num_fields(resource result)">Return the number of fields in the result</s>
+<s f="pg_num_rows" u="int pg_num_rows(resource result)">Return the number of rows in the result</s>
+<s f="pg_options" u="string pg_options([resource connection])">Get the options associated with the connection</s>
+<s f="pg_pconnect" u="resource pg_pconnect(string connection_string | [string host, string port [, string options [, string tty,]]] string database)">Open a persistent PostgreSQL connection</s>
+<s f="pg_ping" u="bool pg_ping([resource connection])">Ping database. If connection is bad, try to reconnect.</s>
+<s f="pg_port" u="int pg_port([resource connection])">Return the port number associated with the connection</s>
+<s f="pg_prepare" u="resource pg_prepare([resource connection,] string stmtname, string query)">Prepare a query for future execution</s>
+<s f="pg_put_line" u="bool pg_put_line([resource connection,] string query)">Send null-terminated string to backend server</s>
+<s f="pg_query" u="resource pg_query([resource connection,] string query)">Execute a query</s>
+<s f="pg_query_params" u="resource pg_query_params([resource connection,] string query, array params)">Execute a query</s>
+<s f="pg_result_error" u="string pg_result_error(resource result)">Get error message associated with result</s>
+<s f="pg_result_error_field" u="string pg_result_error_field(resource result, int fieldcode)">Get error message field associated with result</s>
+<s f="pg_result_seek" u="bool pg_result_seek(resource result, int offset)">Set internal row offset</s>
+<s f="pg_result_status" u="mixed pg_result_status(resource result[, long result_type])">Get status of query result</s>
+<s f="pg_select" u="mixed pg_select(resource db, string table, array ids[, int options])">Select records that has ids (id=&gt;value)</s>
+<s f="pg_send_execute" u="bool pg_send_execute(resource connection, string stmtname, array params)">Executes prevriously prepared stmtname asynchronously</s>
+<s f="pg_send_prepare" u="bool pg_send_prepare(resource connection, string stmtname, string query)">Asynchronously prepare a query for future execution</s>
+<s f="pg_send_query" u="bool pg_send_query(resource connection, string query)">Send asynchronous query</s>
+<s f="pg_send_query_params" u="bool pg_send_query_params(resource connection, string query)">Send asynchronous parameterized query</s>
+<s f="pg_set_client_encoding" u="int pg_set_client_encoding([resource connection,] string encoding)">Set client encoding</s>
+<s f="pg_set_error_verbosity" u="int pg_set_error_verbosity([resource connection,] int verbosity)">Set error verbosity</s>
+<s f="pg_trace" u="bool pg_trace(string filename [, string mode [, resource connection]])">Enable tracing a PostgreSQL connection</s>
+<s f="pg_transaction_status" u="int pg_transaction_status(resource connnection)">Get transaction status</s>
+<s f="pg_tty" u="string pg_tty([resource connection])">Return the tty name associated with the connection</s>
+<s f="pg_unescape_bytea" u="string pg_unescape_bytea(string data)">Unescape binary for bytea type</s>
+<s f="pg_untrace" u="bool pg_untrace([resource connection])">Disable tracing of a PostgreSQL connection</s>
+<s f="pg_update" u="mixed pg_update(resource db, string table, array fields, array ids[, int options])">Update table using values (field=&gt;value) and ids (id=&gt;value)</s>
+<s f="pg_version" u="array pg_version([resource connection])">Returns an array with client, protocol and server version (when available)</s>
+<s f="posix_access" u="bool posix_access(string file [, int mode])">Determine accessibility of a file (POSIX.1 5.6.3)</s>
+<s f="posix_ctermid" u="string posix_ctermid(void)">Generate terminal path name (POSIX.1, 4.7.1)</s>
+<s f="posix_get_last_error" u="int posix_get_last_error(void)">Retrieve the error number set by the last posix function which failed.</s>
+<s f="posix_getcwd" u="string posix_getcwd(void)">Get working directory pathname (POSIX.1, 5.2.2)</s>
+<s f="posix_getegid" u="int posix_getegid(void)">Get the current effective group id (POSIX.1, 4.2.1)</s>
+<s f="posix_geteuid" u="int posix_geteuid(void)">Get the current effective user id (POSIX.1, 4.2.1)</s>
+<s f="posix_getgid" u="int posix_getgid(void)">Get the current group id (POSIX.1, 4.2.1)</s>
+<s f="posix_getgrgid" u="array posix_getgrgid(long gid)">Group database access (POSIX.1, 9.2.1)</s>
+<s f="posix_getgrnam" u="array posix_getgrnam(string groupname)">Group database access (POSIX.1, 9.2.1)</s>
+<s f="posix_getgroups" u="array posix_getgroups(void)">Get supplementary group id's (POSIX.1, 4.2.3)</s>
+<s f="posix_getlogin" u="string posix_getlogin(void)">Get user name (POSIX.1, 4.2.4)</s>
+<s f="posix_getpgid" u="int posix_getpgid(void)">Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally)</s>
+<s f="posix_getpgrp" u="int posix_getpgrp(void)">Get current process group id (POSIX.1, 4.3.1)</s>
+<s f="posix_getpid" u="int posix_getpid(void)">Get the current process id (POSIX.1, 4.1.1)</s>
+<s f="posix_getppid" u="int posix_getppid(void)">Get the parent process id (POSIX.1, 4.1.1)</s>
+<s f="posix_getpwnam" u="array posix_getpwnam(string groupname)">User database access (POSIX.1, 9.2.2)</s>
+<s f="posix_getpwuid" u="array posix_getpwuid(long uid)">User database access (POSIX.1, 9.2.2)</s>
+<s f="posix_getrlimit" u="array posix_getrlimit(void)">Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally)</s>
+<s f="posix_getsid" u="int posix_getsid(void)">Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally)</s>
+<s f="posix_getuid" u="int posix_getuid(void)">Get the current user id (POSIX.1, 4.2.1)</s>
+<s f="posix_initgroups" u="bool posix_initgroups(string name, int base_group_id)">Calculate the group access list for the user specified in name.</s>
+<s f="posix_isatty" u="bool posix_isatty(int fd)">Determine if filedesc is a tty (POSIX.1, 4.7.1)</s>
+<s f="posix_kill" u="bool posix_kill(int pid, int sig)">Send a signal to a process (POSIX.1, 3.3.2)</s>
+<s f="posix_mkfifo" u="bool posix_mkfifo(string pathname, int mode)">Make a FIFO special file (POSIX.1, 5.4.2)</s>
+<s f="posix_mknod" u="bool posix_mknod(string pathname, int mode [, int major [, int minor]])">Make a special or ordinary file (POSIX.1)</s>
+<s f="posix_setegid" u="bool posix_setegid(int uid)">Set effective group id</s>
+<s f="posix_seteuid" u="bool posix_seteuid(int uid)">Set effective user id</s>
+<s f="posix_setgid" u="bool posix_setgid(int uid)">Set group id (POSIX.1, 4.2.2)</s>
+<s f="posix_setpgid" u="bool posix_setpgid(int pid, int pgid)">Set process group id for job control (POSIX.1, 4.3.3)</s>
+<s f="posix_setsid" u="int posix_setsid(void)">Create session and set process group id (POSIX.1, 4.3.2)</s>
+<s f="posix_setuid" u="bool posix_setuid(int uid)">Set user id (POSIX.1, 4.2.2)</s>
+<s f="posix_strerror" u="string posix_strerror(int errno)">Retrieve the system error message associated with the given errno.</s>
+<s f="posix_times" u="array posix_times(void)">Get process times (POSIX.1, 4.5.2)</s>
+<s f="posix_ttyname" u="string posix_ttyname(int fd)">Determine terminal device name (POSIX.1, 4.7.2)</s>
+<s f="posix_uname" u="array posix_uname(void)">Get system name (POSIX.1, 4.4.1)</s>
+<s f="pspell_add_to_personal" u="bool pspell_add_to_personal(int pspell, string word)">Adds a word to a personal list</s>
+<s f="pspell_add_to_session" u="bool pspell_add_to_session(int pspell, string word)">Adds a word to the current session</s>
+<s f="pspell_check" u="bool pspell_check(int pspell, string word)">Returns true if word is valid</s>
+<s f="pspell_clear_session" u="bool pspell_clear_session(int pspell)">Clears the current session</s>
+<s f="pspell_config_create" u="int pspell_config_create(string language [, string spelling [, string jargon [, string encoding]]])">Create a new config to be used later to create a manager</s>
+<s f="pspell_config_data_dir" u="bool pspell_config_data_dir(int conf, string directory)">location of language data files</s>
+<s f="pspell_config_dict_dir" u="bool pspell_config_dict_dir(int conf, string directory)">location of the main word list</s>
+<s f="pspell_config_ignore" u="bool pspell_config_ignore(int conf, int ignore)">Ignore words &lt;= n chars</s>
+<s f="pspell_config_mode" u="bool pspell_config_mode(int conf, long mode)">Select mode for config (PSPELL_FAST, PSPELL_NORMAL or PSPELL_BAD_SPELLERS)</s>
+<s f="pspell_config_personal" u="bool pspell_config_personal(int conf, string personal)">Use a personal dictionary for this config</s>
+<s f="pspell_config_repl" u="bool pspell_config_repl(int conf, string repl)">Use a personal dictionary with replacement pairs for this config</s>
+<s f="pspell_config_runtogether" u="bool pspell_config_runtogether(int conf, bool runtogether)">Consider run-together words as valid components</s>
+<s f="pspell_config_save_repl" u="bool pspell_config_save_repl(int conf, bool save)">Save replacement pairs when personal list is saved for this config</s>
+<s f="pspell_new" u="int pspell_new(string language [, string spelling [, string jargon [, string encoding [, int mode]]]])">Load a dictionary</s>
+<s f="pspell_new_config" u="int pspell_new_config(int config)">Load a dictionary based on the given config</s>
+<s f="pspell_new_personal" u="int pspell_new_personal(string personal, string language [, string spelling [, string jargon [, string encoding [, int mode]]]])">Load a dictionary with a personal wordlist</s>
+<s f="pspell_save_wordlist" u="bool pspell_save_wordlist(int pspell)">Saves the current (personal) wordlist</s>
+<s f="pspell_store_replacement" u="bool pspell_store_replacement(int pspell, string misspell, string correct)">Notify the dictionary of a user-selected replacement</s>
+<s f="pspell_suggest" u="array pspell_suggest(int pspell, string word)">Returns array of suggestions</s>
+<s f="readline" u="string readline([string prompt])">Reads a line</s>
+<s f="readline_add_history" u="bool readline_add_history([string prompt])">Adds a line to the history</s>
+<s f="readline_callback_handler_install" u="void readline_callback_handler_install(string prompt, mixed callback)">Initializes the readline callback interface and terminal, prints the prompt and returns immediately</s>
+<s f="readline_callback_handler_remove" u="bool readline_callback_handler_remove()">Removes a previously installed callback handler and restores terminal settings</s>
+<s f="readline_callback_read_char" u="void readline_callback_read_char()">Informs the readline callback interface that a character is ready for input</s>
+<s f="readline_clear_history" u="bool readline_clear_history(void)">Clears the history</s>
+<s f="readline_completion_function" u="bool readline_completion_function(string funcname)">Readline completion function?</s>
+<s f="readline_info" u="mixed readline_info([string varname] [, string newvalue])">Gets/sets various internal readline variables.</s>
+<s f="readline_list_history" u="array readline_list_history(void)">Lists the history</s>
+<s f="readline_on_new_line" u="void readline_on_new_line(void)">Inform readline that the cursor has moved to a new line</s>
+<s f="readline_read_history" u="bool readline_read_history([string filename] [, int from] [,int to])">Reads the history</s>
+<s f="readline_redisplay" u="void readline_redisplay(void)">Ask readline to redraw the display</s>
+<s f="readline_write_history" u="bool readline_write_history([string filename])">Writes the history</s>
+<s f="recode_file" u="bool recode_file(string request, resource input, resource output)">Recode file input into file output according to request</s>
+<s f="recode_string" u="string recode_string(string request, string str)">Recode string str according to request string</s>
+<s f="session_cache_expire" u="int session_cache_expire([int new_cache_expire])">Return the current cache expire. If new_cache_expire is given, the current cache_expire is replaced with new_cache_expire</s>
+<s f="session_cache_limiter" u="string session_cache_limiter([string new_cache_limiter])">Return the current cache limiter. If new_cache_limited is given, the current cache_limiter is replaced with new_cache_limiter</s>
+<s f="session_decode" u="bool session_decode(string data)">Deserializes data and reinitializes the variables</s>
+<s f="session_destroy" u="bool session_destroy(void)">Destroy the current session and all data associated with it</s>
+<s f="session_encode" u="string session_encode(void)">Serializes the current setup and returns the serialized representation</s>
+<s f="session_get_cookie_params" u="array session_get_cookie_params(void)">Return the session cookie parameters</s>
+<s f="session_id" u="string session_id([string newid])">Return the current session id. If newid is given, the session id is replaced with newid</s>
+<s f="session_module_name" u="string session_module_name([string newname])">Return the current module name used for accessing session data. If newname is given, the module name is replaced with newname</s>
+<s f="session_name" u="string session_name([string newname])">Return the current session name. If newname is given, the session name is replaced with newname</s>
+<s f="session_regenerate_id" u="bool session_regenerate_id([bool delete_old_session])">Update the current session id with a newly generated one. If delete_old_session is set to true, remove the old session.</s>
+<s f="session_save_path" u="string session_save_path([string newname])">Return the current save path passed to module_name. If newname is given, the save path is replaced with newname</s>
+<s f="session_set_cookie_params" u="void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly]]]])">Set session cookie parameters</s>
+<s f="session_set_save_handler" u="void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)">Sets user-level functions</s>
+<s f="session_start" u="bool session_start(void)">Begin session - reinitializes freezed variables, registers browsers etc</s>
+<s f="session_unset" u="void session_unset(void)">Unset all registered variables</s>
+<s f="session_write_close" u="void session_write_close(void)">Write session data and end session</s>
+<s f="SimpleXMLElement::addAttribute" u="void SimpleXMLElement::addAttribute(string qName, string value [,string ns])">Add Attribute with optional namespace information</s>
+<s f="SimpleXMLElement::addChild" u="void SimpleXMLElement::addChild(string qName [, string value [, string ns]])">Add Element with optional namespace information</s>
+<s f="SimpleXMLElement::asXML" u="string SimpleXMLElement::asXML([string filename])">Return a well-formed XML string based on SimpleXML element</s>
+<s f="SimpleXMLElement::attributes" u="array SimpleXMLElement::attributes([string ns [, bool is_prefix]])">Identifies an element's attributes</s>
+<s f="SimpleXMLElement::children" u="object SimpleXMLElement::children([string ns [, bool is_prefix]])">Finds children of given node</s>
+<s f="SimpleXMLElement::getDocNamespaces" u="string SimpleXMLElement::getDocNamespaces([bool recursive])">Return all namespaces registered with document</s>
+<s f="SimpleXMLElement::getName" u="object SimpleXMLElement::getName()">Finds children of given node</s>
+<s f="SimpleXMLElement::getNamespaces" u="string SimpleXMLElement::getNamespaces([bool recursve])">Return all namespaces in use</s>
+<s f="SimpleXMLElement::registerXPathNamespace" u="bool SimpleXMLElement::registerXPathNamespace(string prefix, string ns)">Creates a prefix/ns context for the next XPath query</s>
+<s f="SimpleXMLElement::xpath" u="array SimpleXMLElement::xpath(string path)">Runs XPath query on the XML data</s>
+<s f="SimpleXMLElement::__construct" u=" SimpleXMLElement::__construct(string data [, int options [, bool data_is_url [, string ns [, bool is_prefix]]]])">SimpleXMLElement constructor</s>
+<s f="confirm_extname_compiled" u="string confirm_extname_compiled(string arg)">Return a string to confirm that the module is compiled in</s>
+<s f="php_snmpv3" u="void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st)">* * Generic SNMPv3 object fetcher * From here is passed on the the common internal object fetcher. * * st=SNMP_CMD_GET   snmp3_get() - query an agent and return a single value. * st=SNMP_CMD_GETNEXT   snmp3_getnext() - query an agent and return the next single value. * st=SNMP_CMD_WALK   snmp3_walk() - walk the mib and return a single dimensional array  *                       containing the values. * st=SNMP_CMD_REALWALK   snmp3_real_walk() - walk the mib and return an  *                            array of oid,value pairs. * st=SNMP_CMD_SET  snmp3_set() - query an agent and set a single value *</s>
+<s f="snmp2_get" u="string snmp2_get(string host, string community, string object_id [, int timeout [, int retries]])">Fetch a SNMP object</s>
+<s f="snmp2_getnext" u="string snmp2_getnext(string host, string community, string object_id [, int timeout [, int retries]])">Fetch a SNMP object</s>
+<s f="snmp2_real_walk" u="array snmp2_real_walk(string host, string community, string object_id [, int timeout [, int retries]])">Return all objects including their respective object id withing the specified one</s>
+<s f="snmp2_set" u="int snmp2_set(string host, string community, string object_id, string type, mixed value [, int timeout [, int retries]])">Set the value of a SNMP object</s>
+<s f="snmp2_walk" u="array snmp2_walk(string host, string community, string object_id [, int timeout [, int retries]])">Return all objects under the specified object id</s>
+<s f="snmp3_get" u="int snmp3_get(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])">Fetch the value of a SNMP object</s>
+<s f="snmp3_getnext" u="int snmp3_getnext(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])">Fetch the value of a SNMP object</s>
+<s f="snmp3_real_walk" u="int snmp3_real_walk(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])">Fetch the value of a SNMP object</s>
+<s f="snmp3_set" u="int snmp3_set(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id, string type, mixed value [, int timeout [, int retries]])">Fetch the value of a SNMP object</s>
+<s f="snmp3_walk" u="int snmp3_walk(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])">Fetch the value of a SNMP object</s>
+<s f="snmp_get_quick_print" u="bool snmp_get_quick_print(void)">Return the current status of quick_print</s>
+<s f="snmp_get_valueretrieval" u="int snmp_get_valueretrieval()">Return the method how the SNMP values will be returned</s>
+<s f="snmp_read_mib" u="int snmp_read_mib(string filename)">Reads and parses a MIB file into the active MIB tree.</s>
+<s f="snmp_set_enum_print" u="void snmp_set_enum_print(int enum_print)">Return all values that are enums with their enum value instead of the raw integer</s>
+<s f="snmp_set_oid_output_format" u="void snmp_set_oid_output_format(int oid_format)">Set the OID output format.</s>
+<s f="snmp_set_quick_print" u="void snmp_set_quick_print(int quick_print)">Return all objects including their respective object id withing the specified one</s>
+<s f="snmp_set_valueretrieval" u="int snmp_set_valueretrieval(int method)">Specify the method how the SNMP values will be returned</s>
+<s f="snmpget" u="string snmpget(string host, string community, string object_id [, int timeout [, int retries]])">Fetch a SNMP object</s>
+<s f="snmpgetnext" u="string snmpgetnext(string host, string community, string object_id [, int timeout [, int retries]])">Fetch a SNMP object</s>
+<s f="snmprealwalk" u="array snmprealwalk(string host, string community, string object_id [, int timeout [, int retries]])">Return all objects including their respective object id withing the specified one</s>
+<s f="snmpset" u="int snmpset(string host, string community, string object_id, string type, mixed value [, int timeout [, int retries]])">Set the value of a SNMP object</s>
+<s f="snmpwalk" u="array snmpwalk(string host, string community, string object_id [, int timeout [, int retries]])">Return all objects under the specified object id</s>
+<s f="SoapClient::__doRequest" u="string SoapClient::__doRequest()">SoapClient::__doRequest()</s>
+<s f="SoapClient::__getCookies" u="array SoapClient::__getCookies()">Returns array of cookies.</s>
+<s f="SoapClient::__getLastRequestHeaders" u="string SoapClient::__getLastRequestHeaders(void)">Returns last SOAP request headers</s>
+<s f="SoapClient::__getLastResponseHeaders" u="string SoapClient::__getLastResponseHeaders(void)">Returns last SOAP response headers</s>
+<s f="SoapClient::__setCookie" u="void SoapClient::__setCookie(string name [, strung value])">Sets cookie thet will sent with SOAP request.    The call to this function will effect all folowing calls of SOAP methods.    If value is not specified cookie is removed.</s>
+<s f="SoapClient::__setLocation" u="string SoapClient::__setLocation([string new_location])">Sets the location option (the endpoint URL that will be touched by the    following SOAP requests).    If new_location is not specified or null then SoapClient will use endpoint    from WSDL file.    The function returns old value of location options.</s>
+<s f="SoapClient::__setSoapHeaders" u="void SoapClient::__setSoapHeaders(array SoapHeaders)">Sets SOAP headers for subsequent calls (replaces any previous    values).    If no value is specified, all of the headers are removed.</s>
+<s f="SoapServer::addFunction" u="void SoapServer::addFunction(mixed functions)">Adds one or several functions those will handle SOAP requests</s>
+<s f="SoapServer::getFunctions" u="array SoapServer::getFunctions(void)">Returns list of defined functions</s>
+<s f="SoapServer::setClass" u="void SoapServer::setClass(string class_name [, mixed args])">Sets class which will handle SOAP requests</s>
+<s f="SoapServer::setObject" u="void SoapServer::setObject(object)">Sets object which will handle SOAP requests</s>
+<s f="socket_accept" u="resource socket_accept(resource socket)">Accepts a connection on the listening socket fd</s>
+<s f="socket_bind" u="bool socket_bind(resource socket, string addr [, int port])">Binds an open socket to a listening port, port is only specified in AF_INET family.</s>
+<s f="socket_clear_error" u="void socket_clear_error([resource socket])">Clears the error on the socket or the last error code.</s>
+<s f="socket_close" u="void socket_close(resource socket)">Closes a file descriptor</s>
+<s f="socket_connect" u="bool socket_connect(resource socket, string addr [, int port])">Opens a connection to addr:port on the socket specified by socket</s>
+<s f="socket_create" u="resource socket_create(int domain, int type, int protocol)">Creates an endpoint for communication in the domain specified by domain, of type specified by type</s>
+<s f="socket_create_listen" u="resource socket_create_listen(int port[, int backlog])">Opens a socket on port to accept connections</s>
+<s f="socket_create_pair" u="bool socket_create_pair(int domain, int type, int protocol, array &amp;fd)">Creates a pair of indistinguishable sockets and stores them in fds.</s>
+<s f="socket_get_option" u="mixed socket_get_option(resource socket, int level, int optname)">Gets socket options for the socket</s>
+<s f="socket_getpeername" u="bool socket_getpeername(resource socket, string &amp;addr[, int &amp;port])">Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type.</s>
+<s f="socket_getsockname" u="bool socket_getsockname(resource socket, string &amp;addr[, int &amp;port])">Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type.</s>
+<s f="socket_last_error" u="int socket_last_error([resource socket])">Returns the last socket error (either the last used or the provided socket resource)</s>
+<s f="socket_listen" u="bool socket_listen(resource socket[, int backlog])">Sets the maximum number of connections allowed to be waited for on the socket specified by fd</s>
+<s f="socket_read" u="string socket_read(resource socket, int length [, int type])">Reads a maximum of length bytes from socket</s>
+<s f="socket_recv" u="int socket_recv(resource socket, string &amp;buf, int len, int flags)">Receives data from a connected socket</s>
+<s f="socket_recvfrom" u="int socket_recvfrom(resource socket, string &amp;buf, int len, int flags, string &amp;name [, int &amp;port])">Receives data from a socket, connected or not</s>
+<s f="socket_select" u="int socket_select(array &amp;read_fds, array &amp;write_fds, &amp;array except_fds, int tv_sec[, int tv_usec])">Runs the select() system call on the sets mentioned with a timeout specified by tv_sec and tv_usec</s>
+<s f="socket_send" u="int socket_send(resource socket, string buf, int len, int flags)">Sends data to a connected socket</s>
+<s f="socket_sendto" u="int socket_sendto(resource socket, string buf, int len, int flags, string addr [, int port])">Sends a message to a socket, whether it is connected or not</s>
+<s f="socket_set_block" u="bool socket_set_block(resource socket)">Sets blocking mode on a socket resource</s>
+<s f="socket_set_nonblock" u="bool socket_set_nonblock(resource socket)">Sets nonblocking mode on a socket resource</s>
+<s f="socket_set_option" u="bool socket_set_option(resource socket, int level, int optname, int|array optval)">Sets socket options for the socket</s>
+<s f="socket_shutdown" u="bool socket_shutdown(resource socket[, int how])">Shuts down a socket for receiving, sending, or both.</s>
+<s f="socket_strerror" u="string socket_strerror(int errno)">Returns a string describing an error</s>
+<s f="socket_write" u="int socket_write(resource socket, string buf[, int length])">Writes the buffer to the socket resource, length is optional</s>
+<s f="class_implements" u="array class_implements(mixed what [, bool autoload ])">Return all classes and interfaces implemented by SPL</s>
+<s f="class_parents" u="array class_parents(object instance)">Return an array containing the names of all parent classes</s>
+<s f="spl_autoload" u="void spl_autoload(string class_name [, string file_extensions])">Default implementation for __autoload()</s>
+<s f="spl_autoload_call" u="void spl_autoload_call(string class_name)">Try all registerd autoload function to load the requested class</s>
+<s f="spl_autoload_extensions" u="string spl_autoload_extensions([string file_extensions])">Register and return default file extensions for spl_autoload</s>
+<s f="spl_autoload_register" u="bool spl_autoload_register([mixed autoload_function = &quot;spl_autoload&quot; [, throw = true]])">Register given function as __autoload() implementation</s>
+<s f="spl_autoload_unregister" u="bool spl_autoload_unregister(mixed autoload_function)">Unregister given function as __autoload() implementation</s>
+<s f="spl_classes" u="array spl_classes()">Return an array containing the names of all clsses and interfaces defined in SPL</s>
+<s f="spl_object_hash" u="string spl_object_hash(object obj)">Return hash id for given object</s>
+<s f="ArrayIterator::next" u="void ArrayIterator::next()">Move to next entry</s>
+<s f="ArrayIterator::rewind" u="void ArrayIterator::rewind()">Rewind array back to the start</s>
+<s f="ArrayIterator::seek" u="void ArrayIterator::seek(int $position)">Seek to position.</s>
+<s f="ArrayIterator::valid" u="bool ArrayIterator::valid()">Check whether array contains more entries</s>
+<s f="ArrayObject::__construct" u="void ArrayObject::__construct(array|object ar = array() [, int flags = 0 [, string iterator_class = &quot;ArrayIterator&quot;]])">proto void ArrayIterator::__construct(array|object ar = array() [, int flags = 0]) U  Cronstructs a new array iterator from a path.</s>
+<s f="ArrayObject::append" u="void ArrayObject::append(mixed $newval)">proto void ArrayIterator::append(mixed $newval) U  Appends the value (cannot be called for objects).</s>
+<s f="ArrayObject::asort" u="int ArrayObject::asort()">proto int ArrayIterator::asort() U  Sort the entries by values.</s>
+<s f="ArrayObject::count" u="int ArrayObject::count()">proto int ArrayIterator::count() U  Return the number of elements in the Iterator.</s>
+<s f="ArrayObject::getFlags" u="int ArrayObject::getFlags()">Get flags</s>
+<s f="ArrayObject::getIterator" u="ArrayIterator ArrayObject::getIterator()">Create a new iterator from a ArrayObject instance</s>
+<s f="ArrayObject::getIteratorClass" u="string ArrayObject::getIteratorClass()">Get the class used in getIterator.</s>
+<s f="ArrayObject::ksort" u="int ArrayObject::ksort()">proto int ArrayIterator::ksort() U  Sort the entries by key.</s>
+<s f="ArrayObject::natcasesort" u="int ArrayObject::natcasesort()">proto int ArrayIterator::natcasesort() U  Sort the entries by key using case insensitive &quot;natural order&quot; algorithm.</s>
+<s f="ArrayObject::natsort" u="int ArrayObject::natsort()">proto int ArrayIterator::natsort() U  Sort the entries by values using &quot;natural order&quot; algorithm.</s>
+<s f="ArrayObject::offsetExists" u="bool ArrayObject::offsetExists(mixed $index)">proto bool ArrayIterator::offsetExists(mixed $index) U  Returns whether the requested $index exists.</s>
+<s f="ArrayObject::offsetGet" u="mixed ArrayObject::offsetGet(mixed $index)">proto mixed ArrayIterator::offsetGet(mixed $index) U  Returns the value at the specified $index.</s>
+<s f="ArrayObject::offsetSet" u="void ArrayObject::offsetSet(mixed $index, mixed $newval)">proto void ArrayIterator::offsetSet(mixed $index, mixed $newval) U  Sets the value at the specified $index to $newval.</s>
+<s f="ArrayObject::offsetUnset" u="void ArrayObject::offsetUnset(mixed $index)">proto void ArrayIterator::offsetUnset(mixed $index) U  Unsets the value at the specified $index.</s>
+<s f="ArrayObject::setFlags" u="void ArrayObject::setFlags(int flags)">Set flags</s>
+<s f="ArrayObject::setIteratorClass" u="void ArrayObject::setIteratorClass(string iterator_class)">Set the class used in getIterator.</s>
+<s f="ArrayObject::uasort" u="int ArrayObject::uasort(callback cmp_function)">proto int ArrayIterator::uasort(callback cmp_function) U  Sort the entries by values user defined function.</s>
+<s f="ArrayObject::uksort" u="int ArrayObject::uksort(callback cmp_function)">proto int ArrayIterator::uksort(callback cmp_function) U  Sort the entries by key using user defined function.</s>
+<s f="RecursiveArrayIterator::getChildren" u="object RecursiveArrayIterator::getChildren()">Create a sub iterator for the current element (same class as $this)</s>
+<s f="RecursiveArrayIterator::hasChildren" u="bool RecursiveArrayIterator::hasChildren()">Check whether current element has children (e.g. is an array)</s>
+<s f="DirectoryIterator::__construct" u="void DirectoryIterator::__construct(string $path, [int $flags = 0])">Cronstructs a new dir iterator from a path.</s>
+<s f="DirectoryIterator::count" u="string DirectoryIterator::count()">Return number of entries in directory, works only when USE_GLOB is in effect</s>
+<s f="DirectoryIterator::current" u="DirectoryIterator DirectoryIterator::current()">Return this (needed for Iterator interface)</s>
+<s f="DirectoryIterator::getBasename" u="string DirectoryIterator::getBasename([string $suffix])">Returns filename component of current dir entry</s>
+<s f="DirectoryIterator::getChildren" u="RecursiveDirectoryIterator DirectoryIterator::getChildren()">Returns an iterator for the current entry if it is a directory</s>
+<s f="DirectoryIterator::getFilename" u="string DirectoryIterator::getFilename()">Return filename of current dir entry</s>
+<s f="DirectoryIterator::isDot" u="bool DirectoryIterator::isDot()">Returns true if current entry is '.' or  '..'</s>
+<s f="DirectoryIterator::key" u="string DirectoryIterator::key()">Return current dir entry</s>
+<s f="DirectoryIterator::next" u="void DirectoryIterator::next()">Move to next entry</s>
+<s f="DirectoryIterator::rewind" u="void DirectoryIterator::rewind()">Rewind dir back to the start</s>
+<s f="DirectoryIterator::valid" u="string DirectoryIterator::valid()">Check whether dir contains more entries</s>
+<s f="RecursiveDirectoryIterator::__construct" u="void RecursiveDirectoryIterator::__construct(string path [, int flags])">Cronstructs a new dir iterator from a path.</s>
+<s f="RecursiveDirectoryIterator::current" u="string RecursiveDirectoryIterator::current()">Return getFilename(), getFileInfo() or $this depending on flags</s>
+<s f="RecursiveDirectoryIterator::getSubPath" u="void RecursiveDirectoryIterator::getSubPath()">Get sub path</s>
+<s f="RecursiveDirectoryIterator::getSubPathname" u="void RecursiveDirectoryIterator::getSubPathname()">Get sub path and file name</s>
+<s f="RecursiveDirectoryIterator::hasChildren" u="bool RecursiveDirectoryIterator::hasChildren([bool $allow_links = false])">Returns whether current entry is a directory and not '.' or '..'</s>
+<s f="RecursiveDirectoryIterator::key" u="string RecursiveDirectoryIterator::key()">Return getPathname() or getFilename() depending on flags</s>
+<s f="RecursiveDirectoryIterator::next" u="void RecursiveDirectoryIterator::next()">Move to next entry</s>
+<s f="RecursiveDirectoryIterator::rewind" u="void RecursiveDirectoryIterator::rewind()">Rewind dir back to the start</s>
+<s f="SplFileInfo::__construct" u="void SplFileInfo::__construct(string file_name)">Cronstructs a new SplFileInfo from a path.</s>
+<s f="SplFileInfo::getATime" u="int SplFileInfo::getATime()">Get last access time of file</s>
+<s f="SplFileInfo::getBasename" u="string SplFileInfo::getBasename([string $suffix])">Returns filename component of path</s>
+<s f="SplFileInfo::getCTime" u="int SplFileInfo::getCTime()">Get inode modification time of file</s>
+<s f="SplFileInfo::getFileInfo" u="SplFileInfo SplFileInfo::getFileInfo([string $class_name])">Get/copy file info</s>
+<s f="SplFileInfo::getFilename" u="string SplFileInfo::getFilename()">Return filename only</s>
+<s f="SplFileInfo::getGroup" u="int SplFileInfo::getGroup()">Get file group</s>
+<s f="SplFileInfo::getInode" u="int SplFileInfo::getInode()">Get file inode</s>
+<s f="SplFileInfo::getLinkTarget" u="string SplFileInfo::getLinkTarget()">Return the target of a symbolic link</s>
+<s f="SplFileInfo::getMTime" u="int SplFileInfo::getMTime()">Get last modification time of file</s>
+<s f="SplFileInfo::getOwner" u="int SplFileInfo::getOwner()">Get file owner</s>
+<s f="SplFileInfo::getPath" u="string SplFileInfo::getPath()">Return the path</s>
+<s f="SplFileInfo::getPathInfo" u="SplFileInfo SplFileInfo::getPathInfo([string $class_name])">Get/copy file info</s>
+<s f="SplFileInfo::getPathname" u="string SplFileInfo::getPathname()">Return path and filename</s>
+<s f="SplFileInfo::getPerms" u="int SplFileInfo::getPerms()">Get file permissions</s>
+<s f="SplFileInfo::getRealPath" u="string SplFileInfo::getRealPath()">Return the resolved path</s>
+<s f="SplFileInfo::getSize" u="int SplFileInfo::getSize()">Get file size</s>
+<s f="SplFileInfo::getType" u="string SplFileInfo::getType()">Get file type</s>
+<s f="SplFileInfo::isDir" u="bool SplFileInfo::isDir()">Returns true if file is directory</s>
+<s f="SplFileInfo::isExecutable" u="bool SplFileInfo::isExecutable()">Returns true if file is executable</s>
+<s f="SplFileInfo::isFile" u="bool SplFileInfo::isFile()">Returns true if file is a regular file</s>
+<s f="SplFileInfo::isLink" u="bool SplFileInfo::isLink()">Returns true if file is symbolic link</s>
+<s f="SplFileInfo::isReadable" u="bool SplFileInfo::isReadable()">Returns true if file can be read</s>
+<s f="SplFileInfo::isWritable" u="bool SplFileInfo::isWritable()">Returns true if file can be written</s>
+<s f="SplFileInfo::openFile" u="SplFileObject SplFileInfo::openFile([string mode = 'r' [, bool use_include_path  [, resource context]]])">Open the current file</s>
+<s f="SplFileInfo::setFileClass" u="void SplFileInfo::setFileClass([string class_name])">Class to use in openFile()</s>
+<s f="SplFileInfo::setInfoClass" u="void SplFileInfo::setInfoClass([string class_name])">Class to use in getFileInfo(), getPathInfo()</s>
+<s f="SplFileObject::__construct" u="void SplFileObject::__construct(string filename [, string mode = 'r' [, bool use_include_path  [, resource context]]]])">Construct a new file object</s>
+<s f="SplFileObject::current" u="string SplFileObject::current()">Return current line from file</s>
+<s f="SplFileObject::eof" u="void SplFileObject::eof()">Return whether end of file is reached</s>
+<s f="SplFileObject::fflush" u="bool SplFileObject::fflush()">Flush the file</s>
+<s f="SplFileObject::fgetc" u="int SplFileObject::fgetc()">Get a character form the file</s>
+<s f="SplFileObject::fgetcsv" u="array SplFileObject::fgetcsv([string delimiter [, string enclosure]])">Return current line as csv</s>
+<s f="SplFileObject::fgets" u="string SplFileObject::fgets()">Rturn next line from file</s>
+<s f="SplFileObject::fgetss" u="string SplFileObject::fgetss([string allowable_tags])">Get a line from file pointer and strip HTML tags</s>
+<s f="SplFileObject::flock" u="bool SplFileObject::flock(int operation [, int &amp;wouldblock])">Portable file locking</s>
+<s f="SplFileObject::fpassthru" u="int SplFileObject::fpassthru()">Output all remaining data from a file pointer</s>
+<s f="SplFileObject::fscanf" u="bool SplFileObject::fscanf(string format [, string ...])">Implements a mostly ANSI compatible fscanf()</s>
+<s f="SplFileObject::fseek" u="int SplFileObject::fseek(int pos [, int whence = SEEK_SET])">Return current file position</s>
+<s f="SplFileObject::fstat" u="bool SplFileObject::fstat()">Stat() on a filehandle</s>
+<s f="SplFileObject::ftell" u="int SplFileObject::ftell()">Return current file position</s>
+<s f="SplFileObject::ftruncate" u="bool SplFileObject::ftruncate(int size)">Truncate file to 'size' length</s>
+<s f="SplFileObject::fwrite" u="mixed SplFileObject::fwrite(string str [, int length])">Binary-safe file write</s>
+<s f="SplFileObject::getChildren" u="bool SplFileObject::getChildren()">Read NULL</s>
+<s f="SplFileObject::getCsvControl" u="array SplFileObject::getCsvControl()">Get the delimiter and enclosure character used in fgetcsv</s>
+<s f="SplFileObject::getFlags" u="int SplFileObject::getFlags()">Get file handling flags</s>
+<s f="SplFileObject::getMaxLineLen" u="int SplFileObject::getMaxLineLen()">Get maximum line length</s>
+<s f="SplFileObject::hasChildren" u="bool SplFileObject::hasChildren()">Return false</s>
+<s f="SplFileObject::key" u="int SplFileObject::key()">Return line number</s>
+<s f="SplFileObject::next" u="void SplFileObject::next()">Read next line</s>
+<s f="SplFileObject::rewind" u="void SplFileObject::rewind()">Rewind the file and read the first line</s>
+<s f="SplFileObject::seek" u="void SplFileObject::seek(int line_pos)">Seek to specified line</s>
+<s f="SplFileObject::setCsvControl" u="void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '&quot;']])">Set the delimiter and enclosure character used in fgetcsv</s>
+<s f="SplFileObject::setFlags" u="void SplFileObject::setFlags(int flags)">Set file handling flags</s>
+<s f="SplFileObject::setMaxLineLen" u="void SplFileObject::setMaxLineLen(int max_len)">Set maximum line length</s>
+<s f="SplFileObject::valid" u="void SplFileObject::valid()">Return !eof()</s>
+<s f="SplTempFileObject::__construct" u="void SplTempFileObject::__construct([int max_memory])">Construct a new temp file object</s>
+<s f="AppendIterator::__construct" u="void AppendIterator::__construct()">Create an AppendIterator</s>
+<s f="AppendIterator::append" u="void AppendIterator::append(Iterator it)">Append an iterator</s>
+<s f="AppendIterator::getArrayIterator" u="ArrayIterator AppendIterator::getArrayIterator()">Get access to inner ArrayIterator</s>
+<s f="AppendIterator::getIteratorIndex" u="int AppendIterator::getIteratorIndex()">Get index of iterator</s>
+<s f="AppendIterator::next" u="void AppendIterator::next()">Forward to next element</s>
+<s f="AppendIterator::rewind" u="void AppendIterator::rewind()">Rewind to the first iterator and rewind the first iterator, too</s>
+<s f="AppendIterator::valid" u="bool AppendIterator::valid()">Check if the current state is valid</s>
+<s f="CachingIterator::__construct" u="void CachingIterator::__construct(Iterator it [, flags = CIT_CALL_TOSTRING])">Construct a CachingIterator from an Iterator</s>
+<s f="CachingIterator::__toString" u="string CachingIterator::__toString()">Return the string representation of the current element</s>
+<s f="CachingIterator::count" u="void CachingIterator::count()">Number of cached elements</s>
+<s f="CachingIterator::getCache" u="bool CachingIterator::getCache()">Return the cache</s>
+<s f="CachingIterator::getFlags" u="int CachingIterator::getFlags()">Return the internal flags</s>
+<s f="CachingIterator::hasNext" u="bool CachingIterator::hasNext()">Check whether the inner iterator has a valid next element</s>
+<s f="CachingIterator::next" u="void CachingIterator::next()">Move the iterator forward</s>
+<s f="CachingIterator::offsetExists" u="bool CachingIterator::offsetExists(mixed index)">Return whether the requested index exists</s>
+<s f="CachingIterator::offsetGet" u="string CachingIterator::offsetGet(mixed index)">Return the internal cache if used</s>
+<s f="CachingIterator::offsetSet" u="void CachingIterator::offsetSet(mixed index, mixed newval)">Set given index in cache</s>
+<s f="CachingIterator::offsetUnset" u="void CachingIterator::offsetUnset(mixed index)">Unset given index in cache</s>
+<s f="CachingIterator::rewind" u="void CachingIterator::rewind()">Rewind the iterator</s>
+<s f="CachingIterator::setFlags" u="void CachingIterator::setFlags(int flags)">Set the internal flags</s>
+<s f="CachingIterator::valid" u="bool CachingIterator::valid()">Check whether the current element is valid</s>
+<s f="EmptyIterator::current" u="void EmptyIterator::current()">Throws exception BadMethodCallException</s>
+<s f="EmptyIterator::key" u="void EmptyIterator::key()">Throws exception BadMethodCallException</s>
+<s f="EmptyIterator::next" u="void EmptyIterator::next()">Does nothing</s>
+<s f="EmptyIterator::rewind" u="void EmptyIterator::rewind()">Does nothing</s>
+<s f="EmptyIterator::valid" u="false EmptyIterator::valid()">Return false</s>
+<s f="FilterIterator::__construct" u="void FilterIterator::__construct(Iterator it)">Create an Iterator from another iterator</s>
+<s f="FilterIterator::current" u="mixed FilterIterator::current()">proto mixed CachingIterator::current() U        proto mixed LimitIterator::current() U        proto mixed ParentIterator::current() U        proto mixed IteratorIterator::current() U        proto mixed NoRewindIterator::current() U        proto mixed AppendIterator::current() U    Get the current element value</s>
+<s f="FilterIterator::getInnerIterator" u="Iterator FilterIterator::getInnerIterator()">proto Iterator CachingIterator::getInnerIterator() U        proto Iterator LimitIterator::getInnerIterator() U        proto Iterator ParentIterator::getInnerIterator() U    Get the inner iterator</s>
+<s f="FilterIterator::key" u="mixed FilterIterator::key()">proto mixed CachingIterator::key() U        proto mixed LimitIterator::key() U        proto mixed ParentIterator::key() U        proto mixed IteratorIterator::key() U        proto mixed NoRewindIterator::key() U        proto mixed AppendIterator::key() U    Get the current key</s>
+<s f="FilterIterator::next" u="void FilterIterator::next()">Move the iterator forward</s>
+<s f="FilterIterator::rewind" u="void FilterIterator::rewind()">Rewind the iterator</s>
+<s f="FilterIterator::valid" u="bool FilterIterator::valid()">proto bool ParentIterator::valid() U        proto bool IteratorIterator::valid() U        proto bool NoRewindIterator::valid() U    Check whether the current element is valid</s>
+<s f="InfiniteIterator::__construct" u="void InfiniteIterator::__construct(Iterator it)">Create an iterator from another iterator</s>
+<s f="InfiniteIterator::next" u="void InfiniteIterator::next()">Prevent a call to inner iterators rewind() (internally the current data will be fetched if valid())</s>
+<s f="IteratorIterator::__construct" u="void IteratorIterator::__construct(Traversable it)">Create an iterator from anything that is traversable</s>
+<s f="LimitIterator::getPosition" u="int LimitIterator::getPosition()">Return the current position</s>
+<s f="LimitIterator::next" u="void LimitIterator::next()">Move the iterator forward</s>
+<s f="LimitIterator::rewind" u="void LimitIterator::rewind()">Rewind the iterator to the specified starting offset</s>
+<s f="LimitIterator::seek" u="void LimitIterator::seek(int position)">Seek to the given position</s>
+<s f="LimitIterator::valid" u="bool LimitIterator::valid()">Check whether the current element is valid</s>
+<s f="NoRewindIterator::__construct" u="void NoRewindIterator::__construct(Iterator it)">Create an iterator from another iterator</s>
+<s f="NoRewindIterator::current" u="mixed NoRewindIterator::current()">Return inner iterators current()</s>
+<s f="NoRewindIterator::key" u="mixed NoRewindIterator::key()">Return inner iterators key()</s>
+<s f="NoRewindIterator::next" u="void NoRewindIterator::next()">Return inner iterators next()</s>
+<s f="NoRewindIterator::rewind" u="void NoRewindIterator::rewind()">Prevent a call to inner iterators rewind()</s>
+<s f="NoRewindIterator::valid" u="bool NoRewindIterator::valid()">Return inner iterators valid()</s>
+<s f="ParentIterator::__construct" u="void ParentIterator::__construct(RecursiveIterator it)">Create a ParentIterator from a RecursiveIterator</s>
+<s f="ParentIterator::next" u="void ParentIterator::next()">proto void IteratorIterator::next() U        proto void NoRewindIterator::next() U    Move the iterator forward</s>
+<s f="ParentIterator::rewind" u="void ParentIterator::rewind()">proto void IteratorIterator::rewind()    Rewind the iterator</s>
+<s f="RecursiveCachingIterator::__construct" u="void RecursiveCachingIterator::__construct(RecursiveIterator it [, flags = CIT_CALL_TOSTRING])">Create an iterator from a RecursiveIterator</s>
+<s f="RecursiveCachingIterator::getChildren" u="RecursiveCachingIterator RecursiveCachingIterator::getChildren()">Return the inner iterator's children as a RecursiveCachingIterator</s>
+<s f="RecursiveCachingIterator::hasChildren" u="bool RecursiveCachingIterator::hasChildren()">Check whether the current element of the inner iterator has children</s>
+<s f="RecursiveFilterIterator::__construct" u="void RecursiveFilterIterator::__construct(RecursiveIterator it)">Create a RecursiveFilterIterator from a RecursiveIterator</s>
+<s f="RecursiveFilterIterator::getChildren" u="RecursiveFilterIterator RecursiveFilterIterator::getChildren()">Return the inner iterator's children contained in a RecursiveFilterIterator</s>
+<s f="RecursiveFilterIterator::hasChildren" u="bool RecursiveFilterIterator::hasChildren()">Check whether the inner iterator's current element has children</s>
+<s f="RecursiveIteratorIterator::beginChildren" u="void RecursiveIteratorIterator::beginChildren()">Called when recursing one level down</s>
+<s f="RecursiveIteratorIterator::beginIteration" u="RecursiveIterator RecursiveIteratorIterator::beginIteration()">Called when iteration begins (after first rewind() call)</s>
+<s f="RecursiveIteratorIterator::callGetChildren" u="RecursiveIterator RecursiveIteratorIterator::callGetChildren()">Return children of current element</s>
+<s f="RecursiveIteratorIterator::callHasChildren" u="bool RecursiveIteratorIterator::callHasChildren()">Called for each element to test whether it has children</s>
+<s f="RecursiveIteratorIterator::current" u="mixed RecursiveIteratorIterator::current()">Access the current element value</s>
+<s f="RecursiveIteratorIterator::endChildren" u="void RecursiveIteratorIterator::endChildren()">Called when end recursing one level</s>
+<s f="RecursiveIteratorIterator::endIteration" u="RecursiveIterator RecursiveIteratorIterator::endIteration()">Called when iteration ends (when valid() first returns false</s>
+<s f="RecursiveIteratorIterator::getDepth" u="int RecursiveIteratorIterator::getDepth()">Get the current depth of the recursive iteration</s>
+<s f="RecursiveIteratorIterator::getInnerIterator" u="RecursiveIterator RecursiveIteratorIterator::getInnerIterator()">The current active sub iterator</s>
+<s f="RecursiveIteratorIterator::getSubIterator" u="RecursiveIterator RecursiveIteratorIterator::getSubIterator([int level])">The current active sub iterator or the iterator at specified level</s>
+<s f="RecursiveIteratorIterator::key" u="mixed RecursiveIteratorIterator::key()">Access the current key</s>
+<s f="RecursiveIteratorIterator::next" u="void RecursiveIteratorIterator::next()">Move forward to the next element</s>
+<s f="RecursiveIteratorIterator::nextElement" u="void RecursiveIteratorIterator::nextElement()">Called when the next element is available</s>
+<s f="RecursiveIteratorIterator::rewind" u="void RecursiveIteratorIterator::rewind()">Rewind the iterator to the first element of the top level inner iterator.</s>
+<s f="RecursiveIteratorIterator::setMaxDepth" u="void RecursiveIteratorIterator::setMaxDepth([$max_depth = -1])">Set the maximum allowed depth (or any depth if pmax_depth = -1]</s>
+<s f="RecursiveIteratorIterator::valid" u="bool RecursiveIteratorIterator::valid()">Check whether the current position is valid</s>
+<s f="RecursiveRegexIterator::__construct" u="void RecursiveRegexIterator::__construct(RecursiveIterator it, string regex [, int mode [, int flags [, int preg_flags]]])">Create an RecursiveRegexIterator from another recursive iterator and a regular expression</s>
+<s f="RecursiveRegexIterator::getChildren" u="RecursiveRegexIterator RecursiveRegexIterator::getChildren()">Return the inner iterator's children contained in a RecursiveRegexIterator</s>
+<s f="RegexIterator::__construct" u="void RegexIterator::__construct(Iterator it, string regex [, int mode [, int flags [, int preg_flags]]])">Create an RegexIterator from another iterator and a regular expression</s>
+<s f="RegexIterator::accept" u="bool RegexIterator::accept()">Match (string)current() against regular expression</s>
+<s f="RegexIterator::getFlags" u="bool RegexIterator::getFlags()">Returns current PREG flags (if in use or NULL)</s>
+<s f="RegexIterator::getFlags" u="bool RegexIterator::getFlags()">Returns current operation flags</s>
+<s f="RegexIterator::getMode" u="bool RegexIterator::getMode()">Returns current operation mode</s>
+<s f="RegexIterator::setFlags" u="bool RegexIterator::setFlags(int new_flags)">Set operation flags</s>
+<s f="RegexIterator::setMode" u="bool RegexIterator::setMode(int new_mode)">Set new operation mode</s>
+<s f="RegexIterator::setPregFlags" u="bool RegexIterator::setPregFlags(int new_flags)">Set PREG flags</s>
+<s f="LimitIterator::__construct" u=" LimitIterator::__construct(Iterator it [, int offset, int count])">Construct a LimitIterator from an Iterator with a given starting offset and optionally a maximum count</s>
+<s f="iterator_apply" u="int iterator_apply(Traversable it, mixed function [, mixed params])">Calls a function for every element in an iterator</s>
+<s f="iterator_count" u="int iterator_count(Traversable it)">Count the elements in an iterator</s>
+<s f="iterator_to_array" u="array iterator_to_array(Traversable it [, bool use_keys = true])">Copy the iterator into an array</s>
+<s f="SplObjectStorage::attach" u="void SplObjectStorage::attach($obj)">Attaches an object to the storage if not yet contained</s>
+<s f="SplObjectStorage::contains" u="bool SplObjectStorage::contains($obj)">Determine whethe an object is contained in the storage</s>
+<s f="SplObjectStorage::count" u="int SplObjectStorage::count()">Determine number of objects in storage</s>
+<s f="SplObjectStorage::current" u="mixed SplObjectStorage::current()"></s>
+<s f="SplObjectStorage::detach" u="void SplObjectStorage::detach($obj)">Detaches an object from the storage</s>
+<s f="SplObjectStorage::key" u="mixed SplObjectStorage::key()"></s>
+<s f="SplObjectStorage::next" u="void SplObjectStorage::next()"></s>
+<s f="SplObjectStorage::rewind" u="void SplObjectStorage::rewind()"></s>
+<s f="SplObjectStorage::serialize" u="string SplObjectStorage::serialize()"></s>
+<s f="SplObjectStorage::unserialize" u="void SplObjectStorage::unserialize(string serialized)"></s>
+<s f="SplObjectStorage::valid" u="bool SplObjectStorage::valid()"></s>
+<s f="SimpleXMLIterator::count" u="int SimpleXMLIterator::count()">Get number of child elements</s>
+<s f="SimpleXMLIterator::current" u="SimpleXMLIterator SimpleXMLIterator::current()">Get current element</s>
+<s f="SimpleXMLIterator::getChildren" u="SimpleXMLIterator SimpleXMLIterator::getChildren()">Get child element iterator</s>
+<s f="SimpleXMLIterator::hasChildren" u="bool SimpleXMLIterator::hasChildren()">Check whether element has children (elements)</s>
+<s f="SimpleXMLIterator::key" u="string SimpleXMLIterator::key()">Get name of current child element</s>
+<s f="SimpleXMLIterator::next" u="void SimpleXMLIterator::next()">Move to next element</s>
+<s f="SimpleXMLIterator::rewind" u="void SimpleXMLIterator::rewind()">Rewind to first element</s>
+<s f="SimpleXMLIterator::valid" u="bool SimpleXMLIterator::valid()">Check whether iteration is valid</s>
+<s f="sqlite_array_query" u="array sqlite_array_query(resource db, string query [ , int result_type [, bool decode_binary]])">Executes a query against a given database and returns an array of arrays.</s>
+<s f="sqlite_busy_timeout" u="void sqlite_busy_timeout(resource db, int ms)">Set busy timeout duration. If ms &lt;= 0, all busy handlers are disabled.</s>
+<s f="sqlite_changes" u="int sqlite_changes(resource db)">Returns the number of rows that were changed by the most recent SQL statement.</s>
+<s f="sqlite_close" u="void sqlite_close(resource db)">Closes an open sqlite database.</s>
+<s f="sqlite_column" u="mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])">Fetches a column from the current row of a result set.</s>
+<s f="sqlite_create_aggregate" u="bool sqlite_create_aggregate(resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args])">Registers an aggregate function for queries.</s>
+<s f="sqlite_create_function" u="bool sqlite_create_function(resource db, string funcname, mixed callback[, long num_args])">Registers a &quot;regular&quot; function for queries.</s>
+<s f="sqlite_current" u="array sqlite_current(resource result [, int result_type [, bool decode_binary]])">Fetches the current row from a result set as an array.</s>
+<s f="sqlite_error_string" u="string sqlite_error_string(int error_code)">Returns the textual description of an error code.</s>
+<s f="sqlite_escape_string" u="string sqlite_escape_string(string item)">Escapes a string for use as a query parameter.</s>
+<s f="sqlite_exec" u="boolean sqlite_exec(string query, resource db[, string &amp;error_message])">Executes a result-less query against a given database</s>
+<s f="sqlite_factory" u="object sqlite_factory(string filename [, int mode [, string &amp;error_message]])">Opens a SQLite database and creates an object for it. Will create the database if it does not exist.</s>
+<s f="sqlite_fetch_all" u="array sqlite_fetch_all(resource result [, int result_type [, bool decode_binary]])">Fetches all rows from a result set as an array of arrays.</s>
+<s f="sqlite_fetch_array" u="array sqlite_fetch_array(resource result [, int result_type [, bool decode_binary]])">Fetches the next row from a result set as an array.</s>
+<s f="sqlite_fetch_column_types" u="resource sqlite_fetch_column_types(string table_name, resource db [, int result_type])">Return an array of column types from a particular table.</s>
+<s f="sqlite_fetch_object" u="object sqlite_fetch_object(resource result [, string class_name [, NULL|array ctor_params [, bool decode_binary]]])">Fetches the next row from a result set as an object.</s>
+<s f="sqlite_fetch_single" u="string sqlite_fetch_single(resource result [, bool decode_binary])">Fetches the first column of a result set as a string.</s>
+<s f="sqlite_field_name" u="string sqlite_field_name(resource result, int field_index)">Returns the name of a particular field of a result set.</s>
+<s f="sqlite_has_prev" u="bool sqlite_has_prev(resource result)">* Returns whether a previous row is available.</s>
+<s f="sqlite_key" u="int sqlite_key(resource result)">Return the current row index of a buffered result.</s>
+<s f="sqlite_last_error" u="int sqlite_last_error(resource db)">Returns the error code of the last error for a database.</s>
+<s f="sqlite_last_insert_rowid" u="int sqlite_last_insert_rowid(resource db)">Returns the rowid of the most recently inserted row.</s>
+<s f="sqlite_libencoding" u="string sqlite_libencoding()">Returns the encoding (iso8859 or UTF-8) of the linked SQLite library.</s>
+<s f="sqlite_libversion" u="string sqlite_libversion()">Returns the version of the linked SQLite library.</s>
+<s f="sqlite_next" u="bool sqlite_next(resource result)">Seek to the next row number of a result set.</s>
+<s f="sqlite_num_fields" u="int sqlite_num_fields(resource result)">Returns the number of fields in a result set.</s>
+<s f="sqlite_num_rows" u="int sqlite_num_rows(resource result)">Returns the number of rows in a buffered result set.</s>
+<s f="sqlite_open" u="resource sqlite_open(string filename [, int mode [, string &amp;error_message]])">Opens a SQLite database. Will create the database if it does not exist.</s>
+<s f="sqlite_popen" u="resource sqlite_popen(string filename [, int mode [, string &amp;error_message]])">Opens a persistent handle to a SQLite database. Will create the database if it does not exist.</s>
+<s f="sqlite_prev" u="bool sqlite_prev(resource result)">* Seek to the previous row number of a result set.</s>
+<s f="sqlite_query" u="resource sqlite_query(string query, resource db [, int result_type [, string &amp;error_message]])">Executes a query against a given database and returns a result handle.</s>
+<s f="sqlite_rewind" u="bool sqlite_rewind(resource result)">Seek to the first row number of a buffered result set.</s>
+<s f="sqlite_seek" u="bool sqlite_seek(resource result, int row)">Seek to a particular row number of a buffered result set.</s>
+<s f="sqlite_single_query" u="array sqlite_single_query(resource db, string query [, bool first_row_only [, bool decode_binary]])">Executes a query and returns either an array for one single column or the value of the first row.</s>
+<s f="sqlite_udf_decode_binary" u="string sqlite_udf_decode_binary(string data)">Decode binary encoding on a string parameter passed to an UDF.</s>
+<s f="sqlite_udf_encode_binary" u="string sqlite_udf_encode_binary(string data)">Apply binary encoding (if required) to a string to return from an UDF.</s>
+<s f="sqlite_unbuffered_query" u="resource sqlite_unbuffered_query(string query, resource db [ , int result_type [, string &amp;error_message]])">Executes a query that does not prefetch and buffer all data.</s>
+<s f="sqlite_valid" u="bool sqlite_valid(resource result)">Returns whether more rows are available.</s>
+<s f="array_change_key_case" u="array array_change_key_case(array input [, int case=CASE_LOWER])">Retuns an array with all string keys lowercased [or uppercased]</s>
+<s f="array_chunk" u="array array_chunk(array input, int size [, bool preserve_keys])">Split array into chunks</s>
+<s f="array_combine" u="array array_combine(array keys, array values)">Creates an array by using the elements of the first parameter as keys and the elements of the second as the corresponding values</s>
+<s f="array_count_values" u="array array_count_values(array input)">Return the value as key and the frequency of that value in input as value</s>
+<s f="array_diff" u="array array_diff(array arr1, array arr2 [, array ...])">Returns the entries of arr1 that have values which are not present in any of the others arguments.</s>
+<s f="array_diff_assoc" u="array array_diff_assoc(array arr1, array arr2 [, array ...])">Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal</s>
+<s f="array_diff_key" u="array array_diff_key(array arr1, array arr2 [, array ...])">Returns the entries of arr1 that have keys which are not present in any of the others arguments. This function is like array_diff() but works on the keys instead of the values. The associativity is preserved.</s>
+<s f="array_diff_uassoc" u="array array_diff_uassoc(array arr1, array arr2 [, array ...], callback key_comp_func)">Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal. Elements are compared by user supplied function.</s>
+<s f="array_diff_ukey" u="array array_diff_ukey(array arr1, array arr2 [, array ...], callback key_comp_func)">Returns the entries of arr1 that have keys which are not present in any of the others arguments. User supplied function is used for comparing the keys. This function is like array_udiff() but works on the keys instead of the values. The associativity is preserved.</s>
+<s f="array_fill" u="array array_fill(int start_key, int num, mixed val)">Create an array containing num elements starting with index start_key each initialized to val</s>
+<s f="array_fill_keys" u="array array_fill_keys(array keys, mixed val)">Create an array using the elements of the first parameter as keys each initialized to val</s>
+<s f="array_filter" u="array array_filter(array input [, mixed callback])">Filters elements from the array via the callback.</s>
+<s f="array_flip" u="array array_flip(array input)">Return array with key &lt;-&gt; value flipped</s>
+<s f="array_intersect" u="array array_intersect(array arr1, array arr2 [, array ...])">Returns the entries of arr1 that have values which are present in all the other arguments</s>
+<s f="array_intersect_assoc" u="array array_intersect_assoc(array arr1, array arr2 [, array ...])">Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check</s>
+<s f="array_intersect_key" u="array array_intersect_key(array arr1, array arr2 [, array ...])">Returns the entries of arr1 that have keys which are present in all the other arguments. Kind of equivalent to array_diff(array_keys($arr1), array_keys($arr2)[,array_keys(...)]). Equivalent of array_intersect_assoc() but does not do compare of the data.</s>
+<s f="array_intersect_uassoc" u="array array_intersect_uassoc(array arr1, array arr2 [, array ...], callback key_compare_func)">Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check and they are compared by using an user-supplied callback.</s>
+<s f="array_intersect_ukey" u="array array_intersect_ukey(array arr1, array arr2 [, array ...], callback key_compare_func)">Returns the entries of arr1 that have keys which are present in all the other arguments. Kind of equivalent to array_diff(array_keys($arr1), array_keys($arr2)[,array_keys(...)]). The comparison of the keys is performed by a user supplied function. Equivalent of array_intersect_uassoc() but does not do compare of the data.</s>
+<s f="array_key_exists" u="bool array_key_exists(mixed key, array search)">Checks if the given key or index exists in the array</s>
+<s f="array_keys" u="array array_keys(array input [, mixed search_value[, bool strict]])">Return just the keys from the input array, optionally only for the specified search_value</s>
+<s f="array_map" u="array array_map(mixed callback, array input1 [, array input2 ,...])">Applies the callback to the elements in given arrays.</s>
+<s f="array_merge" u="array array_merge(array arr1, array arr2 [, array ...])">Merges elements from passed arrays into one array</s>
+<s f="array_merge_recursive" u="array array_merge_recursive(array arr1, array arr2 [, array ...])">Recursively merges elements from passed arrays into one array</s>
+<s f="array_multisort" u="bool array_multisort(array ar1 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING]] [, array ar2 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING]], ...])">Sort multiple arrays at once similar to how ORDER BY clause works in SQL</s>
+<s f="array_pad" u="array array_pad(array input, int pad_size, mixed pad_value)">Returns a copy of input array padded with pad_value to size pad_size</s>
+<s f="array_pop" u="mixed array_pop(array stack)">Pops an element off the end of the array</s>
+<s f="array_product" u="mixed array_product(array input)">Returns the product of the array entries</s>
+<s f="array_push" u="int array_push(array stack, mixed var [, mixed ...])">Pushes elements onto the end of the array</s>
+<s f="array_rand" u="mixed array_rand(array input [, int num_req])">Return key/keys for random entry/entries in the array</s>
+<s f="array_reduce" u="mixed array_reduce(array input, mixed callback [, int initial])">Iteratively reduce the array to a single value via the callback.</s>
+<s f="array_reverse" u="array array_reverse(array input [, bool preserve keys])">Return input as a new array with the order of the entries reversed</s>
+<s f="array_search" u="mixed array_search(mixed needle, array haystack [, bool strict])">Searches the array for a given value and returns the corresponding key if successful</s>
+<s f="array_shift" u="mixed array_shift(array stack)">Pops an element off the beginning of the array</s>
+<s f="array_slice" u="array array_slice(array input, int offset [, int length [, bool preserve_keys]])">Returns elements specified by offset and length</s>
+<s f="array_splice" u="array array_splice(array input, int offset [, int length [, array replacement]])">Removes the elements designated by offset and length and replace them with supplied array</s>
+<s f="array_sum" u="mixed array_sum(array input)">Returns the sum of the array entries</s>
+<s f="array_udiff" u="array array_udiff(array arr1, array arr2 [, array ...], callback data_comp_func)">Returns the entries of arr1 that have values which are not present in any of the others arguments. Elements are compared by user supplied function.</s>
+<s f="array_udiff_assoc" u="array array_udiff_assoc(array arr1, array arr2 [, array ...], callback data_comp_func)">Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal. Entries are compared by user supplied function.</s>
+<s f="array_udiff_uassoc" u="array array_udiff_uassoc(array arr1, array arr2 [, array ...], callback data_comp_func, callback key_comp_func)">Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal. Keys and elements are compared by user supplied functions.</s>
+<s f="array_uintersect" u="array array_uintersect(array arr1, array arr2 [, array ...], callback data_compare_func)">Returns the entries of arr1 that have values which are present in all the other arguments. Data is compared by using an user-supplied callback.</s>
+<s f="array_uintersect_assoc" u="array array_uintersect_assoc(array arr1, array arr2 [, array ...], callback data_compare_func)">Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check. Data is compared by using an user-supplied callback.</s>
+<s f="array_uintersect_uassoc" u="array array_uintersect_uassoc(array arr1, array arr2 [, array ...], callback data_compare_func, callback key_compare_func)">Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check. Both data and keys are compared by using user-supplied callbacks.</s>
+<s f="array_unique" u="array array_unique(array input)">Removes duplicate values from array</s>
+<s f="array_unshift" u="int array_unshift(array stack, mixed var [, mixed ...])">Pushes elements onto the beginning of the array</s>
+<s f="array_values" u="array array_values(array input)">Return just the values from the input array</s>
+<s f="array_walk" u="bool array_walk(array input, mixed callback [, mixed userdata])">Apply a user function to every member of an array</s>
+<s f="array_walk_recursive" u="bool array_walk_recursive(array input, mixed callback [, mixed userdata])">Apply a user function recursively to every member of an array</s>
+<s f="arsort" u="bool arsort(array &amp;array_arg [, int sort_flags])">Sort an array in reverse order and maintain index association</s>
+<s f="asort" u="bool asort(array &amp;array_arg [, int sort_flags])">Sort an array and maintain index association</s>
+<s f="compact" u="array compact(mixed var_names [, mixed ...])">Creates a hash containing variables and their values</s>
+<s f="count" u="int count(mixed var [, int mode])">Count the number of elements in a variable (usually an array)</s>
+<s f="current" u="mixed current(array array_arg)">Return the element currently pointed to by the internal array pointer</s>
+<s f="end" u="mixed end(array array_arg)">Advances array argument's internal pointer to the last element and return it</s>
+<s f="extract" u="int extract(array var_array [, int extract_type [, string prefix]])">Imports variables into symbol table from an array</s>
+<s f="in_array" u="bool in_array(mixed needle, array haystack [, bool strict])">Checks if the given value exists in the array</s>
+<s f="key" u="mixed key(array array_arg)">Return the key of the element currently pointed to by the internal array pointer</s>
+<s f="krsort" u="bool krsort(array &amp;array_arg [, int sort_flags])">Sort an array by key value in reverse order</s>
+<s f="ksort" u="bool ksort(array &amp;array_arg [, int sort_flags])">Sort an array by key</s>
+<s f="max" u="mixed max(mixed arg1 [, mixed arg2 [, mixed ...]])">Return the highest value in an array or a series of arguments</s>
+<s f="min" u="mixed min(mixed arg1 [, mixed arg2 [, mixed ...]])">Return the lowest value in an array or a series of arguments</s>
+<s f="natcasesort" u="void natcasesort(array &amp;array_arg)">Sort an array using case-insensitive natural sort</s>
+<s f="natsort" u="void natsort(array &amp;array_arg)">Sort an array using natural sort</s>
+<s f="next" u="mixed next(array array_arg)">Move array argument's internal pointer to the next element and return it</s>
+<s f="prev" u="mixed prev(array array_arg)">Move array argument's internal pointer to the previous element and return it</s>
+<s f="range" u="array range(mixed low, mixed high[, int step])">Create an array containing the range of integers or characters from low to high (inclusive)</s>
+<s f="reset" u="mixed reset(array array_arg)">Set array argument's internal pointer to the first element and return it</s>
+<s f="rsort" u="bool rsort(array &amp;array_arg [, int sort_flags])">Sort an array in reverse order</s>
+<s f="shuffle" u="bool shuffle(array array_arg)">Randomly shuffle the contents of an array</s>
+<s f="sort" u="bool sort(array &amp;array_arg [, int sort_flags])">Sort an array</s>
+<s f="uasort" u="bool uasort(array array_arg, mixed comparator)">Sort an array with a user-defined comparison function and maintain index association</s>
+<s f="uksort" u="bool uksort(array array_arg, mixed comparator)">Sort an array by keys using a user-defined comparison function</s>
+<s f="usort" u="bool usort(array array_arg, mixed comparator)">Sort an array by values using a user-defined comparison function</s>
+<s f="assert" u="int assert(string|bool assertion)">Checks if assertion is false</s>
+<s f="assert_options" u="mixed assert_options(int what [, mixed value])">Set/get the various assert flags</s>
+<s f="base64_decode" u="binary base64_decode(binary str[, bool strict])">Decodes string using MIME base64 algorithm</s>
+<s f="base64_encode" u="binary base64_encode(binary str)">Encodes string using MIME base64 algorithm</s>
+<s f="call_user_func" u="mixed call_user_func(mixed function_name [, mixed parmeter] [, mixed ...])">Call a user function which is the first parameter</s>
+<s f="call_user_func_array" u="mixed call_user_func_array(string function_name, array parameters)">Call a user function which is the first parameter with the arguments contained in array</s>
+<s f="call_user_method" u="mixed call_user_method(string method_name, mixed object [, mixed parameter] [, mixed ...])">Call a user method on a specific object or class</s>
+<s f="call_user_method_array" u="mixed call_user_method_array(string method_name, mixed object, array params)">Call a user method on a specific object or class using a parameter array</s>
+<s f="connection_aborted" u="int connection_aborted(void)">Returns true if client disconnected</s>
+<s f="connection_status" u="int connection_status(void)">Returns the connection status bitfield</s>
+<s f="constant" u="mixed constant(string const_name)">Given the name of a constant this function will return the constant's associated value</s>
+<s f="error_get_last" u="array error_get_last()">Get the last occurred error as associative array. Returns NULL if there hasn't been an error yet.</s>
+<s f="error_log" u="bool error_log(string message [, int message_type [, string destination [, string extra_headers]]])">Send an error message somewhere</s>
+<s f="flush" u="void flush(void)">Flush the output buffer</s>
+<s f="get_cfg_var" u="string get_cfg_var(string option_name)">Get the value of a PHP configuration option</s>
+<s f="get_current_user" u="string get_current_user(void)">Get the name of the owner of the current PHP script</s>
+<s f="get_include_path" u="string get_include_path()">Get the current include_path configuration option</s>
+<s f="getenv" u="string getenv(string varname)">Get the value of an environment variable</s>
+<s f="getopt" u="array getopt(string options [, array longopts])">Get options from the command line argument list</s>
+<s f="getprotobyname" u="int getprotobyname(string name)">Returns protocol number associated with name as per /etc/protocols</s>
+<s f="getprotobynumber" u="string getprotobynumber(int proto)">Returns protocol name associated with protocol number proto</s>
+<s f="getservbyname" u="int getservbyname(string service, string protocol)">Returns port associated with service. Protocol must be &quot;tcp&quot; or &quot;udp&quot;</s>
+<s f="getservbyport" u="string getservbyport(int port, string protocol)">Returns service name associated with port. Protocol must be &quot;tcp&quot; or &quot;udp&quot;</s>
+<s f="highlight_file" u="bool highlight_file(string file_name [, bool return] )">Syntax highlight a source file</s>
+<s f="highlight_string" u="bool highlight_string(string string [, bool return] )">Syntax highlight a string or optionally return it</s>
+<s f="ignore_user_abort" u="int ignore_user_abort([string value])">Set whether we want to ignore a user abort event or not</s>
+<s f="import_request_variables" u="bool import_request_variables(string types [, string prefix])">Import GET/POST/Cookie variables into the global scope</s>
+<s f="inet_ntop" u="string inet_ntop(string in_addr)">Converts a packed inet address to a human readable IP address string</s>
+<s f="inet_pton" u="string inet_pton(string ip_address)">Converts a human readable IP address to a packed binary string</s>
+<s f="ini_get" u="string ini_get(string varname)">Get a configuration option</s>
+<s f="ini_get_all" u="array ini_get_all([string extension])">Get all configuration options</s>
+<s f="ini_restore" u="void ini_restore(string varname)">Restore the value of a configuration option specified by varname</s>
+<s f="ini_set" u="string ini_set(string varname, string newvalue)">Set a configuration option, returns false on error and the old value of the configuration option on success</s>
+<s f="ip2long" u="int ip2long(string ip_address)">Converts a string containing an (IPv4) Internet Protocol dotted address into a proper address</s>
+<s f="is_uploaded_file" u="bool is_uploaded_file(string path)">Check if file was created by rfc1867 upload</s>
+<s f="long2ip" u="string long2ip(int proper_address)">Converts an (IPv4) Internet network address into a string in Internet standard dotted format</s>
+<s f="move_uploaded_file" u="bool move_uploaded_file(string path, string new_path)">Move a file if and only if it was created by an upload</s>
+<s f="parse_ini_file" u="array parse_ini_file(string filename [, bool process_sections])">Parse configuration file</s>
+<s f="php_strip_whitespace" u="string php_strip_whitespace(string file_name)">Return source with stripped comments and whitespace</s>
+<s f="print_r" u="mixed print_r(mixed var [, bool return])">Prints out or returns information about the specified variable</s>
+<s f="putenv" u="bool putenv(string setting)">Set the value of an environment variable</s>
+<s f="register_shutdown_function" u="void register_shutdown_function(string function_name)">Register a user-level function to be called on request termination</s>
+<s f="register_tick_function" u="bool register_tick_function(string function_name [, mixed arg [, mixed ... ]])">Registers a tick callback function</s>
+<s f="restore_include_path" u="void restore_include_path()">Restore the value of the include_path configuration option</s>
+<s f="set_include_path" u="string set_include_path(string new_include_path)">Sets the include_path configuration option</s>
+<s f="sleep" u="void sleep(int seconds)">Delay for a given number of seconds</s>
+<s f="sys_getloadavg" u="array sys_getloadavg()"></s>
+<s f="time_nanosleep" u="mixed time_nanosleep(long seconds, long nanoseconds)">Delay for a number of seconds and nano seconds</s>
+<s f="time_sleep_until" u="mixed time_sleep_until(float timestamp)">Make the script sleep until the specified time</s>
+<s f="unregister_tick_function" u="void unregister_tick_function(string function_name)">Unregisters a tick callback function</s>
+<s f="usleep" u="void usleep(int micro_seconds)">Delay for a given number of micro seconds</s>
+<s f="get_browser" u="mixed get_browser([string browser_name [, bool return_array]])">Get information about the capabilities of a browser. If browser_name is omitted    or null, HTTP_USER_AGENT is used. Returns an object by default; if return_array    is true, returns an array.</s>
+<s f="crc32" u="string crc32(string str)">Calculate the crc32 polynomial of a string</s>
+<s f="crypt" u="string crypt(string str [, string salt])">Hash a string</s>
+<s f="convert_cyr_string" u="string convert_cyr_string(string str, string from, string to)">Convert from one Cyrillic character set to another</s>
+<s f="strptime" u="string strptime(string timestamp, string format)">Parse a time/date generated with strftime()</s>
+<s f="chdir" u="bool chdir(string directory)">Change the current directory</s>
+<s f="chroot" u="bool chroot(string directory)">Change root directory</s>
+<s f="closedir" u="void closedir([resource dir_handle])">Close directory connection identified by the dir_handle</s>
+<s f="dir" u="object dir(string directory[, resource context])">Directory class with properties, handle and class and methods read, rewind and close</s>
+<s f="getcwd" u="mixed getcwd(void)">Gets the current directory</s>
+<s f="glob" u="array glob(string pattern [, int flags])">Find pathnames matching a pattern</s>
+<s f="opendir" u="mixed opendir(string path[, resource context])">Open a directory and return a dir_handle</s>
+<s f="readdir" u="string readdir([resource dir_handle])">Read directory entry from dir_handle</s>
+<s f="rewinddir" u="void rewinddir([resource dir_handle])">Rewind dir_handle back to the start</s>
+<s f="scandir" u="array scandir(string dir [, int sorting_order [, resource context]])">List files &amp; directories inside the specified path</s>
+<s f="dl" u="int dl(string extension_filename)">Load a PHP extension at runtime</s>
+<s f="dns_check_record" u="int dns_check_record(string host [, string type])">Check DNS records corresponding to a given Internet host name or IP address</s>
+<s f="dns_get_mx" u="bool dns_get_mx(string hostname, array mxhosts [, array weight])">Get MX records corresponding to a given Internet host name</s>
+<s f="gethostbyaddr" u="string gethostbyaddr(string ip_address)">Get the Internet host name corresponding to a given IP address</s>
+<s f="gethostbyname" u="string gethostbyname(string hostname)">Get the IP address corresponding to a given Internet host name</s>
+<s f="gethostbynamel" u="array gethostbynamel(string hostname)">Return a list of IP addresses that a given hostname resolves to.</s>
+<s f="escapeshellarg" u="string escapeshellarg(string arg)">Quote and escape an argument for use in a shell command</s>
+<s f="escapeshellcmd" u="string escapeshellcmd(string command)">Escape shell metacharacters</s>
+<s f="exec" u="string exec(string command [, array &amp;output [, int &amp;return_value]])">Execute an external program</s>
+<s f="passthru" u="void passthru(string command [, int &amp;return_value])">Execute an external program and display raw output</s>
+<s f="proc_nice" u="bool proc_nice(int priority)">Change the priority of the current process</s>
+<s f="shell_exec" u="string shell_exec(string cmd)">Execute command via shell and return complete output as string</s>
+<s f="system" u="int system(string command [, int &amp;return_value])">Execute an external program and display output</s>
+<s f="copy" u="bool copy(string source_file, string destination_file[, resource context])">Copy a file</s>
+<s f="fclose" u="bool fclose(resource fp)">Close an open file pointer</s>
+<s f="feof" u="bool feof(resource fp)">Test for end-of-file on a file pointer</s>
+<s f="fflush" u="bool fflush(resource fp)">Flushes output</s>
+<s f="fgetc" u="string fgetc(resource fp)">Get a character from file pointer</s>
+<s f="fgetcsv" u="array fgetcsv(resource fp [,int length [, string delimiter [, string enclosure[, string escape]]]])">Get line from file pointer and parse for CSV fields</s>
+<s f="fgets" u="string fgets(resource fp[, int lengthish])">Get a line from file pointer</s>
+<s f="fgetss" u="string fgetss(resource fp [, int lengthish, string allowable_tags])">Get a line from file pointer and strip HTML tags</s>
+<s f="file" u="array file(string filename [, int flags[, resource context]])">Read entire file into an array</s>
+<s f="file_get_contents" u="string file_get_contents(string filename [, long flags [, resource context [, long offset [, long maxlen]]]])">Read the entire file into a string</s>
+<s f="file_put_contents" u="int file_put_contents(string file, mixed data [, int flags [, resource context]])">Write/Create a file with contents data and return the number of bytes written</s>
+<s f="flock" u="bool flock(resource fp, int operation [, int &amp;wouldblock])">Portable file locking</s>
+<s f="fnmatch" u="bool fnmatch(string pattern, string filename [, int flags])">Match filename against pattern</s>
+<s f="fopen" u="resource fopen(string filename, string mode [, bool use_include_path [, resource context]])">Open a file or a URL and return a file pointer</s>
+<s f="fpassthru" u="int fpassthru(resource fp)">Output all remaining data from a file pointer</s>
+<s f="fputcsv" u="int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]])">Format line as CSV and write to file pointer</s>
+<s f="fread" u="string fread(resource fp, int length)">Binary-safe file read</s>
+<s f="fscanf" u="mixed fscanf(resource stream, string format [, string ...])">Implements a mostly ANSI compatible fscanf()</s>
+<s f="fseek" u="int fseek(resource fp, int offset [, int whence])">Seek on a file pointer</s>
+<s f="fstat" u="array fstat(resource fp)">Stat() on a filehandle</s>
+<s f="ftell" u="int ftell(resource fp)">Get file pointer's read/write position</s>
+<s f="ftruncate" u="bool ftruncate(resource fp, int size)">Truncate file to 'size' length</s>
+<s f="fwrite" u="int fwrite(resource fp, string str [, int length])">Binary-safe file write</s>
+<s f="get_meta_tags" u="array get_meta_tags(string filename [, bool use_include_path])">Extracts all meta tag content attributes from a file and returns an array</s>
+<s f="mkdir" u="bool mkdir(string pathname [, int mode [, bool recursive [, resource context]]])">Create a directory</s>
+<s f="pclose" u="int pclose(resource fp)">Close a file pointer opened by popen()</s>
+<s f="popen" u="resource popen(string command, string mode)">Execute a command and open either a read or a write pipe to it</s>
+<s f="readfile" u="int readfile(string filename [, int flags[, resource context]])">Output a file or a URL</s>
+<s f="realpath" u="string realpath(string path)">Return the resolved path</s>
+<s f="rename" u="bool rename(string old_name, string new_name[, resource context])">Rename a file</s>
+<s f="rewind" u="bool rewind(resource fp)">Rewind the position of a file pointer</s>
+<s f="rmdir" u="bool rmdir(string dirname[, resource context])">Remove a directory</s>
+<s f="sys_get_temp_dir" u="string sys_get_temp_dir()">Returns directory path used for temporary files</s>
+<s f="tempnam" u="string tempnam(string dir, string prefix)">Create a unique filename in a directory</s>
+<s f="tmpfile" u="resource tmpfile(void)">Create a temporary file that will be deleted automatically after use</s>
+<s f="umask" u="int umask([int mask])">Return or change the umask</s>
+<s f="unlink" u="bool unlink(string filename[, context context])">Delete a file</s>
+<s f="chgrp" u="bool chgrp(string filename, mixed group)">Change file group</s>
+<s f="chmod" u="bool chmod(string filename, int mode)">Change file mode</s>
+<s f="clearstatcache" u="void clearstatcache(void)">Clear file stat cache</s>
+<s f="disk_free_space" u="float disk_free_space(string path)">Get free disk space for filesystem that path is on</s>
+<s f="disk_total_space" u="float disk_total_space(string path)">Get total disk space for filesystem that path is on</s>
+<s f="file_exists" u="bool file_exists(string filename)">Returns true if filename exists</s>
+<s f="fileatime" u="int fileatime(string filename)">Get last access time of file</s>
+<s f="filectime" u="int filectime(string filename)">Get inode modification time of file</s>
+<s f="filegroup" u="int filegroup(string filename)">Get file group</s>
+<s f="fileinode" u="int fileinode(string filename)">Get file inode</s>
+<s f="filemtime" u="int filemtime(string filename)">Get last modification time of file</s>
+<s f="fileowner" u="int fileowner(string filename)">Get file owner</s>
+<s f="fileperms" u="int fileperms(string filename)">Get file permissions</s>
+<s f="filesize" u="int filesize(string filename)">Get file size</s>
+<s f="filetype" u="string filetype(string filename)">Get file type</s>
+<s f="is_dir" u="bool is_dir(string filename)">Returns true if file is directory</s>
+<s f="is_executable" u="bool is_executable(string filename)">Returns true if file is executable</s>
+<s f="is_file" u="bool is_file(string filename)">Returns true if file is a regular file</s>
+<s f="is_link" u="bool is_link(string filename)">Returns true if file is symbolic link</s>
+<s f="is_readable" u="bool is_readable(string filename)">Returns true if file can be read</s>
+<s f="is_writable" u="bool is_writable(string filename)">Returns true if file can be written</s>
+<s f="lchgrp" u="bool lchgrp(string filename, mixed group)">Change symlink group</s>
+<s f="lstat" u="array lstat(string filename)">Give information about a file or symbolic link</s>
+<s f="stat" u="array stat(string filename)">Give information about a file</s>
+<s f="touch" u="bool touch(string filename [, int time [, int atime]])">Set modification time of file</s>
+<s f="fprintf" u="int fprintf(resource stream, string format [, mixed arg1 [, mixed ...]])">Output a formatted string into a stream</s>
+<s f="printf" u="int printf(string format [, mixed arg1 [, mixed ...]])">Output a formatted string</s>
+<s f="sprintf" u="string sprintf(string format [, mixed arg1 [, mixed ...]])">Return a formatted string</s>
+<s f="vfprintf" u="int vfprintf(resource stream, string format, array args)">Output a formatted string into a stream</s>
+<s f="vprintf" u="int vprintf(string format, array args)">Output a formatted string</s>
+<s f="vsprintf" u="string vsprintf(string format, array args)">Return a formatted string</s>
+<s f="fsockopen" u="resource fsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])">Open Internet or Unix domain socket connection</s>
+<s f="pfsockopen" u="resource pfsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])">Open persistent Internet or Unix domain socket connection</s>
+<s f="ftok" u="int ftok(string pathname, string proj)">Convert a pathname and a project identifier to a System V IPC key</s>
+<s f="header" u="void header(string header [, bool replace, [int http_response_code]])">Sends a raw HTTP header</s>
+<s f="headers_list" u="array headers_list(void)">Return list of headers to be sent / already sent</s>
+<s f="headers_sent" u="bool headers_sent([string &amp;$file [, int &amp;$line]])">Returns true if headers have already been sent, false otherwise</s>
+<s f="setcookie" u="bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])">Send a cookie</s>
+<s f="setrawcookie" u="bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])">Send a cookie with no url encoding of the value</s>
+<s f="get_html_translation_table" u="array get_html_translation_table([int table [, int quote_style]])">Returns the internal translation table used by htmlspecialchars and htmlentities</s>
+<s f="html_entity_decode" u="string html_entity_decode(string string [, int quote_style][, string charset])">Convert all HTML entities to their applicable characters</s>
+<s f="htmlentities" u="string htmlentities(string string [, int quote_style[, string charset[, bool double_encode]]])">Convert all applicable characters to HTML entities</s>
+<s f="htmlspecialchars" u="string htmlspecialchars(string string [, int quote_style[, string charset[, bool double_encode]]])">Convert special characters to HTML entities</s>
+<s f="htmlspecialchars_decode" u="string htmlspecialchars_decode(string string [, int quote_style])">Convert special HTML entities back to characters</s>
+<s f="http_build_query" u="string http_build_query(mixed formdata [, string prefix [, string arg_separator]])">Generates a form-encoded query string from an associative array or object.</s>
+<s f="getimagesize" u="array getimagesize(string imagefile [, array info])">Get the size of an image as 4-element array</s>
+<s f="image_type_to_extension" u="string image_type_to_extension(int imagetype [, bool include_dot])">Get file extension for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype</s>
+<s f="image_type_to_mime_type" u="string image_type_to_mime_type(int imagetype)">Get Mime-Type for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype</s>
+<s f="php_egg_logo_guid" u="string php_egg_logo_guid(void)">Return the special ID used to request the PHP logo in phpinfo screens</s>
+<s f="php_ini_loaded_file" u="string php_ini_loaded_file(void)">Return the actual loaded ini filename</s>
+<s f="php_ini_scanned_files" u="string php_ini_scanned_files(void)">Return comma-separated string of .ini files parsed from the additional ini dir</s>
+<s f="php_logo_guid" u="string php_logo_guid(void)">Return the special ID used to request the PHP logo in phpinfo screens</s>
+<s f="php_real_logo_guid" u="string php_real_logo_guid(void)">Return the special ID used to request the PHP logo in phpinfo screens</s>
+<s f="php_sapi_name" u="string php_sapi_name(void)">Return the current SAPI module name</s>
+<s f="php_uname" u="string php_uname(void)">Return information about the system PHP was built on</s>
+<s f="phpcredits" u="void phpcredits([int flag])">Prints the list of people who've contributed to the PHP project</s>
+<s f="phpinfo" u="void phpinfo([int what])">Output a page of useful information about PHP and the current request</s>
+<s f="phpversion" u="string phpversion([string extension])">Return the current PHP version</s>
+<s f="zend_logo_guid" u="string zend_logo_guid(void)">Return the special ID used to request the Zend logo in phpinfo screens</s>
+<s f="iptcembed" u="array iptcembed(string iptcdata, string jpeg_file_name [, int spool])">Embed binary IPTC data into a JPEG image.</s>
+<s f="iptcparse" u="array iptcparse(string iptcdata)">Parse binary IPTC-data into associative array</s>
+<s f="lcg_value" u="float lcg_value()">Returns a value from the combined linear congruential generator</s>
+<s f="levenshtein" u="int levenshtein(string str1, string str2[, int cost_ins, int cost_rep, int cost_del])">Calculate Levenshtein distance between two strings</s>
+<s f="link" u="int link(string target, string link)">Create a hard link</s>
+<s f="linkinfo" u="int linkinfo(string filename)">Returns the st_dev field of the UNIX C stat structure describing the link</s>
+<s f="readlink" u="string readlink(string filename)">Return the target of a symbolic link</s>
+<s f="symlink" u="int symlink(string target, string link)">Create a symbolic link</s>
+<s f="ezmlm_hash" u="int ezmlm_hash(string addr)">Calculate EZMLM list hash value.</s>
+<s f="mail" u="int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])">Send an email message</s>
+<s f="abs" u="int abs(int number)">Return the absolute value of the number</s>
+<s f="acos" u="float acos(float number)">Return the arc cosine of the number in radians</s>
+<s f="acosh" u="float acosh(float number)">Returns the inverse hyperbolic cosine of the number, i.e. the value whose hyperbolic cosine is number</s>
+<s f="asin" u="float asin(float number)">Returns the arc sine of the number in radians</s>
+<s f="asinh" u="float asinh(float number)">Returns the inverse hyperbolic sine of the number, i.e. the value whose hyperbolic sine is number</s>
+<s f="atan" u="float atan(float number)">Returns the arc tangent of the number in radians</s>
+<s f="atan2" u="float atan2(float y, float x)">Returns the arc tangent of y/x, with the resulting quadrant determined by the signs of y and x</s>
+<s f="atanh" u="float atanh(float number)">Returns the inverse hyperbolic tangent of the number, i.e. the value whose hyperbolic tangent is number</s>
+<s f="base_convert" u="string base_convert(string number, int frombase, int tobase)">Converts a number in a string from any base &lt;= 36 to any base &lt;= 36</s>
+<s f="bindec" u="int bindec(string binary_number)">Returns the decimal equivalent of the binary number</s>
+<s f="ceil" u="float ceil(float number)">Returns the next highest integer value of the number</s>
+<s f="cos" u="float cos(float number)">Returns the cosine of the number in radians</s>
+<s f="cosh" u="float cosh(float number)">Returns the hyperbolic cosine of the number, defined as (exp(number) + exp(-number))/2</s>
+<s f="decbin" u="string decbin(int decimal_number)">Returns a string containing a binary representation of the number</s>
+<s f="dechex" u="string dechex(int decimal_number)">Returns a string containing a hexadecimal representation of the given number</s>
+<s f="decoct" u="string decoct(int decimal_number)">Returns a string containing an octal representation of the given number</s>
+<s f="deg2rad" u="float deg2rad(float number)">Converts the number in degrees to the radian equivalent</s>
+<s f="exp" u="float exp(float number)">Returns e raised to the power of the number</s>
+<s f="expm1" u="float expm1(float number)">Returns exp(number) - 1, computed in a way that accurate even when the value of number is close to zero</s>
+<s f="floor" u="float floor(float number)">Returns the next lowest integer value from the number</s>
+<s f="fmod" u="float fmod(float x, float y)">Returns the remainder of dividing x by y as a float</s>
+<s f="hexdec" u="int hexdec(string hexadecimal_number)">Returns the decimal equivalent of the hexadecimal number</s>
+<s f="hypot" u="float hypot(float num1, float num2)">Returns sqrt(num1*num1 + num2*num2)</s>
+<s f="is_finite" u="bool is_finite(float val)">Returns whether argument is finite</s>
+<s f="is_infinite" u="bool is_infinite(float val)">Returns whether argument is infinite</s>
+<s f="is_nan" u="bool is_nan(float val)">Returns whether argument is not a number</s>
+<s f="log" u="float log(float number, [float base])">Returns the natural logarithm of the number, or the base log if base is specified</s>
+<s f="log10" u="float log10(float number)">Returns the base-10 logarithm of the number</s>
+<s f="log1p" u="float log1p(float number)">Returns log(1 + number), computed in a way that accurate even when the value of number is close to zero</s>
+<s f="number_format" u="string number_format(float number [, int num_decimal_places [, string dec_seperator, string thousands_seperator]])">Formats a number with grouped thousands</s>
+<s f="octdec" u="int octdec(string octal_number)">Returns the decimal equivalent of an octal string</s>
+<s f="pi" u="float pi(void)">Returns an approximation of pi</s>
+<s f="pow" u="number pow(number base, number exponent)">Returns base raised to the power of exponent. Returns integer result when possible</s>
+<s f="rad2deg" u="float rad2deg(float number)">Converts the radian number to the equivalent number in degrees</s>
+<s f="round" u="float round(float number [, int precision])">Returns the number rounded to specified precision</s>
+<s f="sin" u="float sin(float number)">Returns the sine of the number in radians</s>
+<s f="sinh" u="float sinh(float number)">Returns the hyperbolic sine of the number, defined as (exp(number) - exp(-number))/2</s>
+<s f="sqrt" u="float sqrt(float number)">Returns the square root of the number</s>
+<s f="tan" u="float tan(float number)">Returns the tangent of the number in radians</s>
+<s f="tanh" u="float tanh(float number)">Returns the hyperbolic tangent of the number, defined as sinh(number)/cosh(number)</s>
+<s f="md5" u="string md5(string str, [ bool raw_output])">Calculate the md5 hash of a string</s>
+<s f="md5_file" u="string md5_file(string filename [, bool raw_output])">Calculate the md5 hash of given filename</s>
+<s f="metaphone" u="string metaphone(string text[, int phones])">Break english phrases down into their phonemes</s>
+<s f="getrusage" u="array getrusage([int who])">Returns an array of usage statistics</s>
+<s f="gettimeofday" u="array gettimeofday([bool get_as_float])">Returns the current time as array</s>
+<s f="microtime" u="mixed microtime([bool get_as_float])">Returns either a string or a float containing the current time in seconds and microseconds</s>
+<s f="pack" u="string pack(string format, mixed arg1 [, mixed arg2 [, mixed ...]])">Takes one or more arguments and packs them into a binary string according to the format argument</s>
+<s f="unpack" u="array unpack(string format, string input)">Unpack binary string into named array elements according to format argument</s>
+<s f="getlastmod" u="int getlastmod(void)">Get time of last page modification</s>
+<s f="getmygid" u="int getmygid(void)">Get PHP script owner's GID</s>
+<s f="getmyinode" u="int getmyinode(void)">Get the inode of the current script being parsed</s>
+<s f="getmypid" u="int getmypid(void)">Get current process ID</s>
+<s f="getmyuid" u="int getmyuid(void)">Get PHP script owner's UID</s>
+<s f="proc_close" u="int proc_close(resource process)">close a process opened by proc_open</s>
+<s f="proc_get_status" u="array proc_get_status(resource process)">get information about a process opened by proc_open</s>
+<s f="proc_open" u="resource proc_open(string command, array descriptorspec, array &amp;pipes [, string cwd [, array env [, array other_options]]])">Run a process with more control over it's file descriptors</s>
+<s f="proc_terminate" u="bool proc_terminate(resource process [, long signal])">kill a process opened by proc_open</s>
+<s f="quoted_printable_decode" u="binary quoted_printable_decode(string str)">Convert a quoted-printable string to an 8 bit string</s>
+<s f="getrandmax" u="int getrandmax(void)">Returns the maximum value a random number can have</s>
+<s f="mt_getrandmax" u="int mt_getrandmax(void)">Returns the maximum value a random number from Mersenne Twister can have</s>
+<s f="mt_rand" u="int mt_rand([int min, int max])">Returns a random number from Mersenne Twister</s>
+<s f="mt_srand" u="void mt_srand([int seed])">Seeds Mersenne Twister random number generator</s>
+<s f="rand" u="int rand([int min, int max])">Returns a random number</s>
+<s f="srand" u="void srand([int seed])">Seeds random number generator</s>
+<s f="ereg" u="int ereg(string pattern, string string [, array registers])">Regular expression match</s>
+<s f="ereg_replace" u="string ereg_replace(string pattern, string replacement, string string)">Replace regular expression</s>
+<s f="eregi" u="int eregi(string pattern, string string [, array registers])">Case-insensitive regular expression match</s>
+<s f="eregi_replace" u="string eregi_replace(string pattern, string replacement, string string)">Case insensitive replace regular expression</s>
+<s f="split" u="array split(string pattern, string string [, int limit])">Split string into array by regular expression</s>
+<s f="spliti" u="array spliti(string pattern, string string [, int limit])">Split string into array by regular expression case-insensitive</s>
+<s f="sql_regcase" u="string sql_regcase(string string)">Make regular expression for case insensitive match</s>
+<s f="sha1" u="string sha1(string str [, bool raw_output])">Calculate the sha1 hash of a string</s>
+<s f="sha1_file" u="string sha1_file(string filename [, bool raw_output])">Calculate the sha1 hash of given filename</s>
+<s f="soundex" u="string soundex(string str)">Calculate the soundex key of a string</s>
+<s f="stream_context_create" u="resource stream_context_create([array options[, array params]])">Create a file context and optionally set parameters</s>
+<s f="stream_context_get_default" u="resource stream_context_get_default([array options])">Get a handle on the default file/stream context and optionally set parameters</s>
+<s f="stream_context_get_options" u="array stream_context_get_options(resource context|resource stream)">Retrieve options for a stream/wrapper/context</s>
+<s f="stream_context_set_option" u="bool stream_context_set_option(resource context|resource stream, string wrappername, string optionname, mixed value)">* Overloaded form: stream_context_set_option(resource context|resource stream, array options)  * Set an option (or several options) for a wrapper</s>
+<s f="stream_context_set_params" u="bool stream_context_set_params(resource context|resource stream, array options)">Set parameters for a file context</s>
+<s f="stream_copy_to_stream" u="long stream_copy_to_stream(resource source, resource dest [, long maxlen [, long pos]])">Reads up to maxlen bytes from source stream and writes them to dest stream.</s>
+<s f="stream_default_encoding" u="bool stream_default_encoding(string encoding)">Convenience wrapper for ini_set('unicode.stream_encoding', $encoding)</s>
+<s f="stream_encoding" u="void stream_encoding(resource stream[, string encoding])">Set character set for stream encoding UTODO: Return current encoding charset</s>
+<s f="stream_filter_append" u="resource stream_filter_append(resource stream, string filtername[, int read_write[, mixed filterparams]])">Append a filter to a stream</s>
+<s f="stream_filter_prepend" u="resource stream_filter_prepend(resource stream, string filtername[, int read_write[, mixed filterparams]])">Prepend a filter to a stream</s>
+<s f="stream_filter_remove" u="bool stream_filter_remove(resource stream_filter)">Flushes any data in the filter's internal buffer, removes it from the chain, and frees the resource</s>
+<s f="stream_get_contents" u="string stream_get_contents(resource source [, long maxlen [, long offset]])">Reads all remaining bytes (or up to maxlen bytes) from a stream and returns them as a string.</s>
+<s f="stream_get_line" u="string stream_get_line(resource stream, int maxlen [, string ending])">Read up to maxlen bytes from a stream or until the ending string is found</s>
+<s f="stream_get_meta_data" u="array stream_get_meta_data(resource fp)">Retrieves header/meta data from streams/file pointers</s>
+<s f="stream_get_transports" u="array stream_get_transports()">Retrieves list of registered socket transports</s>
+<s f="stream_get_wrappers" u="array stream_get_wrappers()">Retrieves list of registered stream wrappers</s>
+<s f="stream_is_local" u="bool stream_is_local(resource stream|string url)"></s>
+<s f="stream_resolve_include_path" u="string stream_resolve_include_path(string filename[, resource context])">Determine what file will be opened by calls to fopen() with a relative path</s>
+<s f="stream_select" u="int stream_select(array &amp;read_streams, array &amp;write_streams, array &amp;except_streams, int tv_sec[, int tv_usec])">Runs the select() system call on the sets of streams with a timeout specified by tv_sec and tv_usec</s>
+<s f="stream_set_blocking" u="bool stream_set_blocking(resource socket, int mode)">Set blocking/non-blocking mode on a socket or stream</s>
+<s f="stream_set_timeout" u="bool stream_set_timeout(resource stream, int seconds, int microseconds)">Set timeout on stream read to seconds + microseonds</s>
+<s f="stream_set_write_buffer" u="int stream_set_write_buffer(resource fp, int buffer)">Set file write buffer</s>
+<s f="stream_socket_accept" u="resource stream_socket_accept(resource serverstream, [ double timeout, string &amp;peername ])">Accept a client connection from a server socket</s>
+<s f="stream_socket_client" u="resource stream_socket_client(string remoteaddress [, long &amp;errcode, string &amp;errstring, double timeout, long flags, resource context])">Open a client connection to a remote address</s>
+<s f="stream_socket_enable_crypto" u="int stream_socket_enable_crypto(resource stream, bool enable [, int cryptokind, resource sessionstream])">Enable or disable a specific kind of crypto on the stream</s>
+<s f="stream_socket_get_name" u="string stream_socket_get_name(resource stream, bool want_peer)">Returns either the locally bound or remote name for a socket stream</s>
+<s f="stream_socket_pair" u="array stream_socket_pair(int domain, int type, int protocol)">Creates a pair of connected, indistinguishable socket streams</s>
+<s f="stream_socket_recvfrom" u="string stream_socket_recvfrom(resource stream, long amount [, long flags [, string &amp;remote_addr]])">Receives data from a socket stream</s>
+<s f="stream_socket_sendto" u="long stream_socket_sendto(resouce stream, string data [, long flags [, string target_addr]])">Send data to a socket stream.  If target_addr is specified it must be in dotted quad (or [ipv6]) format</s>
+<s f="stream_socket_server" u="resource stream_socket_server(string localaddress [, long &amp;errcode, string &amp;errstring, long flags, resource context])">Create a server socket bound to localaddress</s>
+<s f="stream_socket_shutdown" u="int stream_socket_shutdown(resource stream, int how)">causes all or part of a full-duplex connection on the socket associated  with stream to be shut down.  If how is SHUT_RD,  further receptions will  be disallowed. If how is SHUT_WR, further transmissions will be disallowed.  If how is SHUT_RDWR,  further  receptions and transmissions will be  disallowed.</s>
+<s f="addcslashes" u="binary addcslashes(binary str, binary charlist)">Escapes all chars mentioned in charlist with backslash. It creates octal representations if asked to backslash characters with 8th bit set or with ASCII&lt;32 (except '\n', '\r', '\t' etc...)</s>
+<s f="addslashes" u="string addslashes(string str)">Escapes single quote, double quotes and backslash characters in a string with backslashes</s>
+<s f="basename" u="string basename(string path [, string suffix])">Returns the filename component of the path</s>
+<s f="bin2hex" u="string bin2hex(string data)">Converts the binary representation of data to hex</s>
+<s f="chr" u="string chr(int codepoint)">Converts a codepoint number to a character</s>
+<s f="chunk_split" u="string chunk_split(string str [, int chunklen [, string ending]])">Returns split line</s>
+<s f="count_chars" u="mixed count_chars(string input [, int mode])">Returns info about what characters are used in input</s>
+<s f="dirname" u="string dirname(string path)">Returns the directory name component of the path</s>
+<s f="explode" u="array explode(string separator, string str [, int limit])">Splits a string on string separator and return array of components. If limit is positive only limit number of components is returned. If limit is negative all components except the last abs(limit) are returned.</s>
+<s f="hebrev" u="string hebrev(string str [, int max_chars_per_line])">Converts logical Hebrew text to visual text</s>
+<s f="hebrevc" u="string hebrevc(string str [, int max_chars_per_line])">Converts logical Hebrew text to visual text with newline conversion</s>
+<s f="implode" u="string implode([string glue,] array pieces)">Joins array elements placing glue string between items and return one string</s>
+<s f="join" u="string join([string glue,] array pieces)">An alias for implode</s>
+<s f="localeconv" u="array localeconv(void)">Returns numeric formatting information based on the current locale</s>
+<s f="ltrim" u="string ltrim(string str [, string character_mask])">Strips whitespace from the beginning of a string</s>
+<s f="money_format" u="string money_format(string format , float value)">Convert monetary value(s) to string</s>
+<s f="nl2br" u="string nl2br(string str)">Converts newlines to HTML line breaks</s>
+<s f="nl_langinfo" u="string nl_langinfo(int item)">Query language and locale information</s>
+<s f="ord" u="int ord(string character)">Returns the codepoint value of a character</s>
+<s f="parse_str" u="void parse_str(string encoded_string [, array result])">Parses GET/POST/COOKIE data and sets global variables</s>
+<s f="pathinfo" u="array pathinfo(string path[, int options])">Returns information about a certain string</s>
+<s f="quotemeta" u="string quotemeta(string str)">Quotes meta characters</s>
+<s f="rtrim" u="string rtrim(string str [, string character_mask])">Removes trailing whitespace</s>
+<s f="setlocale" u="string setlocale(mixed category, string locale [, string ...])">Set locale information</s>
+<s f="similar_text" u="int similar_text(string str1, string str2 [, float percent])">Calculates the similarity between two strings</s>
+<s f="sscanf" u="mixed sscanf(string str, string format [, string ...])">Implements an ANSI C compatible sscanf</s>
+<s f="str_getcsv" u="array str_getcsv(string input[, string delimiter[, string enclosure[, string escape]]])">Parse a CSV string into an array</s>
+<s f="str_ireplace" u="mixed str_ireplace(mixed search, mixed replace, mixed subject [, int &amp;replace_count])">Replaces all occurrences of search in haystack with replace / case-insensitive</s>
+<s f="str_pad" u="string str_pad(string input, int pad_length [, string pad_string [, int pad_type]])">Returns input string padded on the left or right to specified length with pad_string</s>
+<s f="str_repeat" u="string str_repeat(string input, int mult)">Returns the input string repeat mult times</s>
+<s f="str_replace" u="mixed str_replace(mixed search, mixed replace, mixed subject [, int &amp;replace_count])">Replaces all occurrences of search in haystack with replace</s>
+<s f="str_rot13" u="string str_rot13(string str)">Perform the rot13 transform on a string</s>
+<s f="str_shuffle" u="void str_shuffle(string str)">Shuffles string. One permutation of all possible is created</s>
+<s f="str_split" u="array str_split(string str [, int split_length])">Convert a string to an array. If split_length is specified, break the string down into chunks each split_length characters long.</s>
+<s f="str_word_count" u="mixed str_word_count(string str, [int format [, string charlist]])">Counts the number of words inside a string. If format of 1 is specified,     then the function will return an array containing all the words     found inside the string. If format of 2 is specified, then the function     will return an associated array where the position of the word is the key     and the word itself is the value.      For the purpose of this function, 'word' is defined as a locale dependent     string containing alphabetic characters, which also may contain, but not start     with &quot;'&quot; and &quot;-&quot; characters.</s>
+<s f="strchr" u="string strchr(string haystack, string needle[, bool part])">An alias for strstr</s>
+<s f="strcoll" u="int strcoll(string str1, string str2)">Compares two strings using the current locale</s>
+<s f="strcspn" u="int strcspn(string str, string mask [, start [, len]])">Finds length of initial segment consisting entirely of characters not found in mask. If start or/and length is provide works like strcspn(substr($s,$start,$len),$bad_chars)</s>
+<s f="strip_tags" u="string strip_tags(string str [, string allowable_tags])">Strips HTML and PHP tags from a string</s>
+<s f="stripcslashes" u="binary stripcslashes(binary str)">Strips backslashes from a string. Uses C-style conventions</s>
+<s f="stripos" u="int stripos(string haystack, string needle [, int offset])">Finds position of first occurrence of a string within another, case insensitive</s>
+<s f="stripslashes" u="string stripslashes(string str)">Strips backslashes from a string</s>
+<s f="stristr" u="string stristr(string haystack, string needle[, bool part])">Finds first occurrence of a string within another, case insensitive</s>
+<s f="strnatcasecmp" u="int strnatcasecmp(string s1, string s2)">Returns the result of case-insensitive string comparison using 'natural' algorithm</s>
+<s f="strnatcmp" u="int strnatcmp(string s1, string s2)">Returns the result of string comparison using 'natural' algorithm</s>
+<s f="strpbrk" u="array strpbrk(string haystack, string char_list)">Search a string for any of a set of characters</s>
+<s f="strpos" u="int strpos(string haystack, mixed needle [, int offset])">Finds position of first occurrence of a string within another</s>
+<s f="strrchr" u="string strrchr(string haystack, string needle)">Finds the last occurrence of a character in a string within another</s>
+<s f="strrev" u="string strrev(string str)">Reverse a string</s>
+<s f="strripos" u="int strripos(string haystack, string needle [, int offset])">Finds position of last occurrence of a string within another string</s>
+<s f="strrpos" u="int strrpos(string haystack, string needle [, int offset])">Finds position of last occurrence of a string within another string</s>
+<s f="strspn" u="int strspn(string str, string mask [, start [, len]])">Finds length of initial segment consisting entirely of characters found in mask. If start or/and length is provided works like strspn(substr($s,$start,$len),$good_chars)</s>
+<s f="strstr" u="string strstr(string haystack, string needle[, bool part])">Finds first occurrence of a string within another</s>
+<s f="strtok" u="string strtok([string str,] string token)">Tokenize a string</s>
+<s f="strtolower" u="string strtolower(string str)">Makes a string lowercase</s>
+<s f="strtotitle" u="string strtotitle(string str)">Makes a string titlecase</s>
+<s f="strtoupper" u="string strtoupper(string str)">Makes a string uppercase</s>
+<s f="strtr" u="string strtr(string str, string from[, string to])">Translates characters in str using given translation tables</s>
+<s f="substr" u="string substr(string str, int start [, int length])">Returns part of a string</s>
+<s f="substr_compare" u="int substr_compare(string main_str, string str, int offset [, int length [, bool case_sensitivity]])">Binary safe optionally case insensitive comparison of 2 strings from an offset, up to length characters</s>
+<s f="substr_count" u="int substr_count(string haystack, string needle [, int offset [, int length]])">Returns the number of times a substring occurs in the string</s>
+<s f="substr_replace" u="mixed substr_replace(mixed str, mixed repl, mixed start [, mixed length])">Replaces part of a string with another string</s>
+<s f="trim" u="string trim(string str [, string character_mask])">Strips whitespace from the beginning and end of a string</s>
+<s f="ucfirst" u="string ucfirst(string str)">Makes a string's first character uppercase</s>
+<s f="ucwords" u="string ucwords(string str)">Uppercase the first character of every word in a string</s>
+<s f="wordwrap" u="string wordwrap(string str [, int width [, string break [, boolean cut]]])">Wraps buffer to selected number of characters using string break char</s>
+<s f="closelog" u="bool closelog(void)">Close connection to system logger</s>
+<s f="define_syslog_variables" u="void define_syslog_variables(void)">Initializes all syslog-related variables</s>
+<s f="openlog" u="bool openlog(string ident, int option, int facility)">Open connection to system logger</s>
+<s f="syslog" u="bool syslog(int priority, string message)">Generate a system log message</s>
+<s f="floatval" u="float floatval(mixed var)">Get the float value of a variable</s>
+<s f="gettype" u="string gettype(mixed var)">Returns the type of the variable</s>
+<s f="intval" u="int intval(mixed var [, int base])">Get the integer value of a variable using the optional base for the conversion</s>
+<s f="is_array" u="bool is_array(mixed var)">Returns true if variable is an array</s>
+<s f="is_binary" u="bool is_binary(mixed var)">Returns true if variable is a native (binary) string</s>
+<s f="is_bool" u="bool is_bool(mixed var)">Returns true if variable is a boolean</s>
+<s f="is_buffer" u="bool is_buffer(mixed var)">Returns true if variable is a native, unicode or binary string</s>
+<s f="is_callable" u="bool is_callable(mixed var [, bool syntax_only [, string callable_name]])">Returns true if var is callable.</s>
+<s f="is_float" u="bool is_float(mixed var)">Returns true if variable is float point</s>
+<s f="is_long" u="bool is_long(mixed var)">Returns true if variable is a long (integer)</s>
+<s f="is_null" u="bool is_null(mixed var)">Returns true if variable is null</s>
+<s f="is_numeric" u="bool is_numeric(mixed value)">Returns true if value is a number or a numeric string</s>
+<s f="is_object" u="bool is_object(mixed var)">Returns true if variable is an object</s>
+<s f="is_resource" u="bool is_resource(mixed var)">Returns true if variable is a resource</s>
+<s f="is_scalar" u="bool is_scalar(mixed value)">Returns true if value is a scalar</s>
+<s f="is_string" u="bool is_string(mixed var)">Returns true if variable is a Unicode or binary string</s>
+<s f="is_unicode" u="bool is_unicode(mixed var)">Returns true if variable is a unicode string</s>
+<s f="settype" u="bool settype(mixed var, string type)">Set the type of the variable</s>
+<s f="strval" u="string strval(mixed var)">Get the string value of a variable</s>
+<s f="uniqid" u="string uniqid([string prefix , bool more_entropy])">Generates a unique ID</s>
+<s f="get_headers" u="array get_headers(string url[, int format])">fetches all the headers sent by the server in response to a HTTP request</s>
+<s f="parse_url" u="mixed parse_url(string url, [int url_component])">Parse a URL and return its components</s>
+<s f="rawurldecode" u="binary rawurldecode(binary str)">Decodes URL-encodes string</s>
+<s f="rawurlencode" u="binary rawurlencode(binary str)">URL-encodes string</s>
+<s f="urldecode" u="binary urldecode(binary str)">Decodes URL-encoded string</s>
+<s f="urlencode" u="string urlencode(binary str)">URL-encodes string</s>
+<s f="stream_bucket_append" u="void stream_bucket_append(resource brigade, resource bucket)">Append bucket to brigade</s>
+<s f="stream_bucket_make_writeable" u="object stream_bucket_make_writeable(resource brigade)">Return a bucket object from the brigade for operating on</s>
+<s f="stream_bucket_new" u="object stream_bucket_new(resource stream, string buffer)">Create a new bucket for use on the current stream</s>
+<s f="stream_bucket_prepend" u="void stream_bucket_prepend(resource brigade, resource bucket)">Prepend bucket to brigade</s>
+<s f="stream_filter_register" u="bool stream_filter_register(string filtername, string classname)">Registers a custom filter handler class</s>
+<s f="stream_get_filters" u="array stream_get_filters(void)">Returns a list of registered filters</s>
+<s f="user_filter_nop" u="void user_filter_nop(void)">Non-function</s>
+<s f="convert_uudecode" u="string convert_uudecode(string data)">decode a uuencoded string</s>
+<s f="convert_uuencode" u="string convert_uuencode(string data)">uuencode a string</s>
+<s f="debug_zval_dump" u="void debug_zval_dump(mixed var)">Dumps a string representation of an internal zend value to output.</s>
+<s f="memory_get_peak_usage" u="int memory_get_peak_usage([real_usage])">Returns the peak allocated by PHP memory</s>
+<s f="memory_get_usage" u="int memory_get_usage([real_usage])">Returns the allocated by PHP memory</s>
+<s f="serialize" u="string serialize(mixed variable)">Returns a string representation of variable (which can later be unserialized)</s>
+<s f="unserialize" u="mixed unserialize(string variable_representation)">Takes a string representation of variable and recreates it</s>
+<s f="var_dump" u="void var_dump(mixed var)">Dumps a string representation of variable to output</s>
+<s f="var_export" u="mixed var_export(mixed var [, bool return])">Outputs or returns a string representation of a variable</s>
+<s f="var_inspect" u="void var_inspect(mixed var)">Dumps a string representation of variable to output (verbose form)</s>
+<s f="version_compare" u="int version_compare(string ver1, string ver2 [, string oper])">Compares two &quot;PHP-standardized&quot; version number strings</s>
+<s f="sybase_affected_rows" u="int sybase_affected_rows([int link_id])">Get number of affected rows in last query</s>
+<s f="sybase_close" u="bool sybase_close([int link_id])">Close Sybase connection</s>
+<s f="sybase_connect" u="int sybase_connect([string host [, string user [, string password [, string charset [, string appname]]]]])">Open Sybase server connection</s>
+<s f="sybase_data_seek" u="bool sybase_data_seek(int result, int offset)">Move internal row pointer</s>
+<s f="sybase_fetch_array" u="array sybase_fetch_array(int result)">Fetch row as array</s>
+<s f="sybase_fetch_field" u="object sybase_fetch_field(int result [, int offset])">Get field information</s>
+<s f="sybase_fetch_object" u="object sybase_fetch_object(int result)">Fetch row as object</s>
+<s f="sybase_fetch_row" u="array sybase_fetch_row(int result)">Get row as enumerated array</s>
+<s f="sybase_field_seek" u="bool sybase_field_seek(int result, int offset)">Set field offset</s>
+<s f="sybase_free_result" u="bool sybase_free_result(int result)">Free result memory</s>
+<s f="sybase_get_last_message" u="string sybase_get_last_message(void)">Returns the last message from server (over min_message_severity)</s>
+<s f="sybase_min_error_severity" u="void sybase_min_error_severity(int severity)">Sets the minimum error severity</s>
+<s f="sybase_min_message_severity" u="void sybase_min_message_severity(int severity)">Sets the minimum message severity</s>
+<s f="sybase_num_fields" u="int sybase_num_fields(int result)">Get number of fields in result</s>
+<s f="sybase_num_rows" u="int sybase_num_rows(int result)">Get number of rows in result</s>
+<s f="sybase_pconnect" u="int sybase_pconnect([string host [, string user [, string password [, string charset [, string appname]]]]])">Open persistent Sybase connection</s>
+<s f="sybase_query" u="int sybase_query(string query [, int link_id])">Send Sybase query</s>
+<s f="sybase_result" u="string sybase_result(int result, int row, mixed field)">Get result data</s>
+<s f="sybase_select_db" u="bool sybase_select_db(string database [, int link_id])">Select Sybase database</s>
+<s f="sybase_affected_rows" u="int sybase_affected_rows([int link_id])">Get number of affected rows in last query</s>
+<s f="sybase_close" u="bool sybase_close([int link_id])">Close Sybase connection</s>
+<s f="sybase_connect" u="int sybase_connect([string host [, string user [, string password [, string charset [, string appname]]]]])">Open Sybase server connection</s>
+<s f="sybase_data_seek" u="bool sybase_data_seek(int result, int offset)">Move internal row pointer</s>
+<s f="sybase_deadlock_retry_count" u="void sybase_deadlock_retry_count(int retry_count)">Sets deadlock retry count</s>
+<s f="sybase_fetch_array" u="array sybase_fetch_array(int result)">Fetch row as array</s>
+<s f="sybase_fetch_assoc" u="array sybase_fetch_assoc(int result)">Fetch row as array without numberic indices</s>
+<s f="sybase_fetch_field" u="object sybase_fetch_field(int result [, int offset])">Get field information</s>
+<s f="sybase_fetch_object" u="object sybase_fetch_object(int result [, mixed object])">Fetch row as object</s>
+<s f="sybase_fetch_row" u="array sybase_fetch_row(int result)">Get row as enumerated array</s>
+<s f="sybase_field_seek" u="bool sybase_field_seek(int result, int offset)">Set field offset</s>
+<s f="sybase_free_result" u="bool sybase_free_result(int result)">Free result memory</s>
+<s f="sybase_get_last_message" u="string sybase_get_last_message(void)">Returns the last message from server (over min_message_severity)</s>
+<s f="sybase_min_client_severity" u="void sybase_min_client_severity(int severity)">Sets minimum client severity</s>
+<s f="sybase_min_server_severity" u="void sybase_min_server_severity(int severity)">Sets minimum server severity</s>
+<s f="sybase_num_fields" u="int sybase_num_fields(int result)">Get number of fields in result</s>
+<s f="sybase_num_rows" u="int sybase_num_rows(int result)">Get number of rows in result</s>
+<s f="sybase_pconnect" u="int sybase_pconnect([string host [, string user [, string password [, string charset [, string appname]]]]])">Open persistent Sybase connection</s>
+<s f="sybase_query" u="int sybase_query(string query [, int link_id])">Send Sybase query</s>
+<s f="sybase_result" u="string sybase_result(int result, int row, mixed field)">Get result data</s>
+<s f="sybase_select_db" u="bool sybase_select_db(string database [, int link_id])">Select Sybase database</s>
+<s f="sybase_set_message_handler" u="bool sybase_set_message_handler(mixed error_func [, resource connection])">Set the error handler, to be called when a server message is raised.     If error_func is NULL the handler will be deleted</s>
+<s f="sybase_unbuffered_query" u="int sybase_unbuffered_query(string query [, int link_id])">Send Sybase query</s>
+<s f="msg_get_queue" u="resource msg_get_queue(int key [, int perms])">Attach to a message queue</s>
+<s f="msg_receive" u="mixed msg_receive(resource queue, int desiredmsgtype, int &amp;msgtype, int maxsize, mixed message [, bool unserialize=true [, int flags=0 [, int errorcode]]])">Send a message of type msgtype (must be &gt; 0) to a message queue</s>
+<s f="msg_remove_queue" u="bool msg_remove_queue(resource queue)">Destroy the queue</s>
+<s f="msg_send" u="bool msg_send(resource queue, int msgtype, mixed message [, bool serialize=true [, bool blocking=true [, int errorcode]]])">Send a message of type msgtype (must be &gt; 0) to a message queue</s>
+<s f="msg_set_queue" u="bool msg_set_queue(resource queue, array data)">Set information for a message queue</s>
+<s f="msg_stat_queue" u="array msg_stat_queue(resource queue)">Returns information about a message queue</s>
+<s f="sem_acquire" u="bool sem_acquire(resource id)">Acquires the semaphore with the given id, blocking if necessary</s>
+<s f="sem_get" u="resource sem_get(int key [, int max_acquire [, int perm [, int auto_release]])">Return an id for the semaphore with the given key, and allow max_acquire (default 1) processes to acquire it simultaneously</s>
+<s f="sem_release" u="bool sem_release(resource id)">Releases the semaphore with the given id</s>
+<s f="sem_remove" u="bool sem_remove(resource id)">Removes semaphore from Unix systems</s>
+<s f="shm_attach" u="resource shm_attach(int key [, int memsize [, int perm]])">Creates or open a shared memory segment</s>
+<s f="shm_detach" u="bool shm_detach(resource shm_identifier)">Disconnects from shared memory segment</s>
+<s f="shm_get_var" u="mixed shm_get_var(resource id, int variable_key)">Returns a variable from shared memory</s>
+<s f="shm_has_var" u="bool shm_has_var(resource id, int variable_key)">Checks whether a specific entry exists</s>
+<s f="shm_put_var" u="bool shm_put_var(resource shm_identifier, int variable_key, mixed variable)">Inserts or updates a variable in shared memory</s>
+<s f="shm_remove" u="bool shm_remove(resource shm_identifier)">Removes shared memory from Unix systems</s>
+<s f="shm_remove_var" u="bool shm_remove_var(resource id, int variable_key)">Removes variable from shared memory</s>
+<s f="tidyNode::getParent" u="tidyNode tidyNode::getParent()">Returns the parent node if available or NULL</s>
+<s f="tidyNode::hasChildren" u="bool tidyNode::hasChildren()">Returns true if this node has children</s>
+<s f="tidyNode::hasSiblings" u="bool tidyNode::hasSiblings()">Returns true if this node has siblings</s>
+<s f="tidyNode::isAsp" u="bool tidyNode::isAsp()">Returns true if this node is ASP</s>
+<s f="tidyNode::isComment" u="bool tidyNode::isComment()">Returns true if this node represents a comment</s>
+<s f="tidyNode::isHtml" u="bool tidyNode::isHtml()">Returns true if this node is part of a HTML document</s>
+<s f="tidyNode::isJste" u="bool tidyNode::isJste()">Returns true if this node is JSTE</s>
+<s f="tidyNode::isPhp" u="bool tidyNode::isPhp()">Returns true if this node is PHP</s>
+<s f="tidyNode::isText" u="bool tidyNode::isText()">Returns true if this node represents text (no markup)</s>
+<s f="tidy_access_count" u="int tidy_access_count()">Returns the Number of Tidy accessibility warnings encountered for specified document.</s>
+<s f="tidy_clean_repair" u="boolean tidy_clean_repair()">Execute configured cleanup and repair operations on parsed markup</s>
+<s f="tidy_config_count" u="int tidy_config_count()">Returns the Number of Tidy configuration errors encountered for specified document.</s>
+<s f="tidy_diagnose" u="boolean tidy_diagnose()">Run configured diagnostics on parsed and repaired markup.</s>
+<s f="tidy_error_count" u="int tidy_error_count()">Returns the Number of Tidy errors encountered for specified document.</s>
+<s f="tidy_get_body" u="TidyNode tidy_get_body(resource tidy)">Returns a TidyNode Object starting from the &lt;BODY&gt; tag of the tidy parse tree</s>
+<s f="tidy_get_config" u="array tidy_get_config()">Get current Tidy configuration</s>
+<s f="tidy_get_error_buffer" u="string tidy_get_error_buffer()">Return warnings and errors which occured parsing the specified document</s>
+<s f="tidy_get_head" u="TidyNode tidy_get_head()">Returns a TidyNode Object starting from the &lt;HEAD&gt; tag of the tidy parse tree</s>
+<s f="tidy_get_html" u="TidyNode tidy_get_html()">Returns a TidyNode Object starting from the &lt;HTML&gt; tag of the tidy parse tree</s>
+<s f="tidy_get_html_ver" u="int tidy_get_html_ver()">Get the Detected HTML version for the specified document.</s>
+<s f="tidy_get_opt_doc" u="string tidy_get_opt_doc(tidy resource, string optname)">Returns the documentation for the given option name</s>
+<s f="tidy_get_output" u="string tidy_get_output()">Return a string representing the parsed tidy markup</s>
+<s f="tidy_get_release" u="string tidy_get_release()">Get release date (version) for Tidy library</s>
+<s f="tidy_get_root" u="TidyNode tidy_get_root()">Returns a TidyNode Object representing the root of the tidy parse tree</s>
+<s f="tidy_get_status" u="int tidy_get_status()">Get status of specfied document.</s>
+<s f="tidy_getopt" u="mixed tidy_getopt(string option)">Returns the value of the specified configuration option for the tidy document.</s>
+<s f="tidy_is_xhtml" u="bool tidy_is_xhtml()">Indicates if the document is a XHTML document.</s>
+<s f="tidy_is_xml" u="bool tidy_is_xml()">Indicates if the document is a generic (non HTML/XHTML) XML document.</s>
+<s f="tidy_parse_file" u="boolean tidy_parse_file(string file [, mixed config_options [, string encoding [, bool use_include_path]]])">Parse markup in file or URI</s>
+<s f="tidy_parse_string" u="bool tidy_parse_string(string input [, mixed config_options [, string encoding]])">Parse a document stored in a string</s>
+<s f="tidy_repair_file" u="boolean tidy_repair_file(string filename [, mixed config_file [, string encoding [, bool use_include_path]]])">Repair a file using an optionally provided configuration file</s>
+<s f="tidy_repair_string" u="boolean tidy_repair_string(string data [, mixed config_file [, string encoding]])">Repair a string using an optionally provided configuration file</s>
+<s f="tidy_warning_count" u="int tidy_warning_count()">Returns the Number of Tidy warnings encountered for specified document.</s>
+<s f="token_get_all" u="array token_get_all(string source)"></s>
+<s f="token_name" u="string token_name(int type)"></s>
+<s f="Collator::compare" u="int Collator::compare(string str1, string str2)">Compare two strings using collation }}}</s>
+<s f="Collator::getAttribute" u="int Collator::getAttribute(int attribute)">Returns a collation attribute }}}</s>
+<s f="Collator::getStrength" u="int Collator::getStrength()">Returns the current collation strength }}}</s>
+<s f="Collator::setAttribute" u="bool Collator::setAttribute(int attribute, int value)">Set a collation attribute }}}</s>
+<s f="Collator::setStrength" u="void Collator::setStrength(int strength)">Set the collation strength }}}</s>
+<s f="Collator::sort" u="array Collator::sort(array input)">Sort an array using collation }}}</s>
+<s f="collator_compare" u="int collator_compare(Collator coll, string str1, string str2)">Compare two strings using collation</s>
+<s f="collator_create" u="Collator collator_create(string locale)">Create a new Collator object</s>
+<s f="collator_get_attribute" u="int collator_get_attribute(Collator coll, int attribute)">Returns a collation attribute</s>
+<s f="collator_get_default" u="Collator collator_get_default(void)">Returns default collator</s>
+<s f="collator_get_strength" u="int collator_get_strength(Collator coll)">Returns the current collation strength</s>
+<s f="collator_set_attribute" u="bool collator_set_attribute(Collator coll, int attribute, int value)">Set a collation attribute</s>
+<s f="collator_set_default" u="void collator_set_default(Collator coll)">Sets default collator</s>
+<s f="collator_set_strength" u="void collator_set_strength(Collator coll, int strength)">Set the collation strength</s>
+<s f="collator_sort" u="array collator_sort(Collator coll, array input)">Sort an array using collation</s>
+<s f="Collator::__construct" u=" Collator::__construct(string locale)">Create a new Collator object</s>
+<s f="locale_get_default" u="string locale_get_default(void)">Returns default locale</s>
+<s f="locale_set_default" u="bool locale_set_default(string locale)">Sets default locale</s>
+<s f="char_enum_names" u="bool char_enum_names(callback Callback, int start, int limit[, int extended = false])">Enumerate all assigned Unicode characters between the start and limit code points (start inclusive, limit exclusive) and call a function for each, passing the code point value and the character name.</s>
+<s f="char_enum_types" u="bool char_enum_types(callback Callback)">Enumerate all code points with their general categories invoking a callback for each category</s>
+<s f="char_from_digit" u="char char_from_digit(int digit[, int radix = 10])">Get the character representation for the specified digit (optionally in the specified radix)</s>
+<s f="char_from_name" u="char char_from_name(string charname[, bool extended = false])">Translate a human readable character name into a codepoint</s>
+<s f="char_get_age" u="string char_get_age(char c)">Get the &quot;age&quot; of the code point (the Unicode version when it was first designated or assigned a character)</s>
+<s f="char_get_combining_class" u="int char_get_combining_class(char text)">Returns the combining class of the character</s>
+<s f="char_get_digit_value" u="int char_get_digit_value(char text[, int radix])">Returns the decimal digit value of the character (optionally in the specific radix).</s>
+<s f="char_get_direction" u="int char_get_direction(char c)">Returns the bidirectional category value for the character, which is used in the Unicode bidirectional algorithm (UAX #9 http://www.unicode.org/reports/tr9/)</s>
+<s f="char_get_mirrored" u="char char_get_mirrored(char c)">Maps the specified character to its &quot;mirror-image&quot;</s>
+<s f="char_get_name" u="string char_get_name(char c[, bool extended = false])">Get the human readable name associated with the character</s>
+<s f="char_get_numeric_value" u="float char_get_numeric_value(char text)">Get the numeric value for the character, as defined in the Unicode Character Database</s>
+<s f="char_get_property_from_name" u="int char_get_property_from_name(string property_name)">Get the property ID for the given property name</s>
+<s f="char_get_property_max_value" u="int char_get_property_max_value(int property)">Get the maximum possible value associated with the specified property</s>
+<s f="char_get_property_min_value" u="int char_get_property_min_value(int property)">Get the minimum possible value for the specified property</s>
+<s f="char_get_property_name" u="string char_get_property_name(int property)">Get the Unicode name for the given property</s>
+<s f="char_get_property_value" u="int char_get_property_value(char c, int property)">Get the value of a property associated with the character</s>
+<s f="char_get_property_value_from_name" u="int char_get_property_value_from_name(int property, string value_name)">Get the value ID for the given property value name</s>
+<s f="char_get_property_value_name" u="string char_get_property_value_name(int property, int value[, int name_choice])">Get the Unicode name for the givenproperty value</s>
+<s f="char_get_type" u="int char_get_type(char c)">Returns the general category value for the code point</s>
+<s f="char_has_binary_property" u="bool char_has_binary_property(string text, int property)">Determines if all the characters in the string have the specified binary property</s>
+<s f="char_is_alnum" u="bool char_is_alnum(string text)">Determines if the string consists only of alpanumeric characters</s>
+<s f="char_is_alpha" u="bool char_is_alpha(string text)">Determines if the string consists only of letter characters</s>
+<s f="char_is_alphabetic" u="bool char_is_alphabetic(string text)">Determines if the string consists only of characters with Alphabetic property</s>
+<s f="char_is_base" u="bool char_is_base(string text)">Determines if the string consists of only of base characters</s>
+<s f="char_is_blank" u="bool char_is_blank(string text)">Determines if the string consists only of &quot;blank&quot; characters</s>
+<s f="char_is_cntrl" u="bool char_is_cntrl(string text)">Determines if the string consists only of control characters</s>
+<s f="char_is_defined" u="bool char_is_defined(string text)">Determines if the string consists only of defined characters (valid Unicode points)</s>
+<s f="char_is_digit" u="bool char_is_digit(string text)">Determines if the string consists only of digits</s>
+<s f="char_is_graph" u="bool char_is_graph(string text)">Determines if the string consists only of &quot;graphic&quot; characters</s>
+<s f="char_is_id_ignorable" u="bool char_is_id_ignorable(string text)">Determines if the specified characters should be regarded as an ignorable character in an identifier, according to Java</s>
+<s f="char_is_id_part" u="bool char_is_id_part(string text)">etermines if the specified characters are permissible in an identifier, according to Java</s>
+<s f="char_is_id_start" u="bool char_is_id_start(string text)">Determines if the specified character is permissible as the first character in an identifier according to Unicode</s>
+<s f="char_is_iso_control" u="bool char_is_iso_control(string text)">Determines whether the specified code points are ISO control codes</s>
+<s f="char_is_lower" u="bool char_is_lower(string text)">Determines if the string is lowercase</s>
+<s f="char_is_mirrored" u="bool char_is_mirrored(string text)">Determines whether the specified characters have the Bidi_Mirrored property</s>
+<s f="char_is_print" u="bool char_is_print(string text)">Determines if the string consists only of printable characters</s>
+<s f="char_is_punct" u="bool char_is_punct(string text)">Determines if the string consists only of punctuation characters</s>
+<s f="char_is_space" u="bool char_is_space(string text)">Determines if the string consists only of space characters</s>
+<s f="char_is_titlecase" u="bool char_is_titlecase(string text)">Determines whether the string consists only of titlecase characters</s>
+<s f="char_is_upper" u="bool char_is_upper(string text)">Determines if the string is uppercase</s>
+<s f="char_is_uppercase" u="bool char_is_uppercase(string text)">Determines if the string consists only of characters with Uppercase property</s>
+<s f="char_is_valid" u="bool char_is_valid(char c)">Determines if the the code point is valid character, according to Unicode</s>
+<s f="char_is_whitespace" u="bool char_is_whitespace(string text)">Determines if the string consists only of whitespace characters, according to Java/ICU</s>
+<s f="char_is_xdigit" u="bool char_is_xdigit(string text)">Determines if the string consists only of hexadecimal digits</s>
+<s f="str_transliterate" u="string str_transliterate(string str, string from_script, string to_script[, string variant])">Transliterate a string from the source script to the target script</s>
+<s f="unicode_decode" u="unicode unicode_decode(binary input, string encoding [, int flags])">Takes a binary string converts it to a Unicode string using the specifed encoding</s>
+<s f="unicode_encode" u="binary unicode_encode(unicode input, string encoding [, int flags])">Takes a Unicode string and converts it to a binary string using the specified encoding</s>
+<s f="unicode_get_error_mode" u="int unicode_get_error_mode(int direction)">Returns global conversion error mode for the specified conversion direction</s>
+<s f="unicode_get_subst_char" u="string unicode_get_subst_char()">Returns global substitution character for conversion from Unicode to codepage</s>
+<s f="unicode_restore_error_handler" u="bool unicode_restore_error_handler(void)">Restores the active error handler to the one which was previously active (before the last unicode_set_error_handler() call)</s>
+<s f="unicode_semantics" u="bool unicode_semantics()">Check whether unicode semantics are enabled</s>
+<s f="unicode_set_error_handler" u="callback unicode_set_error_handler(callback new_callback)">Set (or clear) the custom Unicode conversion error handler</s>
+<s f="unicode_set_error_mode" u="bool unicode_set_error_mode(int direction, int mode)">Sets global conversion error mode for the specified conversion direction</s>
+<s f="unicode_set_subst_char" u="bool unicode_set_subst_char(string character)">Sets global substitution character for conversion from Unicode to codepage</s>
+<s f="TextIterator::__construct" u="void TextIterator::__construct(unicode text [, int flags = TextIterator::CODEPOINT [, string locale ]])">TextIterator constructor</s>
+<s f="TextIterator::current" u="unicode TextIterator::current()">Returns the element at the current boundary</s>
+<s f="TextIterator::first" u="int TextIterator::first()">Positions iterator at the first character in the text and returns the offset</s>
+<s f="TextIterator::following" u="int TextIterator::following(int offset)">Advances to the text boundary following the specified offset and returns its offset</s>
+<s f="TextIterator::getAll" u="array TextIterator::getAll()">Return all text pieces determined by the text boundaries</s>
+<s f="TextIterator::getAvailableLocales" u="array TextIterator::getAvailableLocales()">Returns locales for which text boundary information is available</s>
+<s f="TextIterator::getRuleStatus" u="int TextIterator::getRuleStatus()">Return the status from the break rule that determined the most recent boundary</s>
+<s f="TextIterator::getRuleStatusArray" u="array TextIterator::getRuleStatusArray()">Return the statuses from the break rules that determined the most recent boundary</s>
+<s f="TextIterator::isBoundary" u="bool TextIterator::isBoundary(int offset)">Determines whether specified offset is a text boundary</s>
+<s f="TextIterator::key" u="int TextIterator::key()">Returns the number boundaries iterated through</s>
+<s f="TextIterator::last" u="int TextIterator::last()">Positions iterator beyond the last character in the text and returns the offset</s>
+<s f="TextIterator::next" u="int TextIterator::next([int n])">Advances to the n'th text boundary following the current one and returns its offset</s>
+<s f="TextIterator::offset" u="int TextIterator::offset()">Returns the offset of the current text boundary</s>
+<s f="TextIterator::preceding" u="int TextIterator::preceding(int offset)">Advances to the text boundary preceding the specified offset and returns its offset</s>
+<s f="TextIterator::previous" u="int TextIterator::previous([int n])">Advances to the n'th text boundary preceding the current one and returns its offset</s>
+<s f="TextIterator::valid" u="bool TextIterator::valid()">Determines validity of the iterator</s>
+<s f="wddx_add_vars" u="int wddx_add_vars(int packet_id,  mixed var_names [, mixed ...])">Serializes given variables and adds them to packet given by packet_id</s>
+<s f="wddx_packet_end" u="string wddx_packet_end(int packet_id)">Ends specified WDDX packet and returns the string containing the packet</s>
+<s f="wddx_packet_start" u="int wddx_packet_start([string comment])">Starts a WDDX packet with optional comment and returns the packet id</s>
+<s f="wddx_serialize_value" u="string wddx_serialize_value(mixed var [, string comment])">Creates a new packet and serializes the given value</s>
+<s f="wddx_serialize_vars" u="string wddx_serialize_vars(mixed var_name [, mixed ...])">Creates a new packet and serializes given variables into a struct</s>
+<s f="wddx_unserialize" u="mixed wddx_unserialize(mixed packet)">Unserializes given packet and returns a PHP value</s>
+<s f="utf8_decode" u="string utf8_decode(string data)">Converts a UTF-8 encoded string to ISO-8859-1</s>
+<s f="utf8_encode" u="string utf8_encode(string data)">Encodes an ISO-8859-1 string to UTF-8</s>
+<s f="xml_error_string" u="string xml_error_string(int code)">Get XML parser error string</s>
+<s f="xml_get_current_byte_index" u="int xml_get_current_byte_index(resource parser)">Get current byte index for an XML parser</s>
+<s f="xml_get_current_column_number" u="int xml_get_current_column_number(resource parser)">Get current column number for an XML parser</s>
+<s f="xml_get_current_line_number" u="int xml_get_current_line_number(resource parser)">Get current line number for an XML parser</s>
+<s f="xml_get_error_code" u="int xml_get_error_code(resource parser)">Get XML parser error code</s>
+<s f="xml_parse" u="int xml_parse(resource parser, string data [, int isFinal])">Start parsing an XML document</s>
+<s f="xml_parse_into_struct" u="int xml_parse_into_struct(resource parser, string data, array &amp;struct, array &amp;index)">Parsing a XML document</s>
+<s f="xml_parser_create" u="resource xml_parser_create([string encoding])">Create an XML parser</s>
+<s f="xml_parser_create_ns" u="resource xml_parser_create_ns([string encoding [, string sep]])">Create an XML parser</s>
+<s f="xml_parser_free" u="int xml_parser_free(resource parser)">Free an XML parser</s>
+<s f="xml_parser_get_option" u="int xml_parser_get_option(resource parser, int option)">Get options from an XML parser</s>
+<s f="xml_parser_set_option" u="int xml_parser_set_option(resource parser, int option, mixed value)">Set options in an XML parser</s>
+<s f="xml_set_character_data_handler" u="int xml_set_character_data_handler(resource parser, string hdl)">Set up character data handler</s>
+<s f="xml_set_default_handler" u="int xml_set_default_handler(resource parser, string hdl)">Set up default handler</s>
+<s f="xml_set_element_handler" u="int xml_set_element_handler(resource parser, string shdl, string ehdl)">Set up start and end element handlers</s>
+<s f="xml_set_end_namespace_decl_handler" u="int xml_set_end_namespace_decl_handler(resource parser, string hdl)">Set up character data handler</s>
+<s f="xml_set_external_entity_ref_handler" u="int xml_set_external_entity_ref_handler(resource parser, string hdl)">Set up external entity reference handler</s>
+<s f="xml_set_notation_decl_handler" u="int xml_set_notation_decl_handler(resource parser, string hdl)">Set up notation declaration handler</s>
+<s f="xml_set_object" u="int xml_set_object(resource parser, object &amp;obj)">Set up object which should be used for callbacks</s>
+<s f="xml_set_processing_instruction_handler" u="int xml_set_processing_instruction_handler(resource parser, string hdl)">Set up processing instruction (PI) handler</s>
+<s f="xml_set_start_namespace_decl_handler" u="int xml_set_start_namespace_decl_handler(resource parser, string hdl)">Set up character data handler</s>
+<s f="xml_set_unparsed_entity_decl_handler" u="int xml_set_unparsed_entity_decl_handler(resource parser, string hdl)">Set up unparsed entity declaration handler</s>
+<s f="XMLReader::XML" u="boolean XMLReader::XML(string source [, string encoding [, int options]])">Sets the string that the the XMLReader will parse.</s>
+<s f="XMLReader::close" u="boolean XMLReader::close()">Closes xmlreader - current frees resources until xmlTextReaderClose is fixed in libxml</s>
+<s f="XMLReader::expand" u="boolean XMLReader::expand()">Moves the position of the current instance to the next node in the stream.</s>
+<s f="XMLReader::getAttribute" u="string XMLReader::getAttribute(string name)">Get value of an attribute from current element</s>
+<s f="XMLReader::getAttributeNo" u="string XMLReader::getAttributeNo(int index)">Get value of an attribute at index from current element</s>
+<s f="XMLReader::getAttributeNs" u="string XMLReader::getAttributeNs(string name, string namespaceURI)">Get value of a attribute via name and namespace from current element</s>
+<s f="XMLReader::getParserProperty" u="boolean XMLReader::getParserProperty(int property)">Indicates whether given property (one of the parser option constants) is set or not on parser</s>
+<s f="XMLReader::isValid" u="boolean XMLReader::isValid()">Returns boolean indicating if parsed document is valid or not. Must set XMLREADER_LOADDTD or XMLREADER_VALIDATE parser option prior to the first call to read  or this method will always return FALSE</s>
+<s f="XMLReader::lookupNamespace" u="string XMLReader::lookupNamespace(string prefix)">Return namespaceURI for associated prefix on current node</s>
+<s f="XMLReader::moveToAttribute" u="boolean XMLReader::moveToAttribute(string name)">Positions reader at specified attribute - Returns TRUE on success and FALSE on failure</s>
+<s f="XMLReader::moveToAttributeNo" u="boolean XMLReader::moveToAttributeNo(int index)">Positions reader at attribute at spcecified index. Returns TRUE on success and FALSE on failure</s>
+<s f="XMLReader::moveToAttributeNs" u="boolean XMLReader::moveToAttributeNs(string name, string namespaceURI)">Positions reader at attribute spcified by name and namespaceURI. Returns TRUE on success and FALSE on failure</s>
+<s f="XMLReader::moveToElement" u="boolean XMLReader::moveToElement()">Moves the position of the current instance to the node that contains the current Attribute node.</s>
+<s f="XMLReader::moveToFirstAttribute" u="boolean XMLReader::moveToFirstAttribute()">Moves the position of the current instance to the first attribute associated with the current node.</s>
+<s f="XMLReader::moveToNextAttribute" u="boolean XMLReader::moveToNextAttribute()">Moves the position of the current instance to the next attribute associated with the current node.</s>
+<s f="XMLReader::next" u="boolean XMLReader::next([string localname])">Moves the position of the current instance to the next node in the stream.</s>
+<s f="XMLReader::open" u="boolean XMLReader::open(string URI [, string encoding [, int options]])">Sets the URI that the the XMLReader will parse.</s>
+<s f="XMLReader::read" u="boolean XMLReader::read()">Moves the position of the current instance to the next node in the stream.</s>
+<s f="XMLReader::readInnerXml" u="boolean XMLReader::readInnerXml()">Reads the contents of the current node, including child nodes and markup.</s>
+<s f="XMLReader::readOuterXml" u="boolean XMLReader::readOuterXml()">Reads the contents of the current node, including child nodes and markup.</s>
+<s f="XMLReader::readString" u="boolean XMLReader::readString()">Reads the contents of an element or a text node as a string.</s>
+<s f="XMLReader::setParserProperty" u="boolean XMLReader::setParserProperty(int property, boolean value)">Sets parser property (one of the parser option constants). Properties must be set after open() or XML() and before the first read() is called</s>
+<s f="XMLReader::setRelaxNGSchema" u="boolean XMLReader::setRelaxNGSchema(string filename)">Sets the string that the the XMLReader will parse.</s>
+<s f="XMLReader::setRelaxNGSchemaSource" u="boolean XMLReader::setRelaxNGSchemaSource(string source)">Sets the string that the the XMLReader will parse.</s>
+<s f="XMLReader::setSchema" u="boolean XMLReader::setSchema(string filename)">Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read().</s>
+<s f="xmlrpc_decode" u="array xmlrpc_decode(string xml [, string encoding])">Decodes XML into native PHP types</s>
+<s f="xmlrpc_decode_request" u="array xmlrpc_decode_request(string xml, string&amp; method [, string encoding])">Decodes XML into native PHP types</s>
+<s f="xmlrpc_encode" u="string xmlrpc_encode(mixed value)">Generates XML for a PHP value</s>
+<s f="xmlrpc_encode_request" u="string xmlrpc_encode_request(string method, mixed params)">Generates XML for a method request</s>
+<s f="xmlrpc_get_type" u="string xmlrpc_get_type(mixed value)">Gets xmlrpc type for a PHP value. Especially useful for base64 and datetime strings</s>
+<s f="xmlrpc_is_fault" u="bool xmlrpc_is_fault(array)">Determines if an array value represents an XMLRPC fault.</s>
+<s f="xmlrpc_parse_method_descriptions" u="array xmlrpc_parse_method_descriptions(string xml)">Decodes XML into a list of method descriptions</s>
+<s f="xmlrpc_server_add_introspection_data" u="int xmlrpc_server_add_introspection_data(resource server, array desc)">Adds introspection documentation</s>
+<s f="xmlrpc_server_call_method" u="mixed xmlrpc_server_call_method(resource server, string xml, mixed user_data [, array output_options])">Parses XML requests and call methods</s>
+<s f="xmlrpc_server_create" u="resource xmlrpc_server_create(void)">Creates an xmlrpc server</s>
+<s f="xmlrpc_server_destroy" u="int xmlrpc_server_destroy(resource server)">Destroys server resources</s>
+<s f="xmlrpc_server_register_introspection_callback" u="bool xmlrpc_server_register_introspection_callback(resource server, string function)">Register a PHP function to generate documentation</s>
+<s f="xmlrpc_server_register_method" u="bool xmlrpc_server_register_method(resource server, string method_name, string function)">Register a PHP function to handle method matching method_name</s>
+<s f="xmlrpc_set_type" u="bool xmlrpc_set_type(string value, string type)">Sets xmlrpc type, base64 or datetime, for a PHP string value</s>
+<s f="xmlwriter_end_attribute" u="bool xmlwriter_end_attribute(resource xmlwriter)">End attribute - returns FALSE on error</s>
+<s f="xmlwriter_end_cdata" u="bool xmlwriter_end_cdata(resource xmlwriter)">End current CDATA - returns FALSE on error</s>
+<s f="xmlwriter_end_comment" u="bool xmlwriter_end_comment(resource xmlwriter)">Create end comment - returns FALSE on error</s>
+<s f="xmlwriter_end_document" u="bool xmlwriter_end_document(resource xmlwriter)">End current document - returns FALSE on error</s>
+<s f="xmlwriter_end_dtd" u="bool xmlwriter_end_dtd(resource xmlwriter)">End current DTD - returns FALSE on error</s>
+<s f="xmlwriter_end_dtd_attlist" u="bool xmlwriter_end_dtd_attlist(resource xmlwriter)">End current DTD AttList - returns FALSE on error</s>
+<s f="xmlwriter_end_dtd_element" u="bool xmlwriter_end_dtd_element(resource xmlwriter)">End current DTD element - returns FALSE on error</s>
+<s f="xmlwriter_end_dtd_entity" u="bool xmlwriter_end_dtd_entity(resource xmlwriter)">End current DTD Entity - returns FALSE on error</s>
+<s f="xmlwriter_end_element" u="bool xmlwriter_end_element(resource xmlwriter)">End current element - returns FALSE on error</s>
+<s f="xmlwriter_end_pi" u="bool xmlwriter_end_pi(resource xmlwriter)">End current PI - returns FALSE on error</s>
+<s f="xmlwriter_flush" u="mixed xmlwriter_flush(resource xmlwriter [,bool empty])">Output current buffer</s>
+<s f="xmlwriter_full_end_element" u="bool xmlwriter_full_end_element(resource xmlwriter)">End current element - returns FALSE on error</s>
+<s f="xmlwriter_open_memory" u="resource xmlwriter_open_memory()">Create new xmlwriter using memory for string output</s>
+<s f="xmlwriter_open_uri" u="resource xmlwriter_open_uri(string source)">Create new xmlwriter using source uri for output</s>
+<s f="xmlwriter_output_memory" u="string xmlwriter_output_memory(resource xmlwriter [,bool flush])">Output current buffer as string</s>
+<s f="xmlwriter_set_indent" u="bool xmlwriter_set_indent(resource xmlwriter, bool indent)">Toggle indentation on/off - returns FALSE on error</s>
+<s f="xmlwriter_set_indent_string" u="bool xmlwriter_set_indent_string(resource xmlwriter, string indentString)">Set string used for indenting - returns FALSE on error</s>
+<s f="xmlwriter_start_attribute" u="bool xmlwriter_start_attribute(resource xmlwriter, string name)">Create start attribute - returns FALSE on error</s>
+<s f="xmlwriter_start_attribute_ns" u="bool xmlwriter_start_attribute_ns(resource xmlwriter, string prefix, string name, string uri)">Create start namespaced attribute - returns FALSE on error</s>
+<s f="xmlwriter_start_cdata" u="bool xmlwriter_start_cdata(resource xmlwriter)">Create start CDATA tag - returns FALSE on error</s>
+<s f="xmlwriter_start_comment" u="bool xmlwriter_start_comment(resource xmlwriter)">Create start comment - returns FALSE on error</s>
+<s f="xmlwriter_start_document" u="bool xmlwriter_start_document(resource xmlwriter, string version, string encoding, string standalone)">Create document tag - returns FALSE on error</s>
+<s f="xmlwriter_start_dtd" u="bool xmlwriter_start_dtd(resource xmlwriter, string name, string pubid, string sysid)">Create start DTD tag - returns FALSE on error</s>
+<s f="xmlwriter_start_dtd_attlist" u="bool xmlwriter_start_dtd_attlist(resource xmlwriter, string name)">Create start DTD AttList - returns FALSE on error</s>
+<s f="xmlwriter_start_dtd_element" u="bool xmlwriter_start_dtd_element(resource xmlwriter, string name)">Create start DTD element - returns FALSE on error</s>
+<s f="xmlwriter_start_dtd_entity" u="bool xmlwriter_start_dtd_entity(resource xmlwriter, string name, bool isparam)">Create start DTD Entity - returns FALSE on error</s>
+<s f="xmlwriter_start_element" u="bool xmlwriter_start_element(resource xmlwriter, string name)">Create start element tag - returns FALSE on error</s>
+<s f="xmlwriter_start_element_ns" u="bool xmlwriter_start_element_ns(resource xmlwriter, string prefix, string name, string uri)">Create start namespaced element tag - returns FALSE on error</s>
+<s f="xmlwriter_start_pi" u="bool xmlwriter_start_pi(resource xmlwriter, string target)">Create start PI tag - returns FALSE on error</s>
+<s f="xmlwriter_text" u="bool xmlwriter_text(resource xmlwriter, string content)">Write text - returns FALSE on error</s>
+<s f="xmlwriter_write_attribute" u="bool xmlwriter_write_attribute(resource xmlwriter, string name, string content)">Write full attribute - returns FALSE on error</s>
+<s f="xmlwriter_write_attribute_ns" u="bool xmlwriter_write_attribute_ns(resource xmlwriter, string prefix, string name, string uri, string content)">Write full namespaced attribute - returns FALSE on error</s>
+<s f="xmlwriter_write_cdata" u="bool xmlwriter_write_cdata(resource xmlwriter, string content)">Write full CDATA tag - returns FALSE on error</s>
+<s f="xmlwriter_write_comment" u="bool xmlwriter_write_comment(resource xmlwriter, string content)">Write full comment tag - returns FALSE on error</s>
+<s f="xmlwriter_write_dtd" u="bool xmlwriter_write_dtd(resource xmlwriter, string name, string pubid, string sysid, string subset)">Write full DTD tag - returns FALSE on error</s>
+<s f="xmlwriter_write_dtd_attlist" u="bool xmlwriter_write_dtd_attlist(resource xmlwriter, string name, string content)">Write full DTD AttList tag - returns FALSE on error</s>
+<s f="xmlwriter_write_dtd_element" u="bool xmlwriter_write_dtd_element(resource xmlwriter, string name, string content)">Write full DTD element tag - returns FALSE on error</s>
+<s f="xmlwriter_write_dtd_entity" u="bool xmlwriter_write_dtd_entity(resource xmlwriter, string name, string content [, int pe [, string pubid [, string sysid [, string ndataid]]]])">Write full DTD Entity tag - returns FALSE on error</s>
+<s f="xmlwriter_write_element" u="bool xmlwriter_write_element(resource xmlwriter, string name[, string content])">Write full element tag - returns FALSE on error</s>
+<s f="xmlwriter_write_element_ns" u="bool xmlwriter_write_element_ns(resource xmlwriter, string prefix, string name, string uri[, string content])">Write full namesapced element tag - returns FALSE on error</s>
+<s f="xmlwriter_write_pi" u="bool xmlwriter_write_pi(resource xmlwriter, string target, string content)">Write full PI tag - returns FALSE on error</s>
+<s f="xmlwriter_write_raw" u="bool xmlwriter_write_raw(resource xmlwriter, string content)">Write text - returns FALSE on error</s>
+<s f="xsl_xsltprocessor_get_parameter" u="string xsl_xsltprocessor_get_parameter(string namespace, string name)"></s>
+<s f="xsl_xsltprocessor_has_exslt_support" u="bool xsl_xsltprocessor_has_exslt_support()"></s>
+<s f="xsl_xsltprocessor_import_stylesheet" u="void xsl_xsltprocessor_import_stylesheet(domdocument doc)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# Since:</s>
+<s f="xsl_xsltprocessor_register_php_functions" u="void xsl_xsltprocessor_register_php_functions()"></s>
+<s f="xsl_xsltprocessor_remove_parameter" u="bool xsl_xsltprocessor_remove_parameter(string namespace, string name)"></s>
+<s f="xsl_xsltprocessor_set_parameter" u="bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value])"></s>
+<s f="xsl_xsltprocessor_transform_to_doc" u="domdocument xsl_xsltprocessor_transform_to_doc(domnode doc)">URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# Since:</s>
+<s f="xsl_xsltprocessor_transform_to_uri" u="int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri)"></s>
+<s f="xsl_xsltprocessor_transform_to_xml" u="string xsl_xsltprocessor_transform_to_xml(domdocument doc)"></s>
+<s f="addFile" u="bool addFile(string filepath[, string entryname[, int start [, int length]]])">Add a file in a Zip archive using its path and the name to use.</s>
+<s f="addFromString" u="bool addFromString(string name, string content)">Add a file using content and the entry name</s>
+<s f="close" u="bool close()">close the zip archive</s>
+<s f="createEmptyDir" u="bool createEmptyDir(string dirname)">Returns the index of the entry named filename in the archive</s>
+<s f="deleteIndex" u="bool deleteIndex(int index)">Delete a file using its index</s>
+<s f="deleteName" u="bool deleteName(string name)">Delete a file using its index</s>
+<s f="getArchiveComment" u="string getArchiveComment()">Returns the comment of an entry using its index</s>
+<s f="getCommentIndex" u="string getCommentIndex(int index)">Returns the comment of an entry using its index</s>
+<s f="getCommentName" u="string getCommentName(string name)">Returns the comment of an entry using its name</s>
+<s f="getFromIndex" u="string getFromIndex(string entryname[, int len [, int flags]])">get the contents of an entry using its index</s>
+<s f="getFromName" u="string getFromName(string entryname[, int len [, int flags]])">get the contents of an entry using its name</s>
+<s f="getNameIndex" u="string getNameIndex(int index [, int flags])">Returns the name of the file at position index</s>
+<s f="getStream" u="resource getStream(string entryname)">get a stream for an entry using its name</s>
+<s f="locateName" u="int locateName(string filename[, int flags])">Returns the index of the entry named filename in the archive</s>
+<s f="open" u="mixed open(string source [, int flags])">Create new zip using source uri for output, return TRUE on success or the error code</s>
+<s f="renameIndex" u="bool renameIndex(int index, string new_name)">Rename an entry selected by its index to new_name</s>
+<s f="renameName" u="bool renameName(string name, string new_name)">Rename an entry selected by its name to new_name</s>
+<s f="setArchiveComment" u="bool setArchiveComment(string name, string comment)">Set or remove (NULL/'') the comment of the archive</s>
+<s f="setCommentIndex" u="bool setCommentIndex(int index, string comment)">Set or remove (NULL/'') the comment of an entry using its index</s>
+<s f="setCommentName" u="bool setCommentName(string name, string comment)">Set or remove (NULL/'') the comment of an entry using its Name</s>
+<s f="statIndex" u="resource statIndex(int index[, int flags])">Returns the zip entry informations using its index</s>
+<s f="statName" u="array statName(string filename[, int flags])">Returns the information about a the zip entry filename</s>
+<s f="unchangeAll" u="bool unchangeAll()">All changes to files and global information in archive are reverted</s>
+<s f="unchangeAll" u="bool unchangeAll()">Revert all global changes to the archive archive.  For now, this only reverts archive comment changes.</s>
+<s f="unchangeIndex" u="bool unchangeIndex(int index)">Changes to the file at position index are reverted</s>
+<s f="unchangeName" u="bool unchangeName(string name)">Changes to the file named 'name' are reverted</s>
+<s f="zip_close" u="void zip_close(resource zip)">Close a Zip archive</s>
+<s f="zip_entry_close" u="void zip_entry_close(resource zip_ent)">Close a zip entry</s>
+<s f="zip_entry_compressedsize" u="int zip_entry_compressedsize(resource zip_entry)">Return the compressed size of a ZZip entry</s>
+<s f="zip_entry_compressionmethod" u="string zip_entry_compressionmethod(resource zip_entry)">Return a string containing the compression method used on a particular entry</s>
+<s f="zip_entry_filesize" u="int zip_entry_filesize(resource zip_entry)">Return the actual filesize of a ZZip entry</s>
+<s f="zip_entry_name" u="string zip_entry_name(resource zip_entry)">Return the name given a ZZip entry</s>
+<s f="zip_entry_open" u="bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])">Open a Zip File, pointed by the resource entry</s>
+<s f="zip_entry_read" u="mixed zip_entry_read(resource zip_entry [, int len])">Read from an open directory entry</s>
+<s f="zip_open" u="resource zip_open(string filename)">Create new zip using source uri for output</s>
+<s f="zip_read" u="resource zip_read(resource zip)">Returns the next file in the archive</s>
+<s f="gzcompress" u="binary gzcompress(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_DEFLATE])">Encode data with the zlib encoding</s>
+<s f="gzdecode" u="binary gzdecode(binary data[, int max_decoded_len])">Decode gzip encoded data</s>
+<s f="gzdeflate" u="binary gzdeflate(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_RAW])">Encode data with the raw deflate encoding</s>
+<s f="gzencode" u="binary gzencode(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_GZIP])">Encode data with the gzip encoding</s>
+<s f="gzfile" u="array gzfile(string filename [, int use_include_path])">Read and uncompress entire .gz-file into an array</s>
+<s f="gzinflate" u="binary gzinflate(binary data[, int max_decoded_len])">Decode raw deflate encoded data</s>
+<s f="gzopen" u="resource gzopen(string filename, string mode [, int use_include_path])">Open a .gz-file and return a .gz-file pointer</s>
+<s f="gzuncompress" u="binary gzuncompress(binary data[, int max_decoded_len])">Decode zlib encoded data</s>
+<s f="readgzfile" u="int readgzfile(string filename [, int use_include_path])">Output a .gz-file</s>
+<s f="zlib_decode" u="binary zlib_decode(binary data[, int max_decoded_len])">Uncompress any raw/gzip/zlib encoded data</s>
+<s f="zlib_encode" u="binary zlib_encode(binary data, int encoding[, int level = -1])">Compress data with the specified encoding</s>
+<s f="zlib_get_coding_type" u="string zlib_get_coding_type(void)">Returns the coding type used for output compression</s>
+<s f="set_time_limit" u="bool set_time_limit(int seconds)">Sets the maximum time a script can run</s>
+<s f="ob_clean" u="bool ob_clean(void)">Clean (delete) the current output buffer</s>
+<s f="ob_end_clean" u="bool ob_end_clean(void)">Clean the output buffer, and delete current output buffer</s>
+<s f="ob_end_flush" u="bool ob_end_flush(void)">Flush (send) the output buffer, and delete current output buffer</s>
+<s f="ob_flush" u="bool ob_flush(void)">Flush (send) contents of the output buffer. The last buffer content is sent to next buffer</s>
+<s f="ob_get_clean" u="bool ob_get_clean(void)">Get current buffer contents and delete current output buffer</s>
+<s f="ob_get_contents" u="string ob_get_contents(void)">Return the contents of the output buffer</s>
+<s f="ob_get_flush" u="bool ob_get_flush(void)">Get current buffer contents, flush (send) the output buffer, and delete current output buffer</s>
+<s f="ob_get_length" u="int ob_get_length(void)">Return the length of the output buffer</s>
+<s f="ob_get_level" u="int ob_get_level(void)">Return the nesting level of the output buffer</s>
+<s f="ob_implicit_flush" u="void ob_implicit_flush([int flag])">Turn implicit flush on/off and is equivalent to calling flush() after every output call</s>
+<s f="ob_start" u="bool ob_start([string|array user_function [, int chunk_size [, int flags]]])">Turn on Output Buffering (specifying an optional output handler).</s>
+<s f="output_add_rewrite_var" u="bool output_add_rewrite_var(string name, string value)">Add URL rewriter values</s>
+<s f="output_reset_rewrite_vars" u="bool output_reset_rewrite_vars(void)">Reset(clear) URL rewriter values</s>
+<s f="stream_wrapper_register" u="bool stream_wrapper_register(string protocol, string classname)">Registers a custom URL protocol handler class</s>
+<s f="stream_wrapper_restore" u="bool stream_wrapper_restore(string protocol)">Restore the original protocol handler, overriding if necessary</s>
+<s f="stream_wrapper_unregister" u="bool stream_wrapper_unregister(string protocol)">Unregister a wrapper for the life of the current request.</s>
+<s f="apache_child_terminate" u="bool apache_child_terminate(void)">Terminate apache process after this request</s>
+<s f="apache_get_modules" u="array apache_get_modules(void)">Get a list of loaded Apache modules</s>
+<s f="apache_get_version" u="string apache_get_version(void)">Fetch Apache version</s>
+<s f="apache_lookup_uri" u="object apache_lookup_uri(string URI)">Perform a partial request of the given URI to obtain information about it</s>
+<s f="apache_note" u="string apache_note(string note_name [, string note_value])">Get and set Apache request notes</s>
+<s f="apache_request_headers" u="array apache_request_headers(void)">Fetch all HTTP request headers</s>
+<s f="apache_reset_timeout" u="bool apache_reset_timeout(void)">Reset the Apache write timer</s>
+<s f="apache_response_headers" u="array apache_response_headers(void)">Fetch all HTTP response headers</s>
+<s f="apache_setenv" u="bool apache_setenv(string variable, string value [, bool walk_to_top])">Set an Apache subprocess_env variable</s>
+<s f="getallheaders" u="array getallheaders(void)">Alias for apache_request_headers()</s>
+<s f="virtual" u="bool virtual(string filename)">Perform an Apache sub-request</s>
+<s f="apache_get_modules" u="array apache_get_modules(void)">Get a list of loaded Apache modules</s>
+<s f="apache_get_version" u="string apache_get_version(void)">Fetch Apache version</s>
+<s f="apache_getenv" u="bool apache_getenv(string variable [, bool walk_to_top])">Get an Apache subprocess_env variable</s>
+<s f="apache_note" u="string apache_note(string note_name [, string note_value])">Get and set Apache request notes</s>
+<s f="apache_response_headers" u="array apache_response_headers(void)">Fetch all HTTP response headers</s>
+<s f="apache_setenv" u="bool apache_setenv(string variable, string value [, bool walk_to_top])">Set an Apache subprocess_env variable</s>
+<s f="getallheaders" u="array getallheaders(void)">Fetch all HTTP request headers</s>
+<s f="virtual" u="bool virtual(string uri)">Perform an apache sub-request</s>
+<s f="apache_get_modules" u="array apache_get_modules(void)">Get a list of loaded Apache modules</s>
+<s f="apache_get_version" u="string apache_get_version(void)">Fetch Apache version</s>
+<s f="apache_getenv" u="bool apache_getenv(string variable [, bool walk_to_top])">Get an Apache subprocess_env variable</s>
+<s f="apache_note" u="string apache_note(string note_name [, string note_value])">Get and set Apache request notes</s>
+<s f="apache_response_headers" u="array apache_response_headers(void)">Fetch all HTTP response headers</s>
+<s f="apache_setenv" u="bool apache_setenv(string variable, string value [, bool walk_to_top])">Set an Apache subprocess_env variable</s>
+<s f="getallheaders" u="array getallheaders(void)">Fetch all HTTP request headers</s>
+<s f="virtual" u="bool virtual(string uri)">Perform an apache sub-request</s>
+<s f="ApacheRequest::allowed" u="int ApacheRequest::allowed([int allowed])"></s>
+<s f="ApacheRequest::args" u="string ApacheRequest::args([string new_args])"></s>
+<s f="ApacheRequest::assbackwards" u="int ApacheRequest::assbackwards()"></s>
+<s f="ApacheRequest::boundary" u="string ApacheRequest::boundary()"></s>
+<s f="ApacheRequest::bytes_sent" u="int ApacheRequest::bytes_sent()"></s>
+<s f="ApacheRequest::chunked" u="int ApacheRequest::chunked()"></s>
+<s f="ApacheRequest::content_encoding" u="string ApacheRequest::content_encoding([string new_encoding])"></s>
+<s f="ApacheRequest::content_length" u="int ApacheRequest::content_length([int new_content_length])"></s>
+<s f="ApacheRequest::content_type" u="string ApacheRequest::content_type([string new_type])"></s>
+<s f="ApacheRequest::filename" u="string ApacheRequest::filename([string new_filename])"></s>
+<s f="ApacheRequest::handler" u="string ApacheRequest::handler([string new_handler])"></s>
+<s f="ApacheRequest::header_only" u="int ApacheRequest::header_only()"></s>
+<s f="ApacheRequest::hostname" u="string ApacheRequest::hostname()"></s>
+<s f="ApacheRequest::method" u="string ApacheRequest::method()"></s>
+<s f="ApacheRequest::method_number" u="int ApacheRequest::method_number([int method_number])"></s>
+<s f="ApacheRequest::mtime" u="int ApacheRequest::mtime()"></s>
+<s f="ApacheRequest::no_cache" u="int ApacheRequest::no_cache()"></s>
+<s f="ApacheRequest::no_local_copy" u="int ApacheRequest::no_local_copy()"></s>
+<s f="ApacheRequest::path_info" u="string ApacheRequest::path_info([string new_path_info])"></s>
+<s f="ApacheRequest::proto_num" u="int ApacheRequest::proto_num()"></s>
+<s f="ApacheRequest::protocol" u="string ApacheRequest::protocol()"></s>
+<s f="ApacheRequest::proxyreq" u="int ApacheRequest::proxyreq([int new_proxyreq])"></s>
+<s f="ApacheRequest::read_body" u="int ApacheRequest::read_body()"></s>
+<s f="ApacheRequest::remaining" u="int ApacheRequest::remaining()"></s>
+<s f="ApacheRequest::request_time" u="int ApacheRequest::request_time()"></s>
+<s f="ApacheRequest::status" u="int ApacheRequest::status([int new_status])"></s>
+<s f="ApacheRequest::status_line" u="string ApacheRequest::status_line([string new_status_line])"></s>
+<s f="ApacheRequest::the_request" u="string ApacheRequest::the_request()"></s>
+<s f="ApacheRequest::unparsed_uri" u="string ApacheRequest::unparsed_uri([string new_unparsed_uri])"></s>
+<s f="ApacheRequest::uri" u="string ApacheRequest::uri([string new_uri])"></s>
+<s f="apache_child_terminate" u="bool apache_child_terminate(void)">Terminate apache process after this request</s>
+<s f="apache_get_modules" u="array apache_get_modules(void)">Get a list of loaded Apache modules</s>
+<s f="apache_get_version" u="string apache_get_version(void)">Fetch Apache version</s>
+<s f="apache_lookup_uri" u="object apache_lookup_uri(string URI)">Perform a partial request of the given URI to obtain information about it</s>
+<s f="apache_note" u="string apache_note(string note_name [, string note_value])">Get and set Apache request notes</s>
+<s f="apache_request_auth_name" u="string apache_request_auth_name()"></s>
+<s f="apache_request_auth_type" u="string apache_request_auth_type()"></s>
+<s f="apache_request_discard_request_body" u="long apache_request_discard_request_body()"></s>
+<s f="apache_request_err_headers_out" u="array apache_request_err_headers_out([{string name|array list} [, string value [, bool replace = false]]])">* fetch all headers that go out in case of an error or a subrequest</s>
+<s f="apache_request_headers" u="array apache_request_headers(void)">Fetch all HTTP request headers</s>
+<s f="apache_request_headers_in" u="array apache_request_headers_in()">* fetch all incoming request headers</s>
+<s f="apache_request_headers_out" u="array apache_request_headers_out([{string name|array list} [, string value [, bool replace = false]]])">* fetch all outgoing request headers</s>
+<s f="apache_request_is_initial_req" u="bool apache_request_is_initial_req()"></s>
+<s f="apache_request_log_error" u="boolean apache_request_log_error(string message, [long facility])"></s>
+<s f="apache_request_meets_conditions" u="long apache_request_meets_conditions()"></s>
+<s f="apache_request_remote_host" u="int apache_request_remote_host([int type])"></s>
+<s f="apache_request_run" u="long apache_request_run()">This is a wrapper for ap_sub_run_req and ap_destory_sub_req.  It takes      sub_request, runs it, destroys it, and returns it's status.</s>
+<s f="apache_request_satisfies" u="long apache_request_satisfies()"></s>
+<s f="apache_request_server_port" u="int apache_request_server_port()"></s>
+<s f="apache_request_set_etag" u="void apache_request_set_etag()"></s>
+<s f="apache_request_set_last_modified" u="void apache_request_set_last_modified()"></s>
+<s f="apache_request_some_auth_required" u="bool apache_request_some_auth_required()"></s>
+<s f="apache_request_sub_req_lookup_file" u="object apache_request_sub_req_lookup_file(string file)">Returns sub-request for the specified file.  You would     need to run it yourself with run().</s>
+<s f="apache_request_sub_req_lookup_uri" u="object apache_request_sub_req_lookup_uri(string uri)">Returns sub-request for the specified uri.  You would     need to run it yourself with run()</s>
+<s f="apache_request_sub_req_method_uri" u="object apache_request_sub_req_method_uri(string method, string uri)">Returns sub-request for the specified file.  You would     need to run it yourself with run().</s>
+<s f="apache_request_update_mtime" u="long apache_request_update_mtime([int dependency_mtime])"></s>
+<s f="apache_response_headers" u="array apache_response_headers(void)">Fetch all HTTP response headers</s>
+<s f="apache_setenv" u="bool apache_setenv(string variable, string value [, bool walk_to_top])">Set an Apache subprocess_env variable</s>
+<s f="getallheaders" u="array getallheaders(void)"></s>
+<s f="virtual" u="bool virtual(string filename)">Perform an Apache sub-request</s>
+<s f="smfi_addheader" u="bool smfi_addheader(string headerf, string headerv)">Adds a header to the current message.</s>
+<s f="smfi_addrcpt" u="bool smfi_addrcpt(string rcpt)">Add a recipient to the message envelope.</s>
+<s f="smfi_chgheader" u="bool smfi_chgheader(string headerf, string headerv)">Changes a header's value for the current message.</s>
+<s f="smfi_delrcpt" u="bool smfi_delrcpt(string rcpt)">Removes the named recipient from the current message's envelope.</s>
+<s f="smfi_getsymval" u="string smfi_getsymval(string macro)">Returns the value of the given macro or NULL if the macro is not defined.</s>
+<s f="smfi_replacebody" u="bool smfi_replacebody(string body)">Replaces the body of the current message. If called more than once,    subsequent calls result in data being appended to the new body.</s>
+<s f="smfi_setflags" u="void smfi_setflags(long flags)">Sets the flags describing the actions the filter may take.</s>
+<s f="smfi_setreply" u="bool smfi_setreply(string rcode, string xcode, string message)">Directly set the SMTP error reply code for this connection.    This code will be used on subsequent error replies resulting from actions taken by this filter.</s>
+<s f="smfi_settimeout" u="void smfi_settimeout(long timeout)">Sets the number of seconds libmilter will wait for an MTA connection before timing out a socket.</s>
+<s f="nsapi_request_headers" u="array nsapi_request_headers(void)">Get all headers from the request</s>
+<s f="nsapi_response_headers" u="array nsapi_response_headers(void)">Get all headers from the response</s>
+<s f="nsapi_virtual" u="bool nsapi_virtual(string uri)">Perform an NSAPI sub-request</s>
+<s f="display_disabled_function" u="void display_disabled_function(void)">Dummy function which displays an error when a disabled function is called.</s>
+<s f="class_exists" u="bool class_exists(string classname [, bool autoload])">Checks if the class exists</s>
+<s f="crash" u="void crash(void)">Cause the process to crash by copying data to an inaccesible location</s>
+<s f="create_function" u="string create_function(string args, string code)">Creates an anonymous function, and returns its name (funny, eh?)</s>
+<s f="debug_backtrace" u="array debug_backtrace(void)">Return backtrace as array</s>
+<s f="define" u="bool define(string constant_name, mixed value, boolean case_sensitive=true)">Define a new constant</s>
+<s f="defined" u="bool defined(string constant_name)">Check whether a constant exists</s>
+<s f="each" u="array each(array arr)">Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element</s>
+<s f="error_reporting" u="int error_reporting(int new_error_level=null)">Return the current error_reporting level, and if an argument was passed - change to the new level</s>
+<s f="extension_loaded" u="bool extension_loaded(string extension_name)">Returns true if the named extension is loaded</s>
+<s f="func_get_arg" u="mixed func_get_arg(int arg_num)">Get the $arg_num'th argument that was passed to the function</s>
+<s f="func_get_args" u="array func_get_args()">Get an array of the arguments that were passed to the function</s>
+<s f="func_num_args" u="int func_num_args(void)">Get the number of arguments that were passed to the function</s>
+<s f="function_exists" u="bool function_exists(string function_name)">Checks if the function exists</s>
+<s f="get_class" u="string get_class([object object])">Retrieves the class name</s>
+<s f="get_class_methods" u="array get_class_methods(mixed class)">Returns an array of method names for class or class instance.</s>
+<s f="get_class_vars" u="array get_class_vars(string class_name)">Returns an array of default properties of the class.</s>
+<s f="get_declared_classes" u="array get_declared_classes()">Returns an array of all declared classes.</s>
+<s f="get_declared_interfaces" u="array get_declared_interfaces()">Returns an array of all declared interfaces.</s>
+<s f="get_defined_constants" u="array get_defined_constants([bool categorize])">Return an array containing the names and values of all defined constants</s>
+<s f="get_defined_functions" u="array get_defined_functions(void)">Returns an array of all defined functions</s>
+<s f="get_defined_vars" u="array get_defined_vars(void)">Returns an associative array of names and values of all currently defined variable names (variables in the current scope)</s>
+<s f="get_extension_funcs" u="array get_extension_funcs(string extension_name)">Returns an array with the names of functions belonging to the named extension</s>
+<s f="get_included_files" u="array get_included_files(void)">Returns an array with the file names that were included (includes require and once varieties)</s>
+<s f="get_loaded_extensions" u="array get_loaded_extensions([bool zend_extensions])">Return an array containing names of loaded extensions</s>
+<s f="get_object_vars" u="array get_object_vars(object obj)">Returns an array of object properties</s>
+<s f="get_parent_class" u="string get_parent_class([mixed object])">Retrieves the parent class name for object or class or current scope.</s>
+<s f="get_resource_type" u="string get_resource_type(resource res)">Get the resource type name for a given resource</s>
+<s f="interface_exists" u="bool interface_exists(string classname [, bool autoload])">Checks if the class exists</s>
+<s f="is_a" u="bool is_a(object object, string class_name)">Returns true if the object is of this class or has this class as one of its parents</s>
+<s f="is_subclass_of" u="bool is_subclass_of(object object, string class_name)">Returns true if the object has this class as one of its parents</s>
+<s f="leak" u="void leak(int num_bytes=3)">Cause an intentional memory leak, for testing/debugging purposes</s>
+<s f="method_exists" u="bool method_exists(object object, string method)">Checks if the class method exists</s>
+<s f="property_exists" u="bool property_exists(mixed object_or_class, string property_name)">Checks if the object or class has a property</s>
+<s f="restore_error_handler" u="void restore_error_handler(void)">Restores the previously defined error handler function</s>
+<s f="restore_exception_handler" u="void restore_exception_handler(void)">Restores the previously defined exception handler function</s>
+<s f="set_error_handler" u="string set_error_handler(string error_handler [, int error_types])">Sets a user-defined error handler function.  Returns the previously defined error handler, or false on error</s>
+<s f="set_exception_handler" u="string set_exception_handler(callable exception_handler)">Sets a user-defined exception handler function.  Returns the previously defined exception handler, or false on error</s>
+<s f="strcasecmp" u="int strcasecmp(string str1, string str2)">Binary safe case-insensitive string comparison</s>
+<s f="strcmp" u="int strcmp(string str1, string str2)">Binary safe string comparison</s>
+<s f="strlen" u="int strlen(string str)">Get string length</s>
+<s f="strncasecmp" u="int strncasecmp(string str1, string str2, int len)">Binary safe string comparison</s>
+<s f="strncmp" u="int strncmp(string str1, string str2, int len)">Binary safe string comparison</s>
+<s f="trigger_error" u="void trigger_error(string messsage [, int error_type])">Generates a user-level error/warning/notice message</s>
+<s f="zend_test_func" u="void zend_test_func(mixed arg1, mixed arg2)">Generic test function</s>
+<s f="zend_thread_id" u="int zend_thread_id(void)">Returns a unique identifier for the current thread</s>
+<s f="zend_version" u="string zend_version(void)">Get the version of the Zend Engine</s>
+<s f="ErrorException::getSeverity" u="int ErrorException::getSeverity()">Get the exception severity</s>
+<s f="Exception::__clone" u="Exception Exception::__clone()">Clone the exception object</s>
+<s f="Exception::__toString" u="string Exception::__toString()">Obtain the string representation of the Exception object</s>
+<s f="Exception::getCode" u="int Exception::getCode()">Get the exception code</s>
+<s f="Exception::getFile" u="string Exception::getFile()">Get the file in which the exception occurred</s>
+<s f="Exception::getLine" u="int Exception::getLine()">Get the line in which the exception occurred</s>
+<s f="Exception::getMessage" u="string Exception::getMessage()">Get the exception message</s>
+<s f="Exception::getTrace" u="array Exception::getTrace()">Get the stack trace for the location in which the exception occurred</s>
+<s f="Exception::getTraceAsString" u="string Exception::getTraceAsString()">Obtain the backtrace for the exception as a string (instead of an array)</s>
+<s f="Exception::__construct" u=" Exception::__construct(string message, int code)">Exception constructor</s>
+<s f="ErrorException::__construct" u=" ErrorException::__construct(string message, int code, int severity [, string filename [, int lineno]])">ErrorException constructor</s>
+<s f="__construct" u="([ mixed $args  [,  $...  ]] )">PHP 5 allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.</s><s f="__destruct" u="( void  )">PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence.</s><s k="abstract" />
+<s k="and" />
+<s k="array" />
+<s k="as" />
+<s k="break" />
+<s k="case" />
+<s k="catch" />
+<s k="class" />
+<s k="clone" />
+<s k="const" />
+<s k="continue" />
+<s k="declare" />
+<s k="default" />
+<s k="do" />
+<s k="else" />
+<s k="elseif" />
+<s k="enddeclare" />
+<s k="endfor" />
+<s k="endforeach" />
+<s k="endif" />
+<s k="endswitch" />
+<s k="endwhile" />
+<s k="extends" />
+<s k="final" />
+<s k="for" />
+<s k="function" />
+<s k="global" />
+<s k="goto" />
+<s k="if" />
+<s k="implements" />
+<s k="interface" />
+<s k="instanceof" />
+<s k="namespace" />
+<s k="new" />
+<s k="or" />
+<s k="private" />
+<s k="protected" />
+<s k="public" />
+<s k="static" />
+<s k="switch" />
+<s k="throw" />
+<s k="try" />
+<s k="use" />
+<s k="var" />
+<s k="while" />
+<s k="xor" />
+<s k="true" />
+<s k="TRUE" />
+<s k="false" />
+<s k="FALSE" />
+<s k="null" />
+<s k="NULL" />
+<s k="static" />
+<s k="parent" />
+<s k="include" />
+<s k="include_once" />
+<s k="require" />
+<s k="require_once" />
+<s k="die" />
+<s k="exit" />
+<s k="print" />
+<s t="string"/>
+<s t="object"/>
+<s t="bool"/>
+<s t="boolean"/>
+<s t="unicode"/>
+<s t="double"/>
+<s t="float"/>
+<s t="array" />
+<s t="resource" />
+<s t="int"/>
+<s t="integer"/>
+<s c="M_PI">3.14159265358979323846</s>
+<s c="M_E">2.7182818284590452354</s>
+<s c="M_LOG2E">1.4426950408889634074</s>
+<s c="M_LOG10E">0.43429448190325182765</s>
+<s c="M_LN2">0.69314718055994530942</s>
+<s c="M_LN10">2.30258509299404568402</s>
+<s c="M_PI_2">1.57079632679489661923</s>
+<s c="M_PI_4">0.78539816339744830962</s>
+<s c="M_1_PI">0.31830988618379067154</s>
+<s c="M_2_PI">0.63661977236758134308</s>
+<s c="M_SQRTPI">1.77245385090551602729</s>
+<s c="M_2_SQRTPI">1.12837916709551257390</s>
+<s c="M_SQRT2">1.41421356237309504880</s>
+<s c="M_SQRT3">1.73205080756887729352</s>
+<s c="M_SQRT1_2">0.70710678118654752440</s>
+<s c="M_LNPI">1.14472988584940017414</s>
+<s c="M_EULER">0.57721566490153286061</s>
+<s c="PHP_ROUND_HALF_UP">1</s>
+<s c="PHP_ROUND_HALF_DOWN">2</s>
+<s c="PHP_ROUND_HALF_EVEN">3</s>
+<s c="PHP_ROUND_HALF_ODD">4</s>
+<s c="HTTP_SUPPORT" />
+<s c="HTTP_SUPPORT_REQUESTS" />
+<s c="HTTP_SUPPORT_MAGICMIME" />
+<s c="HTTP_SUPPORT_ENCODINGS" />
+<s c="HTTP_SUPPORT_SSLREQUESTS" />
+<s c="HTTP_PARAMS_ALLOW_COMMA" />
+<s c="HTTP_PARAMS_ALLOW_FAILURE" />
+<s c="HTTP_PARAMS_RAISE_ERROR" />
+<s c="HTTP_PARAMS_DEFAULT" />
+<s c="HTTP_COOKIE_PARSE_RAW" />
+<s c="HTTP_COOKIE_SECURE" />
+<s c="HTTP_COOKIE_HTTPONLY" />
+<s c="HTTP_DEFLATE_LEVEL_DEF" />
+<s c="HTTP_DEFLATE_LEVEL_MIN" />
+<s c="HTTP_DEFLATE_LEVEL_MAX" />
+<s c="HTTP_DEFLATE_TYPE_ZLIB" />
+<s c="HTTP_DEFLATE_TYPE_GZIP" />
+<s c="HTTP_DEFLATE_TYPE_RAW" />
+<s c="HTTP_DEFLATE_STRATEGY_DEF" />
+<s c="HTTP_DEFLATE_STRATEGY_FILT" />
+<s c="HTTP_DEFLATE_STRATEGY_HUFF" />
+<s c="HTTP_DEFLATE_STRATEGY_RLE" />
+<s c="HTTP_DEFLATE_STRATEGY_FIXED" />
+<s c="HTTP_ENCODING_STREAM_FLUSH_NONE" />
+<s c="HTTP_ENCODING_STREAM_FLUSH_SYNC" />
+<s c="HTTP_ENCODING_STREAM_FLUSH_FULL" />
+<s c="HTTP_E_RUNTIME" />
+<s c="HTTP_E_INVALID_PARAM" />
+<s c="HTTP_E_HEADER" />
+<s c="HTTP_E_MALFORMED_HEADERS" />
+<s c="HTTP_E_REQUEST_METHOD" />
+<s c="HTTP_E_MESSAGE_TYPE" />
+<s c="HTTP_E_ENCODING" />
+<s c="HTTP_E_REQUEST" />
+<s c="HTTP_E_REQUEST_POOL" />
+<s c="HTTP_E_SOCKET" />
+<s c="HTTP_E_RESPONSE" />
+<s c="HTTP_E_URL" />
+<s c="HTTP_E_QUERYSTRING" />
+<s c="HTTP_MSG_NONE" />
+<s c="HTTP_MSG_REQUEST" />
+<s c="HTTP_MSG_RESPONSE" />
+<s c="HTTP_QUERYSTRING_TYPE_BOOL" />
+<s c="HTTP_QUERYSTRING_TYPE_INT" />
+<s c="HTTP_QUERYSTRING_TYPE_FLOAT" />
+<s c="HTTP_QUERYSTRING_TYPE_STRING" />
+<s c="HTTP_QUERYSTRING_TYPE_ARRAY" />
+<s c="HTTP_QUERYSTRING_TYPE_OBJECT" />
+<s c="HTTP_AUTH_BASIC" />
+<s c="HTTP_AUTH_DIGEST" />
+<s c="HTTP_AUTH_NTLM" />
+<s c="HTTP_AUTH_GSSNEG" />
+<s c="HTTP_AUTH_ANY" />
+<s c="HTTP_VERSION_ANY" />
+<s c="HTTP_VERSION_1_0" />
+<s c="HTTP_VERSION_1_1" />
+<s c="HTTP_SSL_VERSION_ANY" />
+<s c="HTTP_SSL_VERSION_TLSv1" />
+<s c="HTTP_SSL_VERSION_SSLv3" />
+<s c="HTTP_SSL_VERSION_SSLv2" />
+<s c="HTTP_PROXY_SOCKS4" />
+<s c="HTTP_PROXY_SOCKS5" />
+<s c="HTTP_PROXY_HTTP" />
+<s c="HTTP_IPRESOLVE_V4" />
+<s c="HTTP_IPRESOLVE_V6" />
+<s c="HTTP_IPRESOLVE_ANY" />
+<s c="HTTP_METH_GET" />
+<s c="HTTP_METH_HEAD" />
+<s c="HTTP_METH_POST" />
+<s c="HTTP_METH_PUT" />
+<s c="HTTP_METH_DELETE" />
+<s c="HTTP_METH_OPTIONS" />
+<s c="HTTP_METH_TRACE" />
+<s c="HTTP_METH_CONNECT" />
+<s c="HTTP_METH_PROPFIND" />
+<s c="HTTP_METH_PROPPATCH" />
+<s c="HTTP_METH_MKCOL" />
+<s c="HTTP_METH_COPY" />
+<s c="HTTP_METH_MOVE" />
+<s c="HTTP_METH_LOCK" />
+<s c="HTTP_METH_UNLOCK" />
+<s c="HTTP_METH_VERSION_CONTROL" />
+<s c="HTTP_METH_REPORT" />
+<s c="HTTP_METH_CHECKOUT" />
+<s c="HTTP_METH_CHECKIN" />
+<s c="HTTP_METH_UNCHECKOUT" />
+<s c="HTTP_METH_MKWORKSPACE" />
+<s c="HTTP_METH_UPDATE" />
+<s c="HTTP_METH_LABEL" />
+<s c="HTTP_METH_MERGE" />
+<s c="HTTP_METH_BASELINE_CONTROL" />
+<s c="HTTP_METH_MKACTIVITY" />
+<s c="HTTP_METH_ACL" />
+<s c="HTTP_REDIRECT" />
+<s c="HTTP_REDIRECT_PERM" />
+<s c="HTTP_REDIRECT_FOUND" />
+<s c="HTTP_REDIRECT_POST" />
+<s c="HTTP_REDIRECT_PROXY" />
+<s c="HTTP_REDIRECT_TEMP" />
+<s c="HTTP_URL_REPLACE" />
+<s c="HTTP_URL_JOIN_PATH" />
+<s c="HTTP_URL_JOIN_QUERY" />
+<s c="HTTP_URL_STRIP_USER" />
+<s c="HTTP_URL_STRIP_PASS" />
+<s c="HTTP_URL_STRIP_AUTH" />
+<s c="HTTP_URL_STRIP_PORT" />
+<s c="HTTP_URL_STRIP_PATH" />
+<s c="HTTP_URL_STRIP_QUERY" />
+<s c="HTTP_URL_STRIP_FRAGMENT" />
+<s c="HTTP_URL_STRIP_ALL" />
+<s c="PARSEKIT_QUIET" />
+<s c="PARSEKIT_SIMPLE" />
+<s c="PARSEKIT_EXTENDED_VALUE" />
+<s c="PARSEKIT_RESULT_CONST" />
+<s c="PARSEKIT_RESULT_EA_TYPE" />
+<s c="PARSEKIT_RESULT_JMP_ADDR" />
+<s c="PARSEKIT_RESULT_OPARRAY" />
+<s c="PARSEKIT_RESULT_OPLINE" />
+<s c="PARSEKIT_RESULT_VAR" />
+<s c="PARSEKIT_USAGE_UNKNOWN" />
+<s c="PARSEKIT_ZEND_INTERNAL_CLASS" />
+<s c="PARSEKIT_ZEND_USER_CLASS" />
+<s c="PARSEKIT_ZEND_EVAL_CODE" />
+<s c="PARSEKIT_ZEND_INTERNAL_FUNCTION" />
+<s c="PARSEKIT_ZEND_OVERLOADED_FUNCTION" />
+<s c="PARSEKIT_ZEND_OVERLOADED_FUNCTION_TEMPORARY" />
+<s c="PARSEKIT_ZEND_USER_FUNCTION" />
+<s c="PARSEKIT_IS_CONST" />
+<s c="PARSEKIT_IS_TMP_VAR" />
+<s c="PARSEKIT_IS_UNUSED" />
+<s c="PARSEKIT_IS_VAR" />
+<s c="PARSEKIT_ZEND_ADD" />
+<s c="PARSEKIT_ZEND_ADD_ARRAY_ELEMENT" />
+<s c="PARSEKIT_ZEND_ADD_CHAR" />
+<s c="PARSEKIT_ZEND_ADD_INTERFACE" />
+<s c="PARSEKIT_ZEND_ADD_STRING" />
+<s c="PARSEKIT_ZEND_ADD_VAR" />
+<s c="PARSEKIT_ZEND_ASSIGN" />
+<s c="PARSEKIT_ZEND_ASSIGN_ADD" />
+<s c="PARSEKIT_ZEND_ASSIGN_BW_AND" />
+<s c="PARSEKIT_ZEND_ASSIGN_BW_OR" />
+<s c="PARSEKIT_ZEND_ASSIGN_BW_XOR" />
+<s c="PARSEKIT_ZEND_ASSIGN_CONCAT" />
+<s c="PARSEKIT_ZEND_ASSIGN_DIM" />
+<s c="PARSEKIT_ZEND_ASSIGN_DIV" />
+<s c="PARSEKIT_ZEND_ASSIGN_MOD" />
+<s c="PARSEKIT_ZEND_ASSIGN_MUL" />
+<s c="PARSEKIT_ZEND_ASSIGN_OBJ" />
+<s c="PARSEKIT_ZEND_ASSIGN_REF" />
+<s c="PARSEKIT_ZEND_ASSIGN_SL" />
+<s c="PARSEKIT_ZEND_ASSIGN_SR" />
+<s c="PARSEKIT_ZEND_ASSIGN_SUB" />
+<s c="PARSEKIT_ZEND_BEGIN_SILENCE" />
+<s c="PARSEKIT_ZEND_BOOL" />
+<s c="PARSEKIT_ZEND_BOOL_NOT" />
+<s c="PARSEKIT_ZEND_BOOL_XOR" />
+<s c="PARSEKIT_ZEND_BRK" />
+<s c="PARSEKIT_ZEND_BW_AND" />
+<s c="PARSEKIT_ZEND_BW_NOT" />
+<s c="PARSEKIT_ZEND_BW_OR" />
+<s c="PARSEKIT_ZEND_BW_XOR" />
+<s c="PARSEKIT_ZEND_CASE" />
+<s c="PARSEKIT_ZEND_CAST" />
+<s c="PARSEKIT_ZEND_CATCH" />
+<s c="PARSEKIT_ZEND_CLONE" />
+<s c="PARSEKIT_ZEND_CONCAT" />
+<s c="PARSEKIT_ZEND_CONT" />
+<s c="PARSEKIT_ZEND_DECLARE_CLASS" />
+<s c="PARSEKIT_ZEND_DECLARE_FUNCTION" />
+<s c="PARSEKIT_ZEND_DECLARE_INHERITED_CLASS" />
+<s c="PARSEKIT_ZEND_DIV" />
+<s c="PARSEKIT_ZEND_DO_FCALL" />
+<s c="PARSEKIT_ZEND_DO_FCALL_BY_NAME" />
+<s c="PARSEKIT_ZEND_ECHO" />
+<s c="PARSEKIT_ZEND_END_SILENCE" />
+<s c="PARSEKIT_ZEND_EXIT" />
+<s c="PARSEKIT_ZEND_EXT_FCALL_BEGIN" />
+<s c="PARSEKIT_ZEND_EXT_FCALL_END" />
+<s c="PARSEKIT_ZEND_EXT_NOP" />
+<s c="PARSEKIT_ZEND_EXT_STMT" />
+<s c="PARSEKIT_ZEND_FETCH_CLASS" />
+<s c="PARSEKIT_ZEND_FETCH_CONSTANT" />
+<s c="PARSEKIT_ZEND_FETCH_DIM_FUNC_ARG" />
+<s c="PARSEKIT_ZEND_FETCH_DIM_IS" />
+<s c="PARSEKIT_ZEND_FETCH_DIM_R" />
+<s c="PARSEKIT_ZEND_FETCH_DIM_RW" />
+<s c="PARSEKIT_ZEND_FETCH_DIM_TMP_VAR" />
+<s c="PARSEKIT_ZEND_FETCH_DIM_UNSET" />
+<s c="PARSEKIT_ZEND_FETCH_DIM_W" />
+<s c="PARSEKIT_ZEND_FETCH_FUNC_ARG" />
+<s c="PARSEKIT_ZEND_FETCH_IS" />
+<s c="PARSEKIT_ZEND_FETCH_OBJ_FUNC_ARG" />
+<s c="PARSEKIT_ZEND_FETCH_OBJ_IS" />
+<s c="PARSEKIT_ZEND_FETCH_OBJ_R" />
+<s c="PARSEKIT_ZEND_FETCH_OBJ_RW" />
+<s c="PARSEKIT_ZEND_FETCH_OBJ_UNSET" />
+<s c="PARSEKIT_ZEND_FETCH_OBJ_W" />
+<s c="PARSEKIT_ZEND_FETCH_R" />
+<s c="PARSEKIT_ZEND_FETCH_RW" />
+<s c="PARSEKIT_ZEND_FETCH_UNSET" />
+<s c="PARSEKIT_ZEND_FETCH_W" />
+<s c="PARSEKIT_ZEND_FE_FETCH" />
+<s c="PARSEKIT_ZEND_FE_RESET" />
+<s c="PARSEKIT_ZEND_FREE" />
+<s c="PARSEKIT_ZEND_HANDLE_EXCEPTION" />
+<s c="PARSEKIT_ZEND_IMPORT_CLASS" />
+<s c="PARSEKIT_ZEND_IMPORT_CONST" />
+<s c="PARSEKIT_ZEND_IMPORT_FUNCTION" />
+<s c="PARSEKIT_ZEND_INCLUDE_OR_EVAL" />
+<s c="PARSEKIT_ZEND_INIT_ARRAY" />
+<s c="PARSEKIT_ZEND_INIT_CTOR_CALL" />
+<s c="PARSEKIT_ZEND_INIT_FCALL_BY_NAME" />
+<s c="PARSEKIT_ZEND_INIT_METHOD_CALL" />
+<s c="PARSEKIT_ZEND_INIT_STATIC_METHOD_CALL" />
+<s c="PARSEKIT_ZEND_INIT_STRING" />
+<s c="PARSEKIT_ZEND_INSTANCEOF" />
+<s c="PARSEKIT_ZEND_ISSET_ISEMPTY" />
+<s c="PARSEKIT_ZEND_ISSET_ISEMPTY_DIM_OBJ" />
+<s c="PARSEKIT_ZEND_ISSET_ISEMPTY_PROP_OBJ" />
+<s c="PARSEKIT_ZEND_ISSET_ISEMPTY_VAR" />
+<s c="PARSEKIT_ZEND_IS_EQUAL" />
+<s c="PARSEKIT_ZEND_IS_IDENTICAL" />
+<s c="PARSEKIT_ZEND_IS_NOT_EQUAL" />
+<s c="PARSEKIT_ZEND_IS_NOT_IDENTICAL" />
+<s c="PARSEKIT_ZEND_IS_SMALLER" />
+<s c="PARSEKIT_ZEND_IS_SMALLER_OR_EQUAL" />
+<s c="PARSEKIT_ZEND_JMP" />
+<s c="PARSEKIT_ZEND_JMPNZ" />
+<s c="PARSEKIT_ZEND_JMPNZ_EX" />
+<s c="PARSEKIT_ZEND_JMPZ" />
+<s c="PARSEKIT_ZEND_JMPZNZ" />
+<s c="PARSEKIT_ZEND_JMPZ_EX" />
+<s c="PARSEKIT_ZEND_JMP_NO_CTOR" />
+<s c="PARSEKIT_ZEND_MOD" />
+<s c="PARSEKIT_ZEND_MUL" />
+<s c="PARSEKIT_ZEND_NEW" />
+<s c="PARSEKIT_ZEND_NOP" />
+<s c="PARSEKIT_ZEND_OP_DATA" />
+<s c="PARSEKIT_ZEND_POST_DEC" />
+<s c="PARSEKIT_ZEND_POST_DEC_OBJ" />
+<s c="PARSEKIT_ZEND_POST_INC" />
+<s c="PARSEKIT_ZEND_POST_INC_OBJ" />
+<s c="PARSEKIT_ZEND_PRE_DEC" />
+<s c="PARSEKIT_ZEND_PRE_DEC_OBJ" />
+<s c="PARSEKIT_ZEND_PRE_INC" />
+<s c="PARSEKIT_ZEND_PRE_INC_OBJ" />
+<s c="PARSEKIT_ZEND_PRINT" />
+<s c="PARSEKIT_ZEND_QM_ASSIGN" />
+<s c="PARSEKIT_ZEND_RAISE_ABSTRACT_ERROR" />
+<s c="PARSEKIT_ZEND_RECV" />
+<s c="PARSEKIT_ZEND_RECV_INIT" />
+<s c="PARSEKIT_ZEND_RETURN" />
+<s c="PARSEKIT_ZEND_SEND_REF" />
+<s c="PARSEKIT_ZEND_SEND_VAL" />
+<s c="PARSEKIT_ZEND_SEND_VAR" />
+<s c="PARSEKIT_ZEND_SEND_VAR_NO_REF" />
+<s c="PARSEKIT_ZEND_SL" />
+<s c="PARSEKIT_ZEND_SR" />
+<s c="PARSEKIT_ZEND_SUB" />
+<s c="PARSEKIT_ZEND_SWITCH_FREE" />
+<s c="PARSEKIT_ZEND_THROW" />
+<s c="PARSEKIT_ZEND_TICKS" />
+<s c="PARSEKIT_ZEND_UNSET_DIM_OBJ" />
+<s c="PARSEKIT_ZEND_UNSET_VAR" />
+<s c="PARSEKIT_ZEND_VERIFY_ABSTRACT_CLASS" />
+<s c="MOD_COLOR" />
+<s c="MOD_MATRIX" />
+<s c="TYPE_PUSHBUTTON" />
+<s c="TYPE_MENUBUTTON" />
+<s c="BSHitTest" />
+<s c="BSDown" />
+<s c="BSOver" />
+<s c="BSUp" />
+<s c="OverDowntoIdle" />
+<s c="IdletoOverDown" />
+<s c="OutDowntoIdle" />
+<s c="OutDowntoOverDown" />
+<s c="OverDowntoOutDown" />
+<s c="OverUptoOverDown" />
+<s c="OverUptoIdle" />
+<s c="IdletoOverUp" />
+<s c="ButtonEnter" />
+<s c="ButtonExit" />
+<s c="MenuEnter" />
+<s c="MenuExit" />
+<s c="FTP_ASCII" />
+<s c="FTP_TEXT" />
+<s c="FTP_BINARY" />
+<s c="FTP_IMAGE" />
+<s c="FTP_TIMEOUT_SEC" />
+<s c="FTP_AUTOSEEK" />
+<s c="FTP_AUTORESUME" />
+<s c="FTP_FAILED" />
+<s c="FTP_FINISHED" />
+<s c="FTP_MOREDATA" />
+<s c="PHP_URL_SCHEME" />
+<s c="PHP_URL_HOST" />
+<s c="PHP_URL_PORT" />
+<s c="PHP_URL_USER" />
+<s c="PHP_URL_PASS" />
+<s c="PHP_URL_PATH" />
+<s c="PHP_URL_QUERY" />
+<s c="PHP_URL_FRAGMENT" />
+<s c="CONNECTION_ABORTED" />
+<s c="CONNECTION_NORMAL" />
+<s c="CONNECTION_TIMEOUT" />
+<s c="__COMPILER_HALT_OFFSET__" />
+<s c="SSH2_FINGERPRINT_MD5" />
+<s c="SSH2_FINGERPRINT_SHA1" />
+<s c="SSH2_FINGERPRINT_HEX" />
+<s c="SSH2_FINGERPRINT_RAW" />
+<s c="SSH2_TERM_UNIT_CHARS" />
+<s c="SSH2_TERM_UNIT_PIXELS" />
+<s c="SSH2_DEFAULT_TERM_WIDTH" />
+<s c="SSH2_DEFAULT_TERM_HEIGHT" />
+<s c="SSH2_DEFAULT_TERM_UNIT" />
+<s c="SSH2_STREAM_STDIO" />
+<s c="SSH2_STREAM_STDERR" />
+<s c="SSH2_DEFAULT_TERMINAL" />
+<s c="HASH_HMAC" />
+<s c="GOPHER_DOCUMENT" /> 
+<s c="GOPHER_DIRECTORY">1</s>
+<s c="GOPHER_BINHEX">4</s>
+<s c="GOPHER_DOSBINARY">5</s>
+<s c="GOPHER_UUENCODED">6</s>
+<s c="GOPHER_BINARY">9</s>
+<s c="GOPHER_INFO">255</s>
+<s c="GOPHER_HTTP">254</s>
+<s c="GOPHER_UNKNOWN">-1</s>
+<s c="U_INVALID_STOP" /> 
+<s c="U_INVALID_SKIP">1</s>
+<s c="U_INVALID_SUBSTITUTE">2</s>
+<s c="U_INVALID_ESCAPE">3</s>
+<s c="PRINTER_COPIES" />
+<s c="PRINTER_MODE" />
+<s c="PRINTER_TITLE" />
+<s c="PRINTER_DEVICENAME" />
+<s c="PRINTER_DRIVERVERSION" />
+<s c="PRINTER_OUTPUT_FILE" />
+<s c="PRINTER_RESOLUTION_Y" />
+<s c="PRINTER_RESOLUTION_X" />
+<s c="PRINTER_SCALE" />
+<s c="PRINTER_BACKGROUND_COLOR" />
+<s c="PRINTER_PAPER_LENGTH" />
+<s c="PRINTER_PAPER_WIDTH" />
+<s c="PRINTER_PAPER_FORMAT" />
+<s c="PRINTER_FORMAT_CUSTOM" />
+<s c="PRINTER_FORMAT_LETTER" />
+<s c="PRINTER_FORMAT_LEGAL" />
+<s c="PRINTER_FORMAT_A3" />
+<s c="PRINTER_FORMAT_A4" />
+<s c="PRINTER_FORMAT_A5" />
+<s c="PRINTER_FORMAT_B4" />
+<s c="PRINTER_FORMAT_B5" />
+<s c="PRINTER_FORMAT_FOLIO" />
+<s c="PRINTER_ORIENTATION" />
+<s c="PRINTER_ORIENTATION_PORTRAIT" />
+<s c="PRINTER_ORIENTATION_LANDSCAPE" />
+<s c="PRINTER_TEXT_COLOR" />
+<s c="PRINTER_TEXT_ALIGN" />
+<s c="PRINTER_TA_BASELINE" />
+<s c="PRINTER_TA_BOTTOM" />
+<s c="PRINTER_TA_TOP" />
+<s c="PRINTER_TA_CENTER" />
+<s c="PRINTER_TA_LEFT" />
+<s c="PRINTER_TA_RIGHT" />
+<s c="PRINTER_PEN_SOLID" />
+<s c="PRINTER_PEN_DASH" />
+<s c="PRINTER_PEN_DOT" />
+<s c="PRINTER_PEN_DASHDOT" />
+<s c="PRINTER_PEN_DASHDOTDOT" />
+<s c="PRINTER_PEN_INVISIBLE" />
+<s c="PRINTER_BRUSH_SOLID" />
+<s c="PRINTER_BRUSH_CUSTOM" />
+<s c="PRINTER_BRUSH_DIAGONAL" />
+<s c="PRINTER_BRUSH_CROSS" />
+<s c="PRINTER_BRUSH_DIAGCROSS" />
+<s c="PRINTER_BRUSH_FDIAGONAL" />
+<s c="PRINTER_BRUSH_HORIZONTAL" />
+<s c="PRINTER_BRUSH_VERTICAL" />
+<s c="PRINTER_FW_THIN" />
+<s c="PRINTER_FW_ULTRALIGHT" />
+<s c="PRINTER_FW_LIGHT" />
+<s c="PRINTER_FW_NORMAL" />
+<s c="PRINTER_FW_MEDIUM" />
+<s c="PRINTER_FW_BOLD" />
+<s c="PRINTER_FW_ULTRABOLD" />
+<s c="PRINTER_FW_HEAVY" />
+<s c="PRINTER_ENUM_LOCAL" />
+<s c="PRINTER_ENUM_NAME" />
+<s c="PRINTER_ENUM_SHARED" />
+<s c="PRINTER_ENUM_DEFAULT" />
+<s c="PRINTER_ENUM_CONNECTIONS" />
+<s c="PRINTER_ENUM_NETWORK" />
+<s c="PRINTER_ENUM_REMOTE" />
+<s c="PKCS7_TEXT">Adds text/plain content type headers to encrypted/signed message. If decrypting or verifying, it strips those headers from the output - if the decrypted or verified message is not of MIME type text/plain then an error will occur.</s>
+<s c="PKCS7_BINARY">Normally the input message is converted to &quot;canonical&quot; format which is effectively using CR and LF as end of line: as required by the S/MIME specification. When this options is present, no translation occurs. This is useful when handling binary data which may not be in MIME format.</s>
+<s c="PKCS7_NOINTERN">When verifying a message, certificates (if any) included in the message are normally searched for the signing certificate. With this option only the certificates specified in the extracerts parameter of openssl_pkcs7_verify are used. The supplied certificates can still be used as untrusted CAs however.</s>
+<s c="PKCS7_NOVERIFY">Do not verify the signers certificate of a signed message.</s>
+<s c="PKCS7_NOCHAIN">Do not chain verification of signers certificates: that is don't use the certificates in the signed message as untrusted CAs.</s>
+<s c="PKCS7_NOCERTS">When signing a message the signer's certificate is normally included - with this option it is excluded. This will reduce the size of the signed message but the verifier must have a copy of the signers certificate available locally (passed using the extracerts to openssl_pkcs7_verify for example).</s>
+<s c="PKCS7_NOATTR">Normally when a message is signed, a set of attributes are included which include the signing time and the supported symmetric algorithms. With this option they are not included.</s>
+<s c="PKCS7_DETACHED">When signing a message, use cleartext signing with the MIME type multipart/signed. This is the default if you do not specify any flags to openssl_pkcs7_sign . If you turn this option off, the message will be signed using opaque signing, which is more resistant to translation by mail relays but cannot be read by mail agents that do not support S/MIME.</s>
+<s c="PKCS7_NOSIGS">Don't try and verify the signatures on a message</s>
+<s c="MCRYPT_ENCRYPT" />
+<s c="MCRYPT_DECRYPT" />
+<s c="MCRYPT_DEV_RANDOM" />
+<s c="MCRYPT_DEV_URANDOM" />
+<s c="MCRYPT_RAND" />
+<s c="256">Phar::SHA512 ( integer )</s>
+<s c="PHP">Phar::PHPS ( integer )</s>
+<s c="M_PENDING" />
+<s c="M_DONE" />
+<s c="M_ERROR" />
+<s c="M_FAIL" />
+<s c="M_SUCCESS" />
+<s c="DC_MICROSOFT" />
+<s c="DC_BORLAND" />
+<s c="DC_CALL_CDECL" />
+<s c="DC_CALL_STD" />
+<s c="DC_RETVAL_MATH4" />
+<s c="DC_RETVAL_MATH8" />
+<s c="DC_CALL_STD_BO" />
+<s c="DC_CALL_STD_MS" />
+<s c="DC_CALL_STD_M8" />
+<s c="DC_FLAG_ARGPTR" />
+<s c="DBPLUS_ERR_NOERR">ERR_NOERR</s>
+<s c="DBPLUS_ERR_DUPLICATE">ERR_DUPLICATE</s>
+<s c="DBPLUS_ERR_EOSCAN">ERR_EOSCAN</s>
+<s c="DBPLUS_ERR_EMPTY">ERR_EMPTY</s>
+<s c="DBPLUS_ERR_CLOSE">ERR_CLOSE</s>
+<s c="DBPLUS_ERR_WLOCKED">ERR_WLOCKED</s>
+<s c="DBPLUS_ERR_LOCKED">ERR_LOCKED</s>
+<s c="DBPLUS_ERR_NOLOCK">ERR_NOLOCK</s>
+<s c="DBPLUS_ERR_READ">ERR_READ</s>
+<s c="DBPLUS_ERR_WRITE">ERR_WRITE</s>
+<s c="DBPLUS_ERR_CREATE">ERR_CREATE</s>
+<s c="DBPLUS_ERR_LSEEK">ERR_LSEEK</s>
+<s c="DBPLUS_ERR_LENGTH">ERR_LENGTH</s>
+<s c="DBPLUS_ERR_OPEN">ERR_OPEN</s>
+<s c="DBPLUS_ERR_WOPEN">ERR_WOPEN</s>
+<s c="DBPLUS_ERR_MAGIC">ERR_MAGIC</s>
+<s c="DBPLUS_ERR_VERSION">ERR_VERSION</s>
+<s c="DBPLUS_ERR_PGSIZE">ERR_PGSIZE</s>
+<s c="DBPLUS_ERR_CRC">ERR_CRC</s>
+<s c="DBPLUS_ERR_PIPE">ERR_PIPE</s>
+<s c="DBPLUS_ERR_NIDX">ERR_NIDX</s>
+<s c="DBPLUS_ERR_MALLOC">ERR_MALLOC</s>
+<s c="DBPLUS_ERR_NUSERS">ERR_NUSERS</s>
+<s c="DBPLUS_ERR_PREEXIT">ERR_PREEXIT</s>
+<s c="DBPLUS_ERR_ONTRAP">ERR_ONTRAP</s>
+<s c="DBPLUS_ERR_PREPROC">ERR_PREPROC</s>
+<s c="DBPLUS_ERR_DBPARSE">ERR_DBPARSE</s>
+<s c="DBPLUS_ERR_DBRUNERR">ERR_DBRUNERR</s>
+<s c="DBPLUS_ERR_DBPREEXIT">ERR_DBPREEXIT</s>
+<s c="DBPLUS_ERR_WAIT">ERR_WAIT</s>
+<s c="DBPLUS_ERR_CORRUPT_TUPLE">ERR_CORRUPT_TUPLE</s>
+<s c="DBPLUS_ERR_WARNING0">ERR_WARNING0</s>
+<s c="DBPLUS_ERR_PANIC">ERR_PANIC</s>
+<s c="DBPLUS_ERR_FIFO">ERR_FIFO</s>
+<s c="DBPLUS_ERR_PERM">ERR_PERM</s>
+<s c="DBPLUS_ERR_TCL">ERR_TCL</s>
+<s c="DBPLUS_ERR_RESTRICTED">ERR_RESTRICTED</s>
+<s c="DBPLUS_ERR_USER">ERR_USER</s>
+<s c="DBPLUS_ERR_UNKNOWN">ERR_UNKNOWN</s>
+<s c="XATTR_ROOT" />
+<s c="XATTR_DONTFOLLOW" />
+<s c="XATTR_CREATE" />
+<s c="XATTR_REPLACE" />
+<s c="CLSCTX_INPROC_SERVER" />
+<s c="CLSCTX_INPROC_HANDLER" />
+<s c="CLSCTX_LOCAL_SERVER" />
+<s c="CLSCTX_REMOTE_SERVER" />
+<s c="CLSCTX_SERVER" />
+<s c="CLSCTX_ALL" />
+<s c="VT_NULL" />
+<s c="VT_EMPTY" />
+<s c="VT_UI1" />
+<s c="VT_I2" />
+<s c="VT_I4" />
+<s c="VT_R4" />
+<s c="VT_R8" />
+<s c="VT_BOOL" />
+<s c="VT_ERROR" />
+<s c="VT_CY" />
+<s c="VT_DATE" />
+<s c="VT_BSTR" />
+<s c="VT_DECIMAL" />
+<s c="VT_UNKNOWN" />
+<s c="VT_DISPATCH" />
+<s c="VT_VARIANT" />
+<s c="VT_I1" />
+<s c="VT_UI2" />
+<s c="VT_UI4" />
+<s c="VT_INT" />
+<s c="VT_UINT" />
+<s c="VT_ARRAY" />
+<s c="VT_BYREF" />
+<s c="CP_ACP" />
+<s c="CP_MACCP" />
+<s c="CP_OEMCP" />
+<s c="CP_UTF7" />
+<s c="CP_UTF8" />
+<s c="CP_SYMBOL" />
+<s c="CP_THREAD_ACP" />
+<s c="VARCMP_LT" />
+<s c="VARCMP_EQ" />
+<s c="VARCMP_GT" />
+<s c="VARCMP_NULL" />
+<s c="NORM_IGNORECASE" />
+<s c="NORM_IGNORENONSPACE" />
+<s c="NORM_IGNORESYMBOLS" />
+<s c="NORM_IGNOREWIDTH" />
+<s c="NORM_IGNOREKANATYPE" />
+<s c="NORM_IGNOREKASHIDA" />
+<s c="DISP_E_DIVBYZERO" />
+<s c="DISP_E_OVERFLOW" />
+<s c="MK_E_UNAVAILABLE" />
+<s c="RUNKIT_IMPORT_FUNCTIONS" />
+<s c="RUNKIT_IMPORT_CLASS_METHODS" />
+<s c="RUNKIT_IMPORT_CLASS_CONSTS" />
+<s c="RUNKIT_IMPORT_CLASS_PROPS" />
+<s c="RUNKIT_IMPORT_CLASSES" />
+<s c="RUNKIT_IMPORT_CLASS_*" />
+<s c="RUNKIT_IMPORT_OVERRIDE" />
+<s c="RUNKIT_ACC_PUBLIC" />
+<s c="RUNKIT_ACC_PROTECTED" />
+<s c="RUNKIT_ACC_PRIVATE" />
+<s c="CLASSKIT_ACC_PUBLIC" />
+<s c="CLASSKIT_ACC_PROTECTED" />
+<s c="CLASSKIT_ACC_PRIVATE" />
+<s c="CLASSKIT_AGGREGATE_OVERRIDE" />
+<s c="RUNKIT_VERSION" />
+<s c="CLASSKIT_VERSION" />
+<s c="XML_ELEMENT_NODE">1</s>
+<s c="XML_ATTRIBUTE_NODE">2</s>
+<s c="XML_TEXT_NODE">3</s>
+<s c="XML_CDATA_SECTION_NODE">4</s>
+<s c="XML_ENTITY_REF_NODE">5</s>
+<s c="XML_ENTITY_NODE">6</s>
+<s c="XML_PI_NODE">7</s>
+<s c="XML_COMMENT_NODE">8</s>
+<s c="XML_DOCUMENT_NODE">9</s>
+<s c="XML_DOCUMENT_TYPE_NODE">10</s>
+<s c="XML_DOCUMENT_FRAG_NODE">11</s>
+<s c="XML_NOTATION_NODE">12</s>
+<s c="XML_HTML_DOCUMENT_NODE">13</s>
+<s c="XML_DTD_NODE">14</s>
+<s c="XML_ELEMENT_DECL_NODE">15</s>
+<s c="XML_ATTRIBUTE_DECL_NODE">16</s>
+<s c="XML_ENTITY_DECL_NODE">17</s>
+<s c="XML_NAMESPACE_DECL_NODE">18</s>
+<s c="XML_ATTRIBUTE_CDATA">1</s>
+<s c="XML_ATTRIBUTE_ID">2</s>
+<s c="XML_ATTRIBUTE_IDREF">3</s>
+<s c="XML_ATTRIBUTE_IDREFS">4</s>
+<s c="XML_ATTRIBUTE_ENTITY">5</s>
+<s c="XML_ATTRIBUTE_NMTOKEN">7</s>
+<s c="XML_ATTRIBUTE_NMTOKENS">8</s>
+<s c="XML_ATTRIBUTE_ENUMERATION">9</s>
+<s c="XML_ATTRIBUTE_NOTATION">10</s>
+<s c="DOM_INDEX_SIZE_ERR">1</s>
+<s c="DOMSTRING_SIZE_ERR">2</s>
+<s c="DOM_HIERARCHY_REQUEST_ERR">3</s>
+<s c="DOM_WRONG_DOCUMENT_ERR">4</s>
+<s c="DOM_INVALID_CHARACTER_ERR">5</s>
+<s c="DOM_NO_DATA_ALLOWED_ERR">6</s>
+<s c="DOM_NO_MODIFICATION_ALLOWED_ERR">7</s>
+<s c="DOM_NOT_FOUND_ERR">8</s>
+<s c="DOM_NOT_SUPPORTED_ERR">9</s>
+<s c="DOM_INUSE_ATTRIBUTE_ERR">10</s>
+<s c="DOM_INVALID_STATE_ERR">11</s>
+<s c="DOM_SYNTAX_ERR">12</s>
+<s c="DOM_INVALID_MODIFICATION_ERR">13</s>
+<s c="DOM_NAMESPACE_ERR">14</s>
+<s c="DOM_INVALID_ACCESS_ERR">15</s>
+<s c="DOM_VALIDATION_ERR">16</s>
+<s c="RPMREADER_MINIMUM" />
+<s c="RPMREADER_NAME" />
+<s c="RPMREADER_VERSION" />
+<s c="RPMREADER_RELEASE" />
+<s c="RPMREADER_EPOCH" />
+<s c="RPMREADER_SERIAL" />
+<s c="RPMREADER_SUMMARY" />
+<s c="RPMREADER_DESCRIPTION" />
+<s c="RPMREADER_BUILDTIME" />
+<s c="RPMREADER_BUILDHOST" />
+<s c="RPMREADER_INSTALLTIME" />
+<s c="RPMREADER_SIZE" />
+<s c="RPMREADER_DISTRIBUTION" />
+<s c="RPMREADER_VENDOR" />
+<s c="RPMREADER_GIF" />
+<s c="RPMREADER_XPM" />
+<s c="RPMREADER_LICENSE" />
+<s c="RPMREADER_COPYRIGHT" />
+<s c="RPMREADER_PACKAGER" />
+<s c="RPMREADER_GROUP" />
+<s c="RPMREADER_SOURCE" />
+<s c="RPMREADER_PATCH" />
+<s c="RPMREADER_URL" />
+<s c="RPMREADER_OS" />
+<s c="RPMREADER_ARCH" />
+<s c="RPMREADER_PREIN" />
+<s c="RPMREADER_POSTIN" />
+<s c="RPMREADER_PREUN" />
+<s c="RPMREADER_POSTUN" />
+<s c="RPMREADER_OLDFILENAMES" />
+<s c="RPMREADER_FILESIZES" />
+<s c="RPMREADER_FILESTATES" />
+<s c="RPMREADER_FILEMODES" />
+<s c="RPMREADER_FILERDEVS" />
+<s c="RPMREADER_FILEMTIMES" />
+<s c="RPMREADER_FILEMD5S" />
+<s c="RPMREADER_FILELINKTOS" />
+<s c="RPMREADER_FILEFLAGS" />
+<s c="RPMREADER_FILEUSERNAME" />
+<s c="RPMREADER_FILEGROUPNAME" />
+<s c="RPMREADER_ICON" />
+<s c="RPMREADER_SOURCERPM" />
+<s c="RPMREADER_FILEVERIFYFLAGS" />
+<s c="RPMREADER_ARCHIVESIZE" />
+<s c="RPMREADER_PROVIDENAME" />
+<s c="RPMREADER_PROVIDES" />
+<s c="RPMREADER_REQUIREFLAGS" />
+<s c="RPMREADER_REQUIRENAME" />
+<s c="RPMREADER_REQUIREVERSION" />
+<s c="RPMREADER_CONFLICTFLAGS" />
+<s c="RPMREADER_CONFLICTNAME" />
+<s c="RPMREADER_CONFLICTVERSION" />
+<s c="RPMREADER_EXCLUDEARCH" />
+<s c="RPMREADER_EXCLUDEOS" />
+<s c="RPMREADER_EXCLUSIVEARCH" />
+<s c="RPMREADER_EXCLUSIVEOS" />
+<s c="RPMREADER_RPMVERSION" />
+<s c="RPMREADER_TRIGGERSCRIPTS" />
+<s c="RPMREADER_TRIGGERNAME" />
+<s c="RPMREADER_TRIGGERVERSION" />
+<s c="RPMREADER_TRIGGERFLAGS" />
+<s c="RPMREADER_TRIGGERINDEX" />
+<s c="RPMREADER_VERIFYSCRIPT" />
+<s c="RPMREADER_CHANGELOGTIME" />
+<s c="RPMREADER_CHANGELOGNAME" />
+<s c="RPMREADER_CHANGELOGTEXT" />
+<s c="RPMREADER_PREINPROG" />
+<s c="RPMREADER_POSTINPROG" />
+<s c="RPMREADER_PREUNPROG" />
+<s c="RPMREADER_POSTUNPROG" />
+<s c="RPMREADER_BUILDARCHS" />
+<s c="RPMREADER_OBSOLETENAME" />
+<s c="RPMREADER_OBSOLETES" />
+<s c="RPMREADER_VERIFYSCRIPTPROG" />
+<s c="RPMREADER_TRIGGERSCRIPTPROG" />
+<s c="RPMREADER_COOKIE" />
+<s c="RPMREADER_FILEDEVICES" />
+<s c="RPMREADER_FILEINODES" />
+<s c="RPMREADER_FILELANGS" />
+<s c="RPMREADER_PREFIXES" />
+<s c="RPMREADER_INSTPREFIXES" />
+<s c="RPMREADER_PROVIDEFLAGS" />
+<s c="RPMREADER_PROVIDEVERSION" />
+<s c="RPMREADER_OBSOLETEFLAGS" />
+<s c="RPMREADER_OBSOLETEVERSION" />
+<s c="RPMREADER_DIRINDEXES" />
+<s c="RPMREADER_BASENAMES" />
+<s c="RPMREADER_DIRNAMES" />
+<s c="RPMREADER_OPTFLAGS" />
+<s c="RPMREADER_DISTURL" />
+<s c="RPMREADER_PAYLOADFORMAT" />
+<s c="RPMREADER_PAYLOADCOMPRESSOR" />
+<s c="RPMREADER_PAYLOADFLAGS" />
+<s c="RPMREADER_INSTALLCOLOR" />
+<s c="RPMREADER_INSTALLTID" />
+<s c="RPMREADER_REMOVETID" />
+<s c="RPMREADER_RHNPLATFORM" />
+<s c="RPMREADER_PLATFORM" />
+<s c="RPMREADER_PATCHESNAME" />
+<s c="RPMREADER_PATCHESFLAGS" />
+<s c="RPMREADER_PATCHESVERSION" />
+<s c="RPMREADER_CACHECTIME" />
+<s c="RPMREADER_CACHEPKGPATH" />
+<s c="RPMREADER_CACHEPKGSIZE" />
+<s c="RPMREADER_CACHEPKGMTIME" />
+<s c="RPMREADER_FILECOLORS" />
+<s c="RPMREADER_FILECLASS" />
+<s c="RPMREADER_CLASSDICT" />
+<s c="RPMREADER_FILEDEPENDSX" />
+<s c="RPMREADER_FILEDEPENDSN" />
+<s c="RPMREADER_DEPENDSDICT" />
+<s c="RPMREADER_SOURCEPKGID" />
+<s c="RPMREADER_FILECONTEXTS" />
+<s c="RPMREADER_FSCONTEXTS" />
+<s c="RPMREADER_RECONTEXTS" />
+<s c="RPMREADER_POLICIES" />
+<s c="RPMREADER_MAXIMUM" />
+<s c="ID3_V1_0" />
+<s c="ID3_V1_1" />
+<s c="ID3_V2_1" />
+<s c="ID3_V2_2" />
+<s c="ID3_V2_3" />
+<s c="ID3_V2_4" />
+<s c="ID3_BEST" />
+<s c="MYSQLI_READ_DEFAULT_GROUP" />
+<s c="MYSQLI_READ_DEFAULT_FILE" />
+<s c="MYSQLI_OPT_CONNECT_TIMEOUT" />
+<s c="MYSQLI_OPT_LOCAL_INFILE" />
+<s c="MYSQLI_INIT_COMMAND" />
+<s c="MYSQLI_CLIENT_SSL" />
+<s c="MYSQLI_CLIENT_COMPRESS" />
+<s c="MYSQLI_CLIENT_INTERACTIVE" />
+<s c="MYSQLI_CLIENT_IGNORE_SPACE" />
+<s c="MYSQLI_CLIENT_NO_SCHEMA" />
+<s c="MYSQLI_CLIENT_MULTI_QUERIES" />
+<s c="MYSQLI_STORE_RESULT" />
+<s c="MYSQLI_USE_RESULT" />
+<s c="MYSQLI_ASSOC" />
+<s c="MYSQLI_NUM" />
+<s c="MYSQLI_BOTH" />
+<s c="MYSQLI_NOT_NULL_FLAG" />
+<s c="MYSQLI_PRI_KEY_FLAG" />
+<s c="MYSQLI_UNIQUE_KEY_FLAG" />
+<s c="MYSQLI_MULTIPLE_KEY_FLAG" />
+<s c="MYSQLI_BLOB_FLAG" />
+<s c="MYSQLI_UNSIGNED_FLAG" />
+<s c="MYSQLI_ZEROFILL_FLAG" />
+<s c="MYSQLI_AUTO_INCREMENT_FLAG" />
+<s c="MYSQLI_TIMESTAMP_FLAG" />
+<s c="MYSQLI_SET_FLAG" />
+<s c="MYSQLI_NUM_FLAG" />
+<s c="MYSQLI_PART_KEY_FLAG" />
+<s c="MYSQLI_GROUP_FLAG" />
+<s c="MYSQLI_TYPE_DECIMAL" />
+<s c="MYSQLI_TYPE_NEWDECIMAL" />
+<s c="MYSQLI_TYPE_BIT" />
+<s c="MYSQLI_TYPE_TINY" />
+<s c="MYSQLI_TYPE_SHORT" />
+<s c="MYSQLI_TYPE_LONG" />
+<s c="MYSQLI_TYPE_FLOAT" />
+<s c="MYSQLI_TYPE_DOUBLE" />
+<s c="MYSQLI_TYPE_NULL" />
+<s c="MYSQLI_TYPE_TIMESTAMP" />
+<s c="MYSQLI_TYPE_LONGLONG" />
+<s c="MYSQLI_TYPE_INT24" />
+<s c="MYSQLI_TYPE_DATE" />
+<s c="MYSQLI_TYPE_TIME" />
+<s c="MYSQLI_TYPE_DATETIME" />
+<s c="MYSQLI_TYPE_YEAR" />
+<s c="MYSQLI_TYPE_NEWDATE" />
+<s c="MYSQLI_TYPE_ENUM" />
+<s c="MYSQLI_TYPE_SET" />
+<s c="MYSQLI_TYPE_TINY_BLOB" />
+<s c="MYSQLI_TYPE_MEDIUM_BLOB" />
+<s c="MYSQLI_TYPE_LONG_BLOB" />
+<s c="MYSQLI_TYPE_BLOB" />
+<s c="MYSQLI_TYPE_VAR_STRING" />
+<s c="MYSQLI_TYPE_STRING" />
+<s c="MYSQLI_TYPE_GEOMETRY" />
+<s c="MYSQLI_NEED_DATA" />
+<s c="MYSQLI_NO_DATA" />
+<s c="MYSQLI_DATA_TRUNCATED" />
+<s c="MYSQLI_ENUM_FLAG" />
+<s c="MEMCACHE_COMPRESSED">Used to turn on-the-fly data compression on with Memcache::set , Memcache::add &amp;listendand; Memcache::replace .</s>
+<s c="MEMCACHE_HAVE_SESSION">1 if this Memcache session handler is available, 0 otherwise.</s>
+<s c="PSPELL_FAST" />
+<s c="PSPELL_NORMAL" />
+<s c="PSPELL_BAD_SPELLERS" />
+<s c="PSPELL_RUN_TOGETHER" />
+<s c="CYRUS_CONN_NONSYNCLITERAL" />
+<s c="CYRUS_CONN_INITIALRESPONSE" />
+<s c="CYRUS_CALLBACK_NUMBERED" />
+<s c="CYRUS_CALLBACK_NOLITERAL" />
+<s c="FRIBIDI_CHARSET_UTF8" />
+<s c="FRIBIDI_CHARSET_8859_6" />
+<s c="FRIBIDI_CHARSET_8859_8" />
+<s c="FRIBIDI_CHARSET_CP1255" />
+<s c="FRIBIDI_CHARSET_CP1256" />
+<s c="FRIBIDI_CHARSET_ISIRI_3342" />
+<s c="FRIBIDI_CHARSET_CAP_RTL" />
+<s c="FRIBIDI_RTL" />
+<s c="FRIBIDI_LTR" />
+<s c="FRIBIDI_AUTO" />
+<s c="STREAM_FILTER_READ">Used with stream_filter_append and stream_filter_prepend to indicate that the specified filter should only be applied when reading</s>
+<s c="STREAM_FILTER_WRITE">Used with stream_filter_append and stream_filter_prepend to indicate that the specified filter should only be applied when writing</s>
+<s c="STREAM_FILTER_ALL">This constant is equivalent to STREAM_FILTER_READ | STREAM_FILTER_WRITE</s>
+<s c="PSFS_PASS_ON">Return Code indicating that the userspace filter returned buckets in $out .</s>
+<s c="PSFS_FEED_ME">Return Code indicating that the userspace filter did not return buckets in $out (i.e. No data available).</s>
+<s c="PSFS_ERR_FATAL">Return Code indicating that the userspace filter encountered an unrecoverable error (i.e. Invalid data received).</s>
+<s c="STREAM_USE_PATH">Flag indicating if the stream used the include path.</s>
+<s c="STREAM_REPORT_ERRORS">Flag indicating if the wrapper is responsible for raising errors using trigger_error during opening of the stream. If this flag is not set, you should not raise any errors.</s>
+<s c="STREAM_CLIENT_ASYNC_CONNECT">Open client socket asynchronously. This option must be used together with the STREAM_CLIENT_CONNECT flag. Used with stream_socket_client .</s>
+<s c="STREAM_CLIENT_CONNECT">Open client socket connection. Client sockets should always include this flag. Used with stream_socket_client .</s>
+<s c="STREAM_CLIENT_PERSISTENT">Client socket opened with stream_socket_client should remain persistent between page loads.</s>
+<s c="STREAM_SERVER_BIND">Tells a stream created with stream_socket_server to bind to the specified target. Server sockets should always include this flag.</s>
+<s c="STREAM_SERVER_LISTEN">Tells a stream created with stream_socket_server and bound using the STREAM_SERVER_BIND flag to start listening on the socket. Connection-orientated transports (such as TCP) must use this flag, otherwise the server socket will not be enabled. Using this flag for connect-less transports (such as UDP) is an error.</s>
+<s c="STREAM_NOTIFY_RESOLVE">A remote address required for this stream has been resolved, or the resolution failed. See severity for an indication of which happened.</s>
+<s c="STREAM_NOTIFY_CONNECT">A connection with an external resource has been established.</s>
+<s c="STREAM_NOTIFY_AUTH_REQUIRED">Additional authorization is required to access the specified resource. Typical issued with severity level of STREAM_NOTIFY_SEVERITY_ERR .</s>
+<s c="STREAM_NOTIFY_MIME_TYPE_IS">The mime-type of resource has been identified, refer to message for a description of the discovered type.</s>
+<s c="STREAM_NOTIFY_FILE_SIZE_IS">The size of the resource has been discovered.</s>
+<s c="STREAM_NOTIFY_REDIRECTED">The external resource has redirected the stream to an alternate location. Refer to message .</s>
+<s c="STREAM_NOTIFY_PROGRESS">Indicates current progress of the stream transfer in bytes_transferred and possibly bytes_max as well.</s>
+<s c="STREAM_NOTIFY_COMPLETED">There is no more data available on the stream.</s>
+<s c="STREAM_NOTIFY_FAILURE">A generic error occurred on the stream, consult message and message_code for details.</s>
+<s c="STREAM_NOTIFY_AUTH_RESULT">Authorization has been completed (with or without success).</s>
+<s c="STREAM_NOTIFY_SEVERITY_INFO">Normal, non-error related, notification.</s>
+<s c="STREAM_NOTIFY_SEVERITY_WARN">Non critical error condition. Processing may continue.</s>
+<s c="STREAM_NOTIFY_SEVERITY_ERR">A critical error occurred. Processing cannot continue.</s>
+<s c="STREAM_IPPROTO_ICMP">Provides a ICMP socket.</s>
+<s c="STREAM_IPPROTO_IP">Provides a IP socket.</s>
+<s c="STREAM_IPPROTO_RAW">Provides a RAW socket.</s>
+<s c="STREAM_IPPROTO_TCP">Provides a TCP socket.</s>
+<s c="STREAM_IPPROTO_UDP">Provides a UDP socket.</s>
+<s c="STREAM_PF_INET">Internet Protocol Version 4 (IPv4).</s>
+<s c="STREAM_PF_INET6">Internet Protocol Version 6 (IPv6).</s>
+<s c="STREAM_PF_UNIX">Unix system internal protocols.</s>
+<s c="STREAM_SOCK_DGRAM">Provides datagrams, which are connectionless messages (UDP, for example).</s>
+<s c="STREAM_SOCK_RAW">Provides a raw socket, which provides access to internal network protocols and interfaces. Usually this type of socket is just available to the root user.</s>
+<s c="STREAM_SOCK_RDM">Provides a RDM (Reliably-delivered messages) socket.</s>
+<s c="STREAM_SOCK_SEQPACKET">Provides a sequenced packet stream socket.</s>
+<s c="STREAM_SOCK_STREAM">Provides sequenced, two-way byte streams with a transmission mechanism for out-of-band data (TCP, for example).</s>
+<s c="STREAM_SHUT_RD">Used with stream_socket_shutdown to disable further receptions. Added in PHP 5.2.1.</s>
+<s c="STREAM_SHUT_WR">Used with stream_socket_shutdown to disable further transmissions. Added in PHP 5.2.1.</s>
+<s c="STREAM_SHUT_RDWR">Used with stream_socket_shutdown to disable further receptions and transmissions. Added in PHP 5.2.1.</s>
+<s c="E_ERROR">Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.</s>
+<s c="DBX_MYSQL" />
+<s c="DBX_ODBC" />
+<s c="DBX_PGSQL" />
+<s c="DBX_MSSQL" />
+<s c="DBX_FBSQL" />
+<s c="DBX_OCI8" />
+<s c="DBX_SYBASECT" />
+<s c="DBX_SQLITE" />
+<s c="DBX_PERSISTENT" />
+<s c="DBX_RESULT_INFO" />
+<s c="DBX_RESULT_INDEX" />
+<s c="DBX_RESULT_ASSOC" />
+<s c="DBX_RESULT_UNBUFFERED" />
+<s c="DBX_COLNAMES_UNCHANGED" />
+<s c="DBX_COLNAMES_UPPERCASE" />
+<s c="DBX_COLNAMES_LOWERCASE" />
+<s c="DBX_CMP_NATIVE" />
+<s c="DBX_CMP_TEXT" />
+<s c="DBX_CMP_NUMBER" />
+<s c="DBX_CMP_ASC" />
+<s c="DBX_CMP_DESC" />
+<s c="F_DUPFD" />
+<s c="F_GETFD" />
+<s c="F_GETFL" />
+<s c="F_GETLK" />
+<s c="F_GETOWN" />
+<s c="F_RDLCK" />
+<s c="F_SETFL" />
+<s c="F_SETLK" />
+<s c="F_SETLKW" />
+<s c="F_SETOWN" />
+<s c="F_UNLCK" />
+<s c="F_WRLCK" />
+<s c="O_APPEND" />
+<s c="O_ASYNC" />
+<s c="O_CREAT" />
+<s c="O_EXCL" />
+<s c="O_NDELAY" />
+<s c="O_NOCTTY" />
+<s c="O_NONBLOCK" />
+<s c="O_RDONLY" />
+<s c="O_RDWR" />
+<s c="O_SYNC" />
+<s c="O_TRUNC" />
+<s c="O_WRONLY" />
+<s c="S_IRGRP" />
+<s c="S_IROTH" />
+<s c="S_IRUSR" />
+<s c="S_IRWXG" />
+<s c="S_IRWXO" />
+<s c="S_IRWXU" />
+<s c="S_IWGRP" />
+<s c="S_IWOTH" />
+<s c="S_IWUSR" />
+<s c="S_IXGRP" />
+<s c="S_IXOTH" />
+<s c="S_IXUSR" />
+<s c="ALC_FREQUENCY" />
+<s c="ALC_REFRESH" />
+<s c="ALC_SYNC" />
+<s c="AL_FREQUENCY" />
+<s c="AL_BITS" />
+<s c="AL_CHANNELS" />
+<s c="AL_SIZE" />
+<s c="AL_BUFFER" />
+<s c="AL_SOURCE_RELATIVE" />
+<s c="AL_SOURCE_STATE" />
+<s c="AL_PITCH" />
+<s c="AL_GAIN" />
+<s c="AL_MIN_GAIN" />
+<s c="AL_MAX_GAIN" />
+<s c="AL_MAX_DISTANCE" />
+<s c="AL_ROLLOFF_FACTOR" />
+<s c="AL_CONE_OUTER_GAIN" />
+<s c="AL_CONE_INNER_ANGLE" />
+<s c="AL_CONE_OUTER_ANGLE" />
+<s c="AL_REFERENCE_DISTANCE" />
+<s c="AL_POSITION" />
+<s c="AL_VELOCITY" />
+<s c="AL_DIRECTION" />
+<s c="AL_ORIENTATION" />
+<s c="AL_FORMAT_MONO8" />
+<s c="AL_FORMAT_MONO16" />
+<s c="AL_FORMAT_STEREO8" />
+<s c="AL_FORMAT_STEREO16" />
+<s c="AL_INITIAL" />
+<s c="AL_PLAYING" />
+<s c="AL_PAUSED" />
+<s c="AL_STOPPED" />
+<s c="AL_LOOPING" />
+<s c="AL_TRUE" />
+<s c="AL_FALSE" />
+<s c="NCURSES_COLOR_BLACK">no color (black)</s>
+<s c="NCURSES_COLOR_WHITE">white</s>
+<s c="NCURSES_COLOR_RED">red - supported when terminal is in color mode</s>
+<s c="NCURSES_COLOR_GREEN">green - supported when terminal is in color mode</s>
+<s c="NCURSES_COLOR_YELLOW">yellow - supported when terminal is in color mode</s>
+<s c="NCURSES_COLOR_BLUE">blue - supported when terminal is in color mode</s>
+<s c="NCURSES_COLOR_CYAN">cyan - supported when terminal is in color mode</s>
+<s c="NCURSES_COLOR_MAGENTA">magenta - supported when terminal is in color mode</s>
+<s c="NCURSES_KEY_DOWN">down arrow</s>
+<s c="NCURSES_KEY_UP">up arrow</s>
+<s c="NCURSES_KEY_LEFT">left arrow</s>
+<s c="NCURSES_KEY_RIGHT">right arrow</s>
+<s c="NCURSES_KEY_HOME">home key (upward+left arrow)</s>
+<s c="NCURSES_KEY_BACKSPACE">backspace</s>
+<s c="NCURSES_KEY_DL">delete line</s>
+<s c="NCURSES_KEY_IL">insert line</s>
+<s c="NCURSES_KEY_DC">delete character</s>
+<s c="NCURSES_KEY_IC">insert char or enter insert mode</s>
+<s c="NCURSES_KEY_EIC">exit insert char mode</s>
+<s c="NCURSES_KEY_CLEAR">clear screen</s>
+<s c="NCURSES_KEY_EOS">clear to end of screen</s>
+<s c="NCURSES_KEY_EOL">clear to end of line</s>
+<s c="NCURSES_KEY_SF">scroll one line forward</s>
+<s c="NCURSES_KEY_SR">scroll one line backward</s>
+<s c="NCURSES_KEY_NPAGE">next page</s>
+<s c="NCURSES_KEY_PPAGE">previous page</s>
+<s c="NCURSES_KEY_STAB">set tab</s>
+<s c="NCURSES_KEY_CTAB">clear tab</s>
+<s c="NCURSES_KEY_CATAB">clear all tabs</s>
+<s c="NCURSES_KEY_SRESET">soft (partial) reset</s>
+<s c="NCURSES_KEY_RESET">reset or hard reset</s>
+<s c="NCURSES_KEY_PRINT">print</s>
+<s c="NCURSES_KEY_LL">lower left</s>
+<s c="NCURSES_KEY_A1">upper left of keypad</s>
+<s c="NCURSES_KEY_A3">upper right of keypad</s>
+<s c="NCURSES_KEY_B2">center of keypad</s>
+<s c="NCURSES_KEY_C1">lower left of keypad</s>
+<s c="NCURSES_KEY_C3">lower right of keypad</s>
+<s c="NCURSES_KEY_BTAB">back tab</s>
+<s c="NCURSES_KEY_BEG">beginning</s>
+<s c="NCURSES_KEY_CANCEL">cancel</s>
+<s c="NCURSES_KEY_CLOSE">close</s>
+<s c="NCURSES_KEY_COMMAND">cmd (command)</s>
+<s c="NCURSES_KEY_COPY">copy</s>
+<s c="NCURSES_KEY_CREATE">create</s>
+<s c="NCURSES_KEY_END">end</s>
+<s c="NCURSES_KEY_EXIT">exit</s>
+<s c="NCURSES_KEY_FIND">find</s>
+<s c="NCURSES_KEY_HELP">help</s>
+<s c="NCURSES_KEY_MARK">mark</s>
+<s c="NCURSES_KEY_MESSAGE">message</s>
+<s c="NCURSES_KEY_MOVE">move</s>
+<s c="NCURSES_KEY_NEXT">next</s>
+<s c="NCURSES_KEY_OPEN">open</s>
+<s c="NCURSES_KEY_OPTIONS">options</s>
+<s c="NCURSES_KEY_PREVIOUS">previous</s>
+<s c="NCURSES_KEY_REDO">redo</s>
+<s c="NCURSES_KEY_REFERENCE">ref (reference)</s>
+<s c="NCURSES_KEY_REFRESH">refresh</s>
+<s c="NCURSES_KEY_REPLACE">replace</s>
+<s c="NCURSES_KEY_RESTART">restart</s>
+<s c="NCURSES_KEY_RESUME">resume</s>
+<s c="NCURSES_KEY_SAVE">save</s>
+<s c="NCURSES_KEY_SBEG">shiftet beg (beginning)</s>
+<s c="NCURSES_KEY_SCANCEL">shifted cancel</s>
+<s c="NCURSES_KEY_SCOMMAND">shifted command</s>
+<s c="NCURSES_KEY_SCOPY">shifted copy</s>
+<s c="NCURSES_KEY_SCREATE">shifted create</s>
+<s c="NCURSES_KEY_SDC">shifted delete char</s>
+<s c="NCURSES_KEY_SDL">shifted delete line</s>
+<s c="NCURSES_KEY_SELECT">select</s>
+<s c="NCURSES_KEY_SEND">shifted end</s>
+<s c="NCURSES_KEY_SEOL">shifted end of line</s>
+<s c="NCURSES_KEY_SEXIT">shifted exit</s>
+<s c="NCURSES_KEY_SFIND">shifted find</s>
+<s c="NCURSES_KEY_SHELP">shifted help</s>
+<s c="NCURSES_KEY_SHOME">shifted home</s>
+<s c="NCURSES_KEY_SIC">shifted input</s>
+<s c="NCURSES_KEY_SLEFT">shifted left arrow</s>
+<s c="NCURSES_KEY_SMESSAGE">shifted message</s>
+<s c="NCURSES_KEY_SMOVE">shifted move</s>
+<s c="NCURSES_KEY_SNEXT">shifted next</s>
+<s c="NCURSES_KEY_SOPTIONS">shifted options</s>
+<s c="NCURSES_KEY_SPREVIOUS">shifted previous</s>
+<s c="NCURSES_KEY_SPRINT">shifted print</s>
+<s c="NCURSES_KEY_SREDO">shifted redo</s>
+<s c="NCURSES_KEY_SREPLACE">shifted replace</s>
+<s c="NCURSES_KEY_SRIGHT">shifted right arrow</s>
+<s c="NCURSES_KEY_SRSUME">shifted resume</s>
+<s c="NCURSES_KEY_SSAVE">shifted save</s>
+<s c="NCURSES_KEY_SSUSPEND">shifted suspend</s>
+<s c="NCURSES_KEY_UNDO">undo</s>
+<s c="NCURSES_KEY_MOUSE">mouse event has occurred</s>
+<s c="NCURSES_KEY_MAX">maximum key value</s>
+<s c="NCURSES_BUTTON_CTRL">ctrl pressed during click</s>
+<s c="NCURSES_BUTTON_SHIFT">shift pressed during click</s>
+<s c="NCURSES_BUTTON_ALT">alt pressed during click</s>
+<s c="NCURSES_ALL_MOUSE_EVENTS">report all mouse events</s>
+<s c="NCURSES_REPORT_MOUSE_POSITION">report mouse position</s>
+<s c="PDO_PARAM_BOOL" />
+<s c="PDO::PARAM_BOOL" />
+<s c="PDO::PARAM_NULL" />
+<s c="PDO::PARAM_INT" />
+<s c="PDO::PARAM_STR" />
+<s c="PDO::PARAM_LOB" />
+<s c="PDO::PARAM_STMT" />
+<s c="PDO::PARAM_INPUT_OUTPUT" />
+<s c="PDO::FETCH_LAZY" />
+<s c="PDO::FETCH_ASSOC" />
+<s c="PDO::FETCH_NAMED" />
+<s c="PDO::FETCH_NUM" />
+<s c="PDO::FETCH_BOTH" />
+<s c="PDO::FETCH_OBJ" />
+<s c="PDO::FETCH_BOUND" />
+<s c="PDO::FETCH_COLUMN" />
+<s c="PDO::FETCH_CLASS" />
+<s c="PDO::FETCH_INTO" />
+<s c="PDO::FETCH_FUNC" />
+<s c="PDO::FETCH_GROUP" />
+<s c="PDO::FETCH_UNIQUE" />
+<s c="PDO::FETCH_KEY_PAIR" />
+<s c="PDO::FETCH_CLASSTYPE" />
+<s c="PDO::FETCH_SERIALIZE" />
+<s c="PDO::FETCH_PROPS_LATE" />
+<s c="PDO::ATTR_AUTOCOMMIT" />
+<s c="PDO::ATTR_PREFETCH" />
+<s c="PDO::ATTR_TIMEOUT" />
+<s c="PDO::ATTR_ERRMODE" />
+<s c="PDO::ATTR_SERVER_VERSION" />
+<s c="PDO::ATTR_CLIENT_VERSION" />
+<s c="PDO::ATTR_SERVER_INFO" />
+<s c="PDO::ATTR_CONNECTION_STATUS" />
+<s c="PDO::ATTR_CASE" />
+<s c="PDO::ATTR_CURSOR_NAME" />
+<s c="PDO::ATTR_CURSOR" />
+<s c="PDO::CURSOR_FWDONLY" />
+<s c="PDO::CURSOR_SCROLL" />
+<s c="PDO::ATTR_DRIVER_NAME" />
+<s c="PDO::ATTR_ORACLE_NULLS" />
+<s c="PDO::ATTR_PERSISTENT" />
+<s c="PDO::ATTR_STATEMENT_CLASS" />
+<s c="PDO::ATTR_FETCH_CATALOG_NAMES" />
+<s c="PDO::ATTR_FETCH_TABLE_NAMES" />
+<s c="PDO::ATTR_STRINGIFY_FETCHES" />
+<s c="PDO::ATTR_MAX_COLUMN_LEN" />
+<s c="PDO::ATTR_DEFAULT_FETCH_MODE" />
+<s c="PDO::ATTR_EMULATE_PREPARES" />
+<s c="PDO::ERRMODE_SILENT" />
+<s c="PDO::ERRMODE_WARNING" />
+<s c="PDO::ERRMODE_EXCEPTION" />
+<s c="PDO::CASE_NATURAL" />
+<s c="PDO::CASE_LOWER" />
+<s c="PDO::CASE_UPPER" />
+<s c="PDO::NULL_NATURAL" />
+<s c="PDO::NULL_EMPTY_STRING" />
+<s c="PDO::NULL_TO_STRING" />
+<s c="PDO::FETCH_ORI_NEXT" />
+<s c="PDO::FETCH_ORI_PRIOR" />
+<s c="PDO::FETCH_ORI_FIRST" />
+<s c="PDO::FETCH_ORI_LAST" />
+<s c="PDO::FETCH_ORI_ABS" />
+<s c="PDO::FETCH_ORI_REL" />
+<s c="PDO::ERR_NONE" />
+<s c="PDO::PARAM_EVT_ALLOC" />
+<s c="PDO::PARAM_EVT_FREE" />
+<s c="PDO::PARAM_EVT_EXEC_PRE" />
+<s c="PDO::PARAM_EVT_EXEC_POST" />
+<s c="PDO::PARAM_EVT_FETCH_PRE" />
+<s c="PDO::PARAM_EVT_FETCH_POST" />
+<s c="PDO::PARAM_EVT_NORMALIZE" />
+<s c="GNUPG_SIG_MODE_NORMAL" />
+<s c="GNUPG_SIG_MODE_DETACH" />
+<s c="GNUPG_SIG_MODE_CLEAR" />
+<s c="GNUPG_VALIDITY_UNKNOWN" />
+<s c="GNUPG_VALIDITY_UNDEFINED" />
+<s c="GNUPG_VALIDITY_NEVER" />
+<s c="GNUPG_VALIDITY_MARGINAL" />
+<s c="GNUPG_VALIDITY_FULL" />
+<s c="GNUPG_VALIDITY_ULTIMATE" />
+<s c="GNUPG_PROTOCOL_OpenPGP" />
+<s c="GNUPG_PROTOCOL_CMS" />
+<s c="GNUPG_SIGSUM_VALID" />
+<s c="GNUPG_SIGSUM_GREEN" />
+<s c="GNUPG_SIGSUM_RED" />
+<s c="GNUPG_SIGSUM_KEY_REVOKED" />
+<s c="GNUPG_SIGSUM_KEY_EXPIRED" />
+<s c="GNUPG_SIGSUM_KEY_MISSING" />
+<s c="GNUPG_SIGSUM_SIG_EXPIRED" />
+<s c="GNUPG_SIGSUM_CRL_MISSING" />
+<s c="GNUPG_SIGSUM_CRL_TOO_OLD" />
+<s c="GNUPG_SIGSUM_BAD_POLICY" />
+<s c="GNUPG_SIGSUM_SYS_ERROR" />
+<s c="GNUPG_ERROR_WARNING" />
+<s c="GNUPG_ERROR_EXCEPTION" />
+<s c="GNUPG_ERROR_SILENT" />
+<s c="XML_ELEMENT_NODE">1</s>
+<s c="XML_ATTRIBUTE_NODE">2</s>
+<s c="XML_TEXT_NODE">3</s>
+<s c="XML_CDATA_SECTION_NODE">4</s>
+<s c="XML_ENTITY_REF_NODE">5</s>
+<s c="XML_ENTITY_NODE">6</s>
+<s c="XML_PI_NODE">7</s>
+<s c="XML_COMMENT_NODE">8</s>
+<s c="XML_DOCUMENT_NODE">9</s>
+<s c="XML_DOCUMENT_TYPE_NODE">10</s>
+<s c="XML_DOCUMENT_FRAG_NODE">11</s>
+<s c="XML_NOTATION_NODE">12</s>
+<s c="XML_GLOBAL_NAMESPACE">1</s>
+<s c="XML_LOCAL_NAMESPACE">2</s>
+<s c="XML_HTML_DOCUMENT_NODE" /> 
+<s c="XML_DTD_NODE" /> 
+<s c="XML_ELEMENT_DECL_NODE" /> 
+<s c="XML_ATTRIBUTE_DECL_NODE" /> 
+<s c="XML_ENTITY_DECL_NODE" /> 
+<s c="XML_NAMESPACE_DECL_NODE" /> 
+<s c="XML_ATTRIBUTE_CDATA" /> 
+<s c="XML_ATTRIBUTE_ID" /> 
+<s c="XML_ATTRIBUTE_IDREF" /> 
+<s c="XML_ATTRIBUTE_IDREFS" /> 
+<s c="XML_ATTRIBUTE_ENTITY" /> 
+<s c="XML_ATTRIBUTE_NMTOKEN" /> 
+<s c="XML_ATTRIBUTE_NMTOKENS" /> 
+<s c="XML_ATTRIBUTE_ENUMERATION" /> 
+<s c="XML_ATTRIBUTE_NOTATION" /> 
+<s c="XPATH_UNDEFINED" /> 
+<s c="XPATH_NODESET" /> 
+<s c="XPATH_BOOLEAN" /> 
+<s c="XPATH_NUMBER" /> 
+<s c="XPATH_STRING" /> 
+<s c="XPATH_POINT" /> 
+<s c="XPATH_RANGE" /> 
+<s c="XPATH_LOCATIONSET" /> 
+<s c="XPATH_USERS" /> 
+<s c="XPATH_NUMBER" /> 
+<s c="_LINECAP_BUTT" /> 
+<s c="_LINECAP_ROUND" /> 
+<s c="_LINECAP_SQUARED" /> 
+<s c="_LINEJOIN_MITER" /> 
+<s c="_LINEJOIN_ROUND" /> 
+<s c="_LINEJOIN_BEVEL" /> 
+<s c="XML_ERROR_NONE" />
+<s c="XML_ERROR_NO_MEMORY" />
+<s c="XML_ERROR_SYNTAX" />
+<s c="XML_ERROR_NO_ELEMENTS" />
+<s c="XML_ERROR_INVALID_TOKEN" />
+<s c="XML_ERROR_UNCLOSED_TOKEN" />
+<s c="XML_ERROR_PARTIAL_CHAR" />
+<s c="XML_ERROR_TAG_MISMATCH" />
+<s c="XML_ERROR_DUPLICATE_ATTRIBUTE" />
+<s c="XML_ERROR_JUNK_AFTER_DOC_ELEMENT" />
+<s c="XML_ERROR_PARAM_ENTITY_REF" />
+<s c="XML_ERROR_UNDEFINED_ENTITY" />
+<s c="XML_ERROR_RECURSIVE_ENTITY_REF" />
+<s c="XML_ERROR_ASYNC_ENTITY" />
+<s c="XML_ERROR_BAD_CHAR_REF" />
+<s c="XML_ERROR_BINARY_ENTITY_REF" />
+<s c="XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF" />
+<s c="XML_ERROR_MISPLACED_XML_PI" />
+<s c="XML_ERROR_UNKNOWN_ENCODING" />
+<s c="XML_ERROR_INCORRECT_ENCODING" />
+<s c="XML_ERROR_UNCLOSED_CDATA_SECTION" />
+<s c="XML_ERROR_EXTERNAL_ENTITY_HANDLING" />
+<s c="XML_OPTION_CASE_FOLDING" />
+<s c="XML_OPTION_TARGET_ENCODING" />
+<s c="XML_OPTION_SKIP_TAGSTART" />
+<s c="XML_OPTION_SKIP_WHITE" />
+<s c="FDFValue" />
+<s c="FDFStatus" />
+<s c="FDFFile" />
+<s c="FDFID" />
+<s c="FDFFf" />
+<s c="FDFSetFf" />
+<s c="FDFClearFf" />
+<s c="FDFFlags" />
+<s c="FDFSetF" />
+<s c="FDFClrF" />
+<s c="FDFAP" />
+<s c="FDFAS" />
+<s c="FDFAction" />
+<s c="FDFAA" />
+<s c="FDFAPRef" />
+<s c="FDFIF" />
+<s c="FDFEnter" />
+<s c="FDFExit" />
+<s c="FDFDown" />
+<s c="FDFUp" />
+<s c="FDFFormat" />
+<s c="FDFValidate" />
+<s c="FDFKeystroke" />
+<s c="FDFCalculate" />
+<s c="FDFNormalAP" />
+<s c="FDFRolloverAP" />
+<s c="FDFDownAP" />
+<s c="SOAP_1_1" />
+<s c="SOAP_1_2" />
+<s c="SOAP_PERSISTENCE_SESSION" />
+<s c="SOAP_PERSISTENCE_REQUEST" />
+<s c="SOAP_FUNCTIONS_ALL" />
+<s c="SOAP_ENCODED" />
+<s c="SOAP_LITERAL" />
+<s c="SOAP_RPC" />
+<s c="SOAP_DOCUMENT" />
+<s c="SOAP_ACTOR_NEXT" />
+<s c="SOAP_ACTOR_NONE" />
+<s c="SOAP_ACTOR_UNLIMATERECEIVER" />
+<s c="SOAP_COMPRESSION_ACCEPT" />
+<s c="SOAP_COMPRESSION_GZIP" />
+<s c="SOAP_COMPRESSION_DEFLATE" />
+<s c="SOAP_AUTHENTICATION_BASIC" />
+<s c="SOAP_AUTHENTICATION_DIGEST" />
+<s c="UNKNOWN_TYPE" />
+<s c="XSD_STRING" />
+<s c="XSD_BOOLEAN" />
+<s c="XSD_DECIMAL" />
+<s c="XSD_FLOAT" />
+<s c="XSD_DOUBLE" />
+<s c="XSD_DURATION" />
+<s c="XSD_DATETIME" />
+<s c="XSD_TIME" />
+<s c="XSD_DATE" />
+<s c="XSD_GYEARMONTH" />
+<s c="XSD_GYEAR" />
+<s c="XSD_GMONTHDAY" />
+<s c="XSD_GDAY" />
+<s c="XSD_GMONTH" />
+<s c="XSD_HEXBINARY" />
+<s c="XSD_BASE64BINARY" />
+<s c="XSD_ANYURI" />
+<s c="XSD_QNAME" />
+<s c="XSD_NOTATION" />
+<s c="XSD_NORMALIZEDSTRING" />
+<s c="XSD_TOKEN" />
+<s c="XSD_LANGUAGE" />
+<s c="XSD_NMTOKEN" />
+<s c="XSD_NAME" />
+<s c="XSD_NCNAME" />
+<s c="XSD_ID" />
+<s c="XSD_IDREF" />
+<s c="XSD_IDREFS" />
+<s c="XSD_ENTITY" />
+<s c="XSD_ENTITIES" />
+<s c="XSD_INTEGER" />
+<s c="XSD_NONPOSITIVEINTEGER" />
+<s c="XSD_NEGATIVEINTEGER" />
+<s c="XSD_LONG" />
+<s c="XSD_INT" />
+<s c="XSD_SHORT" />
+<s c="XSD_BYTE" />
+<s c="XSD_NONNEGATIVEINTEGER" />
+<s c="XSD_UNSIGNEDLONG" />
+<s c="XSD_UNSIGNEDINT" />
+<s c="XSD_UNSIGNEDSHORT" />
+<s c="XSD_UNSIGNEDBYTE" />
+<s c="XSD_POSITIVEINTEGER" />
+<s c="XSD_NMTOKENS" />
+<s c="XSD_ANYTYPE" />
+<s c="XSD_ANYXML" />
+<s c="APACHE_MAP" />
+<s c="SOAP_ENC_OBJECT" />
+<s c="SOAP_ENC_ARRAY" />
+<s c="XSD_1999_TIMEINSTANT" />
+<s c="XSD_NAMESPACE" />
+<s c="XSD_1999_NAMESPACE" />
+<s c="SOAP_SINGLE_ELEMENT_ARRAYS" />
+<s c="SOAP_WAIT_ONE_WAY_CALLS" />
+<s c="SOAP_USE_XSI_ARRAY_TYPE" />
+<s c="WSDL_CACHE_NONE" />
+<s c="WSDL_CACHE_DISK" />
+<s c="WSDL_CACHE_MEMORY" />
+<s c="WSDL_CACHE_BOTH" />
+<s c="RAR_HOST_MSDOS" />
+<s c="RAR_HOST_OS2" />
+<s c="RAR_HOST_WIN32" />
+<s c="RAR_HOST_UNIX" />
+<s c="RAR_HOST_BEOS" />
+<s c="IBASE_DEFAULT">The default transaction settings are to be used. This default is determined by the client library, which defines it as IBASE_WRITE|IBASE_CONCURRENCY|IBASE_WAIT in most cases.</s>
+<s c="IBASE_READ">Starts a read-only transaction.</s>
+<s c="IBASE_WRITE">Starts a read-write transaction.</s>
+<s c="IBASE_CONSISTENCY">Starts a transaction with the isolation level set to 'consistency', which means the transaction cannot read from tables that are being modified by other concurrent transactions.</s>
+<s c="IBASE_CONCURRENCY">Starts a transaction with the isolation level set to 'concurrency' (or 'snapshot'), which means the transaction has access to all tables, but cannot see changes that were committed by other transactions after the transaction was started.</s>
+<s c="IBASE_COMMITTED">Starts a transaction with the isolation level set to 'read committed'. This flag should be combined with either IBASE_REC_VERSION or IBASE_REC_NO_VERSION . This isolation level allows access to changes that were committed after the transaction was started. If IBASE_REC_NO_VERSION was specified, only the latest version of a row can be read. If IBASE_REC_VERSION was specified, a row can even be read when a modification to it is pending in a concurrent transaction.</s>
+<s c="IBASE_WAIT">Indicated that a transaction should wait and retry when a conflict occurs.</s>
+<s c="IBASE_NOWAIT">Indicated that a transaction should fail immediately when a conflict occurs.</s>
+<s c="IBASE_FETCH_BLOBS">Also available as IBASE_TEXT for backward compatibility. Causes BLOB contents to be fetched inline, instead of being fetched as BLOB identifiers.</s>
+<s c="IBASE_FETCH_ARRAYS">Causes arrays to be fetched inline. Otherwise, array identifiers are returned. Array identifiers can only be used as arguments to INSERT operations, as no functions to handle array identifiers are currently available.</s>
+<s c="IBASE_UNIXTIME">Causes date and time fields not to be returned as strings, but as UNIX timestamps (the number of seconds since the epoch, which is 1-Jan-1970 0:00 UTC). Might be problematic if used with dates before 1970 on some systems.</s>
+<s c="MING_NEW" />
+<s c="MING_ZLIB" />
+<s c="SWFBUTTON_HIT" />
+<s c="SWFBUTTON_DOWN" />
+<s c="SWFBUTTON_OVER" />
+<s c="SWFBUTTON_UP" />
+<s c="SWFBUTTON_MOUSEUPOUTSIDE" />
+<s c="SWFBUTTON_DRAGOVER" />
+<s c="SWFBUTTON_DRAGOUT" />
+<s c="SWFBUTTON_MOUSEUP" />
+<s c="SWFBUTTON_MOUSEDOWN" />
+<s c="SWFBUTTON_MOUSEOUT" />
+<s c="SWFBUTTON_MOUSEOVER" />
+<s c="SWFFILL_RADIAL_GRADIENT" />
+<s c="SWFFILL_LINEAR_GRADIENT" />
+<s c="SWFFILL_TILED_BITMAP" />
+<s c="SWFFILL_CLIPPED_BITMAP" />
+<s c="SWFTEXTFIELD_HASLENGTH" />
+<s c="SWFTEXTFIELD_NOEDIT" />
+<s c="SWFTEXTFIELD_PASSWORD" />
+<s c="SWFTEXTFIELD_MULTILINE" />
+<s c="SWFTEXTFIELD_WORDWRAP" />
+<s c="SWFTEXTFIELD_DRAWBOX" />
+<s c="SWFTEXTFIELD_NOSELECT" />
+<s c="SWFTEXTFIELD_HTML" />
+<s c="SWFTEXTFIELD_ALIGN_LEFT" />
+<s c="SWFTEXTFIELD_ALIGN_RIGHT" />
+<s c="SWFTEXTFIELD_ALIGN_CENTER" />
+<s c="SWFTEXTFIELD_ALIGN_JUSTIFY" />
+<s c="SWFACTION_ONLOAD" />
+<s c="SWFACTION_ENTERFRAME" />
+<s c="SWFACTION_UNLOAD" />
+<s c="SWFACTION_MOUSEMOVE" />
+<s c="SWFACTION_MOUSEDOWN" />
+<s c="SWFACTION_MOUSEUP" />
+<s c="SWFACTION_KEYDOWN" />
+<s c="SWFACTION_KEYUP" />
+<s c="SWFACTION_DATA" />
+<s c="LDAP_DEREF_NEVER" />
+<s c="LDAP_DEREF_SEARCHING" />
+<s c="LDAP_DEREF_FINDING" />
+<s c="LDAP_DEREF_ALWAYS" />
+<s c="LDAP_OPT_DEREF" />
+<s c="LDAP_OPT_SIZELIMIT" />
+<s c="LDAP_OPT_TIMELIMIT" />
+<s c="LDAP_OPT_NETWORK_TIMEOUT" />
+<s c="LDAP_OPT_PROTOCOL_VERSION" />
+<s c="LDAP_OPT_ERROR_NUMBER" />
+<s c="LDAP_OPT_REFERRALS" />
+<s c="LDAP_OPT_RESTART" />
+<s c="LDAP_OPT_HOST_NAME" />
+<s c="LDAP_OPT_ERROR_STRING" />
+<s c="LDAP_OPT_MATCHED_DN" />
+<s c="LDAP_OPT_SERVER_CONTROLS" />
+<s c="LDAP_OPT_CLIENT_CONTROLS" />
+<s c="LDAP_OPT_DEBUG_LEVEL" />
+<s c="GSLC_SSL_NO_AUTH" />
+<s c="GSLC_SSL_ONEWAY_AUTH" />
+<s c="GSLC_SSL_TWOWAY_AUTH" />
+<s c="IIS_READ" />
+<s c="IIS_WRITE" />
+<s c="IIS_EXECUTE" />
+<s c="IIS_SCRIPT" />
+<s c="IIS_ANONYMOUS" />
+<s c="IIS_BASIC" />
+<s c="IIS_NTLM" />
+<s c="IIS_STARTING" />
+<s c="IIS_STOPPED" />
+<s c="IIS_PAUSED" />
+<s c="IIS_RUNNING" />
+<s c="FBSQL_ASSOC" />
+<s c="FBSQL_NUM" />
+<s c="FBSQL_BOTH" />
+<s c="FBSQL_LOCK_DEFERRED" />
+<s c="FBSQL_LOCK_OPTIMISTIC" />
+<s c="FBSQL_LOCK_PESSIMISTIC" />
+<s c="FBSQL_ISO_READ_UNCOMMITTED" />
+<s c="FBSQL_ISO_READ_COMMITTED" />
+<s c="FBSQL_ISO_REPEATABLE_READ" />
+<s c="FBSQL_ISO_SERIALIZABLE" />
+<s c="FBSQL_ISO_VERSIONED" />
+<s c="FBSQL_UNKNOWN" />
+<s c="FBSQL_STOPPED" />
+<s c="FBSQL_STARTING" />
+<s c="FBSQL_RUNNING" />
+<s c="FBSQL_STOPPING" />
+<s c="FBSQL_NOEXEC" />
+<s c="FBSQL_LOB_DIRECT" />
+<s c="FBSQL_LOB_HANDLE" />
+<s c="POSIX_F_OK" />
+<s c="POSIX_R_OK" />
+<s c="POSIX_W_OK" />
+<s c="POSIX_X_OK" />
+<s c="POSIX_S_IFBLK" />
+<s c="POSIX_S_IFCHR" />
+<s c="POSIX_S_IFIFO" />
+<s c="POSIX_S_IFREG" />
+<s c="POSIX_S_IFSOCK" />
+<s c="RIT_LEAVES_ONLY" />
+<s c="RecursiveIteratorIterator::LEAVES_ONLY" />
+<s c="RecursiveIteratorIterator::SELF_FIRST" />
+<s c="RecursiveIteratorIterator::CHILD_FIRST" />
+<s c="CachingIterator::CALL_TOSTRING" />
+<s c="CachingIterator::CATCH_GET_CHILD" />
+<s c="OGGVORBIS_PCM_U8">Unsigned 8-bit PCM.</s>
+<s c="OGGVORBIS_PCM_S8">Signed 8-bit PCM.</s>
+<s c="OGGVORBIS_PCM_U16_LE">Unsigned 16-bit PCM. Little Endian byte order.</s>
+<s c="OGGVORBIS_PCM_U16_BE">Unsigned 16-bit PCM. Big Endian byte order.</s>
+<s c="OGGVORBIS_PCM_S16_LE">Signed 16-bit PCM. Little Endian byte order.</s>
+<s c="OGGVORBIS_PCM_S16_BE">Signed 16-bit PCM. Big Endian byte order.</s>
+<s c="CRYPT_SALT_LENGTH" />
+<s c="CRYPT_STD_DES" />
+<s c="CRYPT_EXT_DES" />
+<s c="CRYPT_MD5" />
+<s c="CRYPT_BLOWFISH" />
+<s c="HTML_SPECIALCHARS" />
+<s c="HTML_ENTITIES" />
+<s c="ENT_COMPAT" />
+<s c="ENT_QUOTES" />
+<s c="ENT_NOQUOTES" />
+<s c="CHAR_MAX" />
+<s c="LC_CTYPE" />
+<s c="LC_NUMERIC" />
+<s c="LC_TIME" />
+<s c="LC_COLLATE" />
+<s c="LC_MONETARY" />
+<s c="LC_ALL" />
+<s c="LC_MESSAGES" />
+<s c="STR_PAD_LEFT" />
+<s c="STR_PAD_RIGHT" />
+<s c="STR_PAD_BOTH" />
+<s c="CASE_LOWER" />
+<s c="CASE_UPPER" />
+<s c="SORT_ASC" />
+<s c="SORT_DESC" />
+<s c="SORT_REGULAR" />
+<s c="SORT_NUMERIC" />
+<s c="SORT_STRING" />
+<s c="SORT_LOCALE_STRING" />
+<s c="COUNT_NORMAL" />
+<s c="COUNT_RECURSIVE" />
+<s c="EXTR_OVERWRITE" />
+<s c="EXTR_SKIP" />
+<s c="EXTR_PREFIX_SAME" />
+<s c="EXTR_PREFIX_ALL" />
+<s c="EXTR_PREFIX_INVALID" />
+<s c="EXTR_PREFIX_IF_EXISTS" />
+<s c="EXTR_IF_EXISTS" />
+<s c="EXTR_REFS" />
+<s c="LOG_CONS">if there is an error while sending data to the system logger, write directly to the system console</s>
+<s c="LOG_NDELAY">open the connection to the logger immediately</s>
+<s c="LOG_ODELAY">(default) delay opening the connection until the first message is logged</s>
+<s c="LOG_NOWAIT"></s>
+<s c="LOG_PERROR">print log message also to standard error</s>
+<s c="LOG_PID">include PID with each message</s>
+<s c="LOG_AUTH">security/authorization messages (use LOG_AUTHPRIV instead in systems where that constant is defined)</s>
+<s c="LOG_AUTHPRIV">security/authorization messages (private)</s>
+<s c="LOG_CRON">clock daemon (cron and at)</s>
+<s c="LOG_DAEMON">other system daemons</s>
+<s c="LOG_KERN">kernel messages</s>
+<s c="LOG_LPR">line printer subsystem</s>
+<s c="LOG_MAIL">mail subsystem</s>
+<s c="LOG_NEWS">USENET news subsystem</s>
+<s c="LOG_SYSLOG">messages generated internally by syslogd</s>
+<s c="LOG_USER">generic user-level messages</s>
+<s c="LOG_UUCP">UUCP subsystem</s>
+<s c="LOG_EMERG">system is unusable</s>
+<s c="LOG_ALERT">action must be taken immediately</s>
+<s c="LOG_CRIT">critical conditions</s>
+<s c="LOG_ERR">error conditions</s>
+<s c="LOG_WARNING">warning conditions</s>
+<s c="LOG_NOTICE">normal, but significant, condition</s>
+<s c="LOG_INFO">informational message</s>
+<s c="LOG_DEBUG">debug-level message</s>
+<s c="DNS_A">IPv4 Address Resource</s>
+<s c="DNS_MX">Mail Exchanger Resource</s>
+<s c="DNS_CNAME">Alias (Canonical Name) Resource</s>
+<s c="DNS_NS">Authoritative Name Server Resource</s>
+<s c="DNS_PTR">Pointer Resource</s>
+<s c="DNS_HINFO">Host Info Resource (See IANA's Operating System Names for the meaning of these values)</s>
+<s c="DNS_SOA">Start of Authority Resource</s>
+<s c="DNS_TXT">Text Resource</s>
+<s c="DNS_ANY">Any Resource Record. On most systems this returns all resource records, however it should not be counted upon for critical uses. Try DNS_ALL instead.</s>
+<s c="DNS_AAAA">IPv6 Address Resource</s>
+<s c="DNS_ALL">Iteratively query the name server for each available record type.</s>
+<s c="OCI_DEFAULT" />
+<s c="OCI_DESCRIBE_ONLY" />
+<s c="OCI_COMMIT_ON_SUCCESS" />
+<s c="OCI_EXACT_FETCH" />
+<s c="OCI_SYSDATE" />
+<s c="OCI_B_BFILE" />
+<s c="OCI_B_CFILEE" />
+<s c="OCI_B_CLOB" />
+<s c="OCI_B_BLOB" />
+<s c="OCI_B_ROWID" />
+<s c="OCI_B_CURSOR" />
+<s c="OCI_B_NTY" />
+<s c="OCI_B_SQLT_NTY" />
+<s c="OCI_B_BIN" />
+<s c="SQLT_BFILEE" />
+<s c="SQLT_CFILEE" />
+<s c="SQLT_CLOB" />
+<s c="SQLT_BLOB" />
+<s c="SQLT_RDD" />
+<s c="SQLT_NTY" />
+<s c="SQLT_LNG" />
+<s c="SQLT_LBI" />
+<s c="SQLT_BIN" />
+<s c="SQLT_NUM" />
+<s c="SQLT_INT" />
+<s c="SQLT_AFC" />
+<s c="SQLT_CHR" />
+<s c="SQLT_VCS" />
+<s c="SQLT_AVC" />
+<s c="SQLT_STR" />
+<s c="SQLT_LVC" />
+<s c="SQLT_FLT" />
+<s c="SQLT_ODT" />
+<s c="SQLT_BDOUBLE" />
+<s c="SQLT_BFLOAT" />
+<s c="OCI_FETCHSTATEMENT_BY_COLUMN" />
+<s c="OCI_FETCHSTATEMENT_BY_ROW" />
+<s c="OCI_ASSOC" />
+<s c="OCI_NUM" />
+<s c="OCI_BOTH" />
+<s c="OCI_RETURN_NULLS" />
+<s c="OCI_RETURN_LOBS" />
+<s c="OCI_DTYPE_FILE" />
+<s c="OCI_DTYPE_LOB" />
+<s c="OCI_DTYPE_ROWID" />
+<s c="OCI_D_FILE" />
+<s c="OCI_D_LOB" />
+<s c="OCI_D_ROWID" />
+<s c="OCI_SYSOPER" />
+<s c="OCI_SYSDBA" />
+<s c="OCI_LOB_BUFFER_FREE" />
+<s c="OCI_TEMP_CLOB" />
+<s c="OCI_TEMP_BLOB" />
+<s c="GMP_ROUND_ZERO" />
+<s c="GMP_ROUND_PLUSINF" />
+<s c="GMP_ROUND_MINUSINF" />
+<s c="GMP_VERSION" />
+<s c="PGSQL_ASSOC" />
+<s c="PGSQL_NUM" />
+<s c="PGSQL_BOTH" />
+<s c="PGSQL_CONNECT_FORCE_NEW" />
+<s c="PGSQL_CONNECTION_BAD" />
+<s c="PGSQL_CONNECTION_OK" />
+<s c="PGSQL_SEEK_SET" />
+<s c="PGSQL_SEEK_CUR" />
+<s c="PGSQL_SEEK_END" />
+<s c="PGSQL_EMPTY_QUERY" />
+<s c="PGSQL_COMMAND_OK" />
+<s c="PGSQL_TUPLES_OK" />
+<s c="PGSQL_COPY_OUT" />
+<s c="PGSQL_COPY_IN" />
+<s c="PGSQL_BAD_RESPONSE" />
+<s c="PGSQL_NONFATAL_ERROR" />
+<s c="PGSQL_FATAL_ERROR" />
+<s c="PGSQL_TRANSACTION_IDLE" />
+<s c="PGSQL_TRANSACTION_ACTIVE" />
+<s c="PGSQL_TRANSACTION_INTRANS" />
+<s c="PGSQL_TRANSACTION_INERROR" />
+<s c="PGSQL_TRANSACTION_UNKNOWN" />
+<s c="PGSQL_DIAG_SEVERITY" />
+<s c="PGSQL_DIAG_SQLSTATE" />
+<s c="PGSQL_DIAG_MESSAGE_PRIMARY" />
+<s c="PGSQL_DIAG_MESSAGE_DETAIL" />
+<s c="PGSQL_DIAG_MESSAGE_HINT" />
+<s c="PGSQL_DIAG_STATEMENT_POSITION" />
+<s c="PGSQL_DIAG_INTERNAL_POSITION" />
+<s c="PG_DIAG_STATEMENT_POSITION" />
+<s c="PG_DIAG_INTERNAL_QUERY" />
+<s c="PGSQL_DIAG_INTERNAL_QUERY" />
+<s c="PGSQL_DIAG_CONTEXT" />
+<s c="PGSQL_DIAG_SOURCE_FILE" />
+<s c="PGSQL_DIAG_SOURCE_LINE" />
+<s c="PGSQL_DIAG_SOURCE_FUNCTION" />
+<s c="PGSQL_ERRORS_TERSE" />
+<s c="PGSQL_ERRORS_DEFAULT" />
+<s c="PGSQL_ERRORS_VERBOSE" />
+<s c="PGSQL_STATUS_LONG" />
+<s c="PGSQL_STATUS_STRING" />
+<s c="PGSQL_CONV_IGNORE_DEFAULT" />
+<s c="PGSQL_CONV_FORCE_NULL" />
+<s c="MYSQL_CLIENT_COMPRESS">Use compression protocol</s>
+<s c="MYSQL_CLIENT_IGNORE_SPACE">Allow space after function names</s>
+<s c="MYSQL_CLIENT_INTERACTIVE">Allow interactive_timeout seconds (instead of wait_timeout) of inactivity before closing the connection.</s>
+<s c="MYSQL_CLIENT_SSL">Use SSL encryption. This flag is only available with version 4.x of the MySQL client library or newer. Version 3.23.x is bundled both with PHP 4 and Windows binaries of PHP 5.</s>
+<s c="MYSQL_ASSOC">Columns are returned into the array having the fieldname as the array index.</s>
+<s c="MYSQL_BOTH">Columns are returned into the array having both a numerical index and the fieldname as the array index.</s>
+<s c="MYSQL_NUM">Columns are returned into the array having a numerical index to the fields. This index starts with 0, the first field in the result.</s>
+<s c="JSON_ERROR_NONE" />
+<s c="JSON_ERROR_DEPTH" />
+<s c="JSON_ERROR_CTRL_CHAR" />
+<s c="JSON_ERROR_SYNTAX" />
+<s c="NIL" />
+<s c="OP_DEBUG" />
+<s c="OP_READONLY" />
+<s c="OP_ANONYMOUS" />
+<s c="OP_SHORTCACHE" />
+<s c="OP_SILENT" />
+<s c="OP_PROTOTYPE" />
+<s c="OP_HALFOPEN" />
+<s c="OP_EXPUNGE" />
+<s c="OP_SECURE" />
+<s c="CL_EXPUNGE" />
+<s c="FT_UID" />
+<s c="FT_PEEK" />
+<s c="FT_NOT" />
+<s c="FT_INTERNAL" />
+<s c="FT_PREFETCHTEXT" />
+<s c="ST_UID" />
+<s c="ST_SILENT" />
+<s c="ST_SET" />
+<s c="CP_UID" />
+<s c="CP_MOVE" />
+<s c="SE_UID" />
+<s c="SE_FREE" />
+<s c="SE_NOPREFETCH" />
+<s c="SO_FREE" />
+<s c="SO_NOSERVER" />
+<s c="SA_MESSAGES" />
+<s c="SA_RECENT" />
+<s c="SA_UNSEEN" />
+<s c="SA_UIDNEXT" />
+<s c="SA_UIDVALIDITY" />
+<s c="SA_ALL" />
+<s c="LATT_NOINFERIORS" />
+<s c="LATT_NOSELECT" />
+<s c="LATT_MARKED" />
+<s c="LATT_UNMARKED" />
+<s c="SORTDATE" />
+<s c="SORTARRIVAL" />
+<s c="SORTFROM" />
+<s c="SORTSUBJECT" />
+<s c="SORTTO" />
+<s c="SORTCC" />
+<s c="SORTSIZE" />
+<s c="TYPETEXT" />
+<s c="TYPEMULTIPART" />
+<s c="TYPEMESSAGE" />
+<s c="TYPEAPPLICATION" />
+<s c="TYPEAUDIO" />
+<s c="TYPEIMAGE" />
+<s c="TYPEVIDEO" />
+<s c="TYPEOTHER" />
+<s c="ENC7BIT" />
+<s c="ENC8BIT" />
+<s c="ENCBINARY" />
+<s c="ENCBASE64" />
+<s c="ENCQUOTEDPRINTABLE" />
+<s c="ENCOTHER" />
+<s c="IMAP_OPENTIMEOUT" />
+<s c="IMAP_READTIMEOUT" />
+<s c="IMAP_WRITETIMEOUT" />
+<s c="IMAP_CLOSETIMEOUT" />
+<s c="LATT_REFERRAL" />
+<s c="LATT_HASCHILDREN" />
+<s c="LATT_HASNOCHILDREN" />
+<s c="TYPEMODEL" />
+<s c="GEOIP_COUNTRY_EDITION" />
+<s c="GEOIP_REGION_EDITION_REV0" />
+<s c="GEOIP_CITY_EDITION_REV0" />
+<s c="GEOIP_ORG_EDITION" />
+<s c="GEOIP_ISP_EDITION" />
+<s c="GEOIP_CITY_EDITION_REV1" />
+<s c="GEOIP_REGION_EDITION_REV1" />
+<s c="GEOIP_PROXY_EDITION" />
+<s c="GEOIP_ASNUM_EDITION" />
+<s c="GEOIP_NETSPEED_EDITION" />
+<s c="GEOIP_DOMAIN_EDITION" />
+<s c="GEOIP_UNKNOWN_SPEED" />
+<s c="GEOIP_DIALUP_SPEED" />
+<s c="GEOIP_CABLEDSL_SPEED" />
+<s c="GEOIP_CORPORATE_SPEED" />
+<s c="SDO_DAS_ChangeSummary::NONE=0" />
+<s c="SDO_DAS_ChangeSummary::MODIFICATION=1" />
+<s c="SDO_DAS_ChangeSummary::ADDITION=2" />
+<s c="SDO_DAS_ChangeSummary::DELETION=3" />
+<s c="WIN32_SERVICE_CONTROL_CONTINUE" />
+<s c="WIN32_SERVICE_CONTROL_INTERROGATE" />
+<s c="WIN32_SERVICE_CONTROL_PAUSE" />
+<s c="WIN32_SERVICE_CONTROL_STOP" />
+<s c="WIN32_SERVICE_CONTROL_HARDWAREPROFILECHANGE" />
+<s c="WIN32_SERVICE_CONTROL_POWEREVENT" />
+<s c="WIN32_SERVICE_CONTROL_SESSIONCHANGE" />
+<s c="WIN32_ERROR_CALL_NOT_IMPLEMENTED" />
+<s c="WIN32_NO_ERROR" />
+<s c="WIN32_SERVICE_RUNNING" />
+<s c="WIN32_SERVICE_STOPPED" />
+<s c="WIN32_SERVICE_STOP_PENDING" />
+<s c="WIN32_SERVICE_WIN32_OWN_PROCESS" />
+<s c="WIN32_SERVICE_INTERACTIVE_PROCESS" />
+<s c="WIN32_SERVICE_START_PENDING" />
+<s c="WIN32_SERVICE_CONTINUE_PENDING" />
+<s c="WIN32_SERVICE_PAUSE_PENDING" />
+<s c="WIN32_SERVICE_PAUSED" />
+<s c="WIN32_SERVICE_ACCEPT_NETBINDCHANGE" />
+<s c="WIN32_SERVICE_ACCEPT_PARAMCHANGE" />
+<s c="WIN32_SERVICE_ACCEPT_PAUSE_CONTINUE" />
+<s c="WIN32_SERVICE_ACCEPT_SHUTDOWN" />
+<s c="WIN32_SERVICE_ACCEPT_STOP" />
+<s c="WIN32_SERVICE_ACCEPT_HARDWAREPROFILECHANGE" />
+<s c="WIN32_SERVICE_ACCEPT_POWEREVENT" />
+<s c="WIN32_SERVICE_ACCEPT_SESSIONCHANGE" />
+<s c="WIN32_SERVICE_FILE_SYSTEM_DRIVER" />
+<s c="WIN32_SERVICE_KERNEL_DRIVER" />
+<s c="WIN32_SERVICE_WIN32_SHARE_PROCESS" />
+<s c="WIN32_SERVICE_RUNS_IN_SYSTEM_PROCESS" />
+<s c="ICONV_IMPL">string</s>
+<s c="ICONV_VERSION">string</s>
+<s c="ICONV_MIME_DECODE_STRICT">integer</s>
+<s c="ICONV_MIME_DECODE_CONTINUE_ON_ERROR">integer</s>
+<s c="SVN_REVISION_HEAD" />
+<s c="SVN_AUTH_PARAM_DEFAULT_USERNAME" />
+<s c="SVN_AUTH_PARAM_DEFAULT_PASSWORD" />
+<s c="SVN_AUTH_PARAM_NON_INTERACTIVE" />
+<s c="SVN_AUTH_PARAM_DONT_STORE_PASSWORDS" />
+<s c="SVN_AUTH_PARAM_NO_AUTH_CACHE" />
+<s c="SVN_AUTH_PARAM_SSL_SERVER_FAILURES" />
+<s c="SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO" />
+<s c="SVN_AUTH_PARAM_CONFIG" />
+<s c="SVN_AUTH_PARAM_SERVER_GROUP" />
+<s c="SVN_AUTH_PARAM_CONFIG_DIR" />
+<s c="PHP_SVN_AUTH_PARAM_IGNORE_SSL_VERIFY_ERRORS" />
+<s c="SVN_FS_CONFIG_FS_TYPE" />
+<s c="SVN_FS_TYPE_BDB" />
+<s c="SVN_FS_TYPE_FSFS" />
+<s c="SVN_PROP_REVISION_DATE" />
+<s c="SVN_PROP_REVISION_ORIG_DATE" />
+<s c="SVN_PROP_REVISION_AUTHOR" />
+<s c="SVN_PROP_REVISION_LOG" />
+<s c="SVN_WC_STATUS_NONE" />
+<s c="SVN_WC_STATUS_UNVERSIONED" />
+<s c="SVN_WC_STATUS_NORMAL" />
+<s c="SVN_WC_STATUS_ADDED" />
+<s c="SVN_WC_STATUS_MISSING" />
+<s c="SVN_WC_STATUS_DELETED" />
+<s c="SVN_WC_STATUS_REPLACED" />
+<s c="SVN_WC_STATUS_MODIFIED" />
+<s c="SVN_WC_STATUS_MERGED" />
+<s c="SVN_WC_STATUS_CONFLICTED" />
+<s c="SVN_WC_STATUS_IGNORED" />
+<s c="SVN_WC_STATUS_OBSTRUCTED" />
+<s c="SVN_WC_STATUS_EXTERNAL" />
+<s c="SVN_WC_STATUS_INCOMPLETE" />
+<s c="SVN_NODE_NONE" />
+<s c="SVN_NODE_FILE" />
+<s c="SVN_NODE_DIR" />
+<s c="SVN_NODE_UNKNOWN" />
+<s c="FILEINFO_NONE" />
+<s c="FILEINFO_SYMLINK" />
+<s c="FILEINFO_MIME" />
+<s c="FILEINFO_COMPRESS" />
+<s c="FILEINFO_DEVICES" />
+<s c="FILEINFO_CONTINUE" />
+<s c="FILEINFO_PRESERVE_ATIME" />
+<s c="FILEINFO_RAW" />
+<s c="GLOB_BRACE" />
+<s c="GLOB_ONLYDIR" />
+<s c="GLOB_MARK" />
+<s c="GLOB_NOSORT" />
+<s c="GLOB_NOCHECK" />
+<s c="GLOB_NOESCAPE" />
+<s c="PATHINFO_DIRNAME" />
+<s c="PATHINFO_BASENAME" />
+<s c="PATHINFO_EXTENSION" />
+<s c="PATHINFO_FILENAME" />
+<s c="FILE_USE_INCLUDE_PATH" />
+<s c="FILE_APPEND" />
+<s c="FILE_IGNORE_NEW_LINES" />
+<s c="FILE_SKIP_EMPTY_LINES" />
+<s c="FILE_BINARY" />
+<s c="FILE_TEXT" />
+<s c="INI_SCANNER_NORMAL" />
+<s c="INI_SCANNER_RAW" />
+<s c="ZIPARCHIVE::CREATE" />
+<s c="ZIPARCHIVE::OVERWRITE" />
+<s c="ZIPARCHIVE::EXCL" />
+<s c="ZIPARCHIVE::CHECKCONS" />
+<s c="ZIPARCHIVE::FL_NOCASE" />
+<s c="ZIPARCHIVE::FL_NODIR" />
+<s c="ZIPARCHIVE::FL_COMPRESSED" />
+<s c="ZIPARCHIVE::FL_UNCHANGED" />
+<s c="ZIPARCHIVE::CM_DEFAULT" />
+<s c="ZIPARCHIVE::CM_STORE" />
+<s c="ZIPARCHIVE::CM_SHRINK" />
+<s c="ZIPARCHIVE::CM_REDUCE_1" />
+<s c="ZIPARCHIVE::CM_REDUCE_2" />
+<s c="ZIPARCHIVE::CM_REDUCE_3" />
+<s c="ZIPARCHIVE::CM_REDUCE_4" />
+<s c="ZIPARCHIVE::CM_IMPLODE" />
+<s c="ZIPARCHIVE::CM_DEFLATE" />
+<s c="ZIPARCHIVE::CM_DEFLATE64" />
+<s c="ZIPARCHIVE::CM_PKWARE_IMPLODE" />
+<s c="ZIPARCHIVE::CM_BZIP2" />
+<s c="ZIPARCHIVE::ER_OK" />
+<s c="ZIPARCHIVE::ER_MULTIDISK" />
+<s c="ZIPARCHIVE::ER_RENAME" />
+<s c="ZIPARCHIVE::ER_CLOSE" />
+<s c="ZIPARCHIVE::ER_SEEK" />
+<s c="ZIPARCHIVE::ER_READ" />
+<s c="ZIPARCHIVE::ER_WRITE" />
+<s c="ZIPARCHIVE::ER_CRC" />
+<s c="ZIPARCHIVE::ER_ZIPCLOSED" />
+<s c="ZIPARCHIVE::ER_NOENT" />
+<s c="ZIPARCHIVE::ER_EXISTS" />
+<s c="ZIPARCHIVE::ER_OPEN" />
+<s c="ZIPARCHIVE::ER_TMPOPEN" />
+<s c="ZIPARCHIVE::ER_ZLIB" />
+<s c="ZIPARCHIVE::ER_MEMORY" />
+<s c="ZIPARCHIVE::ER_CHANGED" />
+<s c="ZIPARCHIVE::ER_COMPNOTSUPP" />
+<s c="ZIPARCHIVE::ER_EOF" />
+<s c="ZIPARCHIVE::ER_INVAL" />
+<s c="ZIPARCHIVE::ER_NOZIP" />
+<s c="ZIPARCHIVE::ER_INTERNAL" />
+<s c="ZIPARCHIVE::ER_INCONS" />
+<s c="ZIPARCHIVE::ER_REMOVE" />
+<s c="ZIPARCHIVE::ER_DELETED" />
+<s c="LIBXML_COMPACT" />
+<s c="LIBXML_DTDATTR" />
+<s c="LIBXML_DTDLOAD" />
+<s c="LIBXML_DTDVALID" />
+<s c="LIBXML_NOBLANKS" />
+<s c="LIBXML_NOCDATA" />
+<s c="LIBXML_NOEMPTYTAG" />
+<s c="LIBXML_NOENT" />
+<s c="LIBXML_NOERROR" />
+<s c="LIBXML_NONET" />
+<s c="LIBXML_NOWARNING" />
+<s c="LIBXML_NOXMLDECL" />
+<s c="LIBXML_NSCLEAN" />
+<s c="LIBXML_XINCLUDE" />
+<s c="LIBXML_ERR_ERROR" />
+<s c="LIBXML_ERR_FATAL" />
+<s c="LIBXML_ERR_NONE" />
+<s c="LIBXML_ERR_WARNING" />
+<s c="LIBXML_VERSION" />
+<s c="LIBXML_DOTTED_VERSION" />
+<s c="CLASSKIT_ACC_PRIVATE" />
+<s c="CLASSKIT_ACC_PROTECTED" />
+<s c="CLASSKIT_ACC_PUBLIC" />
+<s c="MSSQL_ASSOC" />
+<s c="MSSQL_NUM" />
+<s c="MSSQL_BOTH" />
+<s c="SQLTEXT" />
+<s c="SQLVARCHAR" />
+<s c="SQLCHAR" />
+<s c="SQLINT1" />
+<s c="SQLINT2" />
+<s c="SQLINT4" />
+<s c="SQLBIT" />
+<s c="SQLFLT4" />
+<s c="SQLFLT8" />
+<s c="CURLOPT_AUTOREFERER" />
+<s c="CURLOPT_COOKIESESSION" />
+<s c="CURLOPT_DNS_USE_GLOBAL_CACHE" />
+<s c="CURLOPT_DNS_CACHE_TIMEOUT" />
+<s c="CURLOPT_FTP_SSL" />
+<s c="CURLFTPSSL_TRY" />
+<s c="CURLFTPSSL_ALL" />
+<s c="CURLFTPSSL_CONTROL" />
+<s c="CURLFTPSSL_NONE" />
+<s c="CURLOPT_PRIVATE" />
+<s c="CURLOPT_FTPSSLAUTH" />
+<s c="CURLOPT_PORT" />
+<s c="CURLOPT_FILE" />
+<s c="CURLOPT_READDATA" />
+<s c="CURLOPT_INFILE" />
+<s c="CURLOPT_INFILESIZE" />
+<s c="CURLOPT_URL" />
+<s c="CURLOPT_PROXY" />
+<s c="CURLOPT_VERBOSE" />
+<s c="CURLOPT_HEADER" />
+<s c="CURLOPT_HTTPHEADER" />
+<s c="CURLOPT_NOPROGRESS" />
+<s c="CURLOPT_NOBODY" />
+<s c="CURLOPT_FAILONERROR" />
+<s c="CURLOPT_UPLOAD" />
+<s c="CURLOPT_POST" />
+<s c="CURLOPT_FTPLISTONLY" />
+<s c="CURLOPT_FTPAPPEND" />
+<s c="CURLOPT_FTP_CREATE_MISSING_DIRS" />
+<s c="CURLOPT_NETRC" />
+<s c="CURLOPT_FOLLOWLOCATION" />
+<s c="CURLOPT_FTPASCII" />
+<s c="CURLOPT_PUT" />
+<s c="CURLOPT_MUTE" />
+<s c="CURLOPT_USERPWD" />
+<s c="CURLOPT_PROXYUSERPWD" />
+<s c="CURLOPT_RANGE" />
+<s c="CURLOPT_TIMEOUT" />
+<s c="CURLOPT_TIMEOUT_MS" />
+<s c="CURLOPT_TCP_NODELAY" />
+<s c="CURLOPT_POSTFIELDS" />
+<s c="CURLOPT_REFERER" />
+<s c="CURLOPT_USERAGENT" />
+<s c="CURLOPT_FTPPORT" />
+<s c="CURLOPT_FTP_USE_EPSV" />
+<s c="CURLOPT_LOW_SPEED_LIMIT" />
+<s c="CURLOPT_LOW_SPEED_TIME" />
+<s c="CURLOPT_RESUME_FROM" />
+<s c="CURLOPT_COOKIE" />
+<s c="CURLOPT_SSLCERT" />
+<s c="CURLOPT_SSLCERTPASSWD" />
+<s c="CURLOPT_WRITEHEADER" />
+<s c="CURLOPT_SSL_VERIFYHOST" />
+<s c="CURLOPT_COOKIEFILE" />
+<s c="CURLOPT_SSLVERSION" />
+<s c="CURLOPT_TIMECONDITION" />
+<s c="CURLOPT_TIMEVALUE" />
+<s c="CURLOPT_CUSTOMREQUEST" />
+<s c="CURLOPT_STDERR" />
+<s c="CURLOPT_TRANSFERTEXT" />
+<s c="CURLOPT_RETURNTRANSFER" />
+<s c="CURLOPT_QUOTE" />
+<s c="CURLOPT_POSTQUOTE" />
+<s c="CURLOPT_INTERFACE" />
+<s c="CURLOPT_KRB4LEVEL" />
+<s c="CURLOPT_HTTPPROXYTUNNEL" />
+<s c="CURLOPT_FILETIME" />
+<s c="CURLOPT_WRITEFUNCTION" />
+<s c="CURLOPT_READFUNCTION" />
+<s c="CURLOPT_PASSWDFUNCTION" />
+<s c="CURLOPT_HEADERFUNCTION" />
+<s c="CURLOPT_MAXREDIRS" />
+<s c="CURLOPT_MAXCONNECTS" />
+<s c="CURLOPT_CLOSEPOLICY" />
+<s c="CURLOPT_FRESH_CONNECT" />
+<s c="CURLOPT_FORBID_REUSE" />
+<s c="CURLOPT_RANDOM_FILE" />
+<s c="CURLOPT_EGDSOCKET" />
+<s c="CURLOPT_CONNECTTIMEOUT" />
+<s c="CURLOPT_CONNECTTIMEOUT_MS" />
+<s c="CURLOPT_SSL_VERIFYPEER" />
+<s c="CURLOPT_CAINFO" />
+<s c="CURLOPT_CAPATH" />
+<s c="CURLOPT_COOKIEJAR" />
+<s c="CURLOPT_SSL_CIPHER_LIST" />
+<s c="CURLOPT_BINARYTRANSFER" />
+<s c="CURLOPT_NOSIGNAL" />
+<s c="CURLOPT_PROXYTYPE" />
+<s c="CURLOPT_BUFFERSIZE" />
+<s c="CURLOPT_HTTPGET" />
+<s c="CURLOPT_HTTP_VERSION" />
+<s c="CURLOPT_SSLKEY" />
+<s c="CURLOPT_SSLKEYTYPE" />
+<s c="CURLOPT_SSLKEYPASSWD" />
+<s c="CURLOPT_SSLENGINE" />
+<s c="CURLOPT_SSLENGINE_DEFAULT" />
+<s c="CURLOPT_SSLCERTTYPE" />
+<s c="CURLOPT_CRLF" />
+<s c="CURLOPT_ENCODING" />
+<s c="CURLOPT_PROXYPORT" />
+<s c="CURLOPT_UNRESTRICTED_AUTH" />
+<s c="CURLOPT_FTP_USE_EPRT" />
+<s c="CURLOPT_HTTP200ALIASES" />
+<s c="CURLOPT_HTTPAUTH" />
+<s c="CURLAUTH_BASIC" />
+<s c="CURLAUTH_DIGEST" />
+<s c="CURLAUTH_GSSNEGOTIATE" />
+<s c="CURLAUTH_NTLM" />
+<s c="CURLAUTH_ANY" />
+<s c="CURLAUTH_ANYSAFE" />
+<s c="CURLOPT_PROXYAUTH" />
+<s c="CURLCLOSEPOLICY_LEAST_RECENTLY_USED" />
+<s c="CURLCLOSEPOLICY_LEAST_TRAFFIC" />
+<s c="CURLCLOSEPOLICY_SLOWEST" />
+<s c="CURLCLOSEPOLICY_CALLBACK" />
+<s c="CURLCLOSEPOLICY_OLDEST" />
+<s c="CURLINFO_PRIVATE" />
+<s c="CURLINFO_EFFECTIVE_URL" />
+<s c="CURLINFO_HTTP_CODE" />
+<s c="CURLINFO_HEADER_OUT" />
+<s c="CURLINFO_HEADER_SIZE" />
+<s c="CURLINFO_REQUEST_SIZE" />
+<s c="CURLINFO_TOTAL_TIME" />
+<s c="CURLINFO_NAMELOOKUP_TIME" />
+<s c="CURLINFO_CONNECT_TIME" />
+<s c="CURLINFO_PRETRANSFER_TIME" />
+<s c="CURLINFO_SIZE_UPLOAD" />
+<s c="CURLINFO_SIZE_DOWNLOAD" />
+<s c="CURLINFO_SPEED_DOWNLOAD" />
+<s c="CURLINFO_SPEED_UPLOAD" />
+<s c="CURLINFO_FILETIME" />
+<s c="CURLINFO_SSL_VERIFYRESULT" />
+<s c="CURLINFO_CONTENT_LENGTH_DOWNLOAD" />
+<s c="CURLINFO_CONTENT_LENGTH_UPLOAD" />
+<s c="CURLINFO_STARTTRANSFER_TIME" />
+<s c="CURLINFO_CONTENT_TYPE" />
+<s c="CURLINFO_REDIRECT_TIME" />
+<s c="CURLINFO_REDIRECT_COUNT" />
+<s c="CURL_TIMECOND_IFMODSINCE" />
+<s c="CURL_TIMECOND_IFUNMODSINCE" />
+<s c="CURL_TIMECOND_LASTMOD" />
+<s c="CURL_VERSION_IPV6" />
+<s c="CURL_VERSION_KERBEROS4" />
+<s c="CURL_VERSION_SSL" />
+<s c="CURL_VERSION_LIBZ" />
+<s c="CURLVERSION_NOW" />
+<s c="CURLE_OK" />
+<s c="CURLE_UNSUPPORTED_PROTOCOL" />
+<s c="CURLE_FAILED_INIT" />
+<s c="CURLE_URL_MALFORMAT" />
+<s c="CURLE_URL_MALFORMAT_USER" />
+<s c="CURLE_COULDNT_RESOLVE_PROXY" />
+<s c="CURLE_COULDNT_RESOLVE_HOST" />
+<s c="CURLE_COULDNT_CONNECT" />
+<s c="CURLE_FTP_WEIRD_SERVER_REPLY" />
+<s c="CURLE_FTP_ACCESS_DENIED" />
+<s c="CURLE_FTP_USER_PASSWORD_INCORRECT" />
+<s c="CURLE_FTP_WEIRD_PASS_REPLY" />
+<s c="CURLE_FTP_WEIRD_USER_REPLY" />
+<s c="CURLE_FTP_WEIRD_PASV_REPLY" />
+<s c="CURLE_FTP_WEIRD_227_FORMAT" />
+<s c="CURLE_FTP_CANT_GET_HOST" />
+<s c="CURLE_FTP_CANT_RECONNECT" />
+<s c="CURLE_FTP_COULDNT_SET_BINARY" />
+<s c="CURLE_PARTIAL_FILE" />
+<s c="CURLE_FTP_COULDNT_RETR_FILE" />
+<s c="CURLE_FTP_WRITE_ERROR" />
+<s c="CURLE_FTP_QUOTE_ERROR" />
+<s c="CURLE_HTTP_NOT_FOUND" />
+<s c="CURLE_WRITE_ERROR" />
+<s c="CURLE_MALFORMAT_USER" />
+<s c="CURLE_FTP_COULDNT_STOR_FILE" />
+<s c="CURLE_READ_ERROR" />
+<s c="CURLE_OUT_OF_MEMORY" />
+<s c="CURLE_OPERATION_TIMEOUTED" />
+<s c="CURLE_FTP_COULDNT_SET_ASCII" />
+<s c="CURLE_FTP_PORT_FAILED" />
+<s c="CURLE_FTP_COULDNT_USE_REST" />
+<s c="CURLE_FTP_COULDNT_GET_SIZE" />
+<s c="CURLE_HTTP_RANGE_ERROR" />
+<s c="CURLE_HTTP_POST_ERROR" />
+<s c="CURLE_SSL_CONNECT_ERROR" />
+<s c="CURLE_FTP_BAD_DOWNLOAD_RESUME" />
+<s c="CURLE_FILE_COULDNT_READ_FILE" />
+<s c="CURLE_LDAP_CANNOT_BIND" />
+<s c="CURLE_LDAP_SEARCH_FAILED" />
+<s c="CURLE_LIBRARY_NOT_FOUND" />
+<s c="CURLE_FUNCTION_NOT_FOUND" />
+<s c="CURLE_ABORTED_BY_CALLBACK" />
+<s c="CURLE_BAD_FUNCTION_ARGUMENT" />
+<s c="CURLE_BAD_CALLING_ORDER" />
+<s c="CURLE_HTTP_PORT_FAILED" />
+<s c="CURLE_BAD_PASSWORD_ENTERED" />
+<s c="CURLE_TOO_MANY_REDIRECTS" />
+<s c="CURLE_UNKNOWN_TELNET_OPTION" />
+<s c="CURLE_TELNET_OPTION_SYNTAX" />
+<s c="CURLE_OBSOLETE" />
+<s c="CURLE_SSL_PEER_CERTIFICATE" />
+<s c="CURLE_GOT_NOTHING" />
+<s c="CURLE_SSL_ENGINE_NOTFOUND" />
+<s c="CURLE_SSL_ENGINE_SETFAILED" />
+<s c="CURLE_SEND_ERROR" />
+<s c="CURLE_RECV_ERROR" />
+<s c="CURLE_SHARE_IN_USE" />
+<s c="CURLE_SSL_CERTPROBLEM" />
+<s c="CURLE_SSL_CIPHER" />
+<s c="CURLE_SSL_CACERT" />
+<s c="CURLE_BAD_CONTENT_ENCODING" />
+<s c="CURLE_LDAP_INVALID_URL" />
+<s c="CURLE_FILESIZE_EXCEEDED" />
+<s c="CURLE_FTP_SSL_FAILED" />
+<s c="CURLFTPAUTH_DEFAULT" />
+<s c="CURLFTPAUTH_SSL" />
+<s c="CURLFTPAUTH_TLS" />
+<s c="CURLPROXY_HTTP" />
+<s c="CURLPROXY_SOCKS5" />
+<s c="CURL_NETRC_OPTIONAL" />
+<s c="CURL_NETRC_IGNORED" />
+<s c="CURL_NETRC_REQUIRED" />
+<s c="CURL_HTTP_VERSION_NONE" />
+<s c="CURL_HTTP_VERSION_1_0" />
+<s c="CURL_HTTP_VERSION_1_1" />
+<s c="CURLM_CALL_MULTI_PERFORM" />
+<s c="CURLM_OK" />
+<s c="CURLM_BAD_HANDLE" />
+<s c="CURLM_BAD_EASY_HANDLE" />
+<s c="CURLM_OUT_OF_MEMORY" />
+<s c="CURLM_INTERNAL_ERROR" />
+<s c="CURLMSG_DONE" />
+<s c="CAL_GREGORIAN" />
+<s c="CAL_JULIAN" />
+<s c="CAL_JEWISH" />
+<s c="CAL_FRENCH" />
+<s c="CAL_NUM_CALS" />
+<s c="CAL_DOW_DAYNO" />
+<s c="CAL_DOW_SHORT" />
+<s c="CAL_DOW_LONG" />
+<s c="CAL_MONTH_GREGORIAN_SHORT" />
+<s c="CAL_MONTH_GREGORIAN_LONG" />
+<s c="CAL_MONTH_JULIAN_SHORT" />
+<s c="CAL_MONTH_JULIAN_LONG" />
+<s c="CAL_MONTH_JEWISH" />
+<s c="CAL_MONTH_FRENCH" />
+<s c="CAL_EASTER_DEFAULT" />
+<s c="CAL_EASTER_ROMAN" />
+<s c="CAL_EASTER_ALWAYS_GREGORIAN" />
+<s c="CAL_EASTER_ALWAYS_JULIAN" />
+<s c="CAL_JEWISH_ADD_ALAFIM_GERESH" />
+<s c="CAL_JEWISH_ADD_ALAFIM" />
+<s c="CAL_JEWISH_ADD_GERESHAYIM" />
+<s c="PDO::FB_ATTR_DATE_FORMAT" />
+<s c="PDO::FB_ATTR_TIME_FORMAT" />
+<s c="PDO::FB_ATTR_TIMESTAMP_FORMAT" />
+<s c="RADIUS_ACCESS_REQUEST" />
+<s c="RADIUS_ACCESS_ACCEPT" />
+<s c="RADIUS_ACCESS_REJECT" />
+<s c="RADIUS_ACCOUNTING_REQUEST" />
+<s c="RADIUS_ACCOUNTING_RESPONSE" />
+<s c="RADIUS_ACCESS_CHALLENGE" />
+<s c="RADIUS_USER_NAME" />
+<s c="RADIUS_USER_PASSWORD" />
+<s c="RADIUS_CHAP_PASSWORD" />
+<s c="RADIUS_NAS_IP_ADDRESS" />
+<s c="RADIUS_NAS_PORT" />
+<s c="RADIUS_SERVICE_TYPE" />
+<s c="RADIUS_LOGIN" />
+<s c="RADIUS_FRAMED" />
+<s c="RADIUS_CALLBACK_LOGIN" />
+<s c="RADIUS_CALLBACK_FRAMED" />
+<s c="RADIUS_OUTBOUND" />
+<s c="RADIUS_ADMINISTRATIVE" />
+<s c="RADIUS_NAS_PROMPT" />
+<s c="RADIUS_AUTHENTICATE_ONLY" />
+<s c="RADIUS_CALLBACK_NAS_PROMPT" />
+<s c="RADIUS_FRAMED_PROTOCOL" />
+<s c="RADIUS_PPP" />
+<s c="RADIUS_SLIP" />
+<s c="RADIUS_ARAP" />
+<s c="RADIUS_GANDALF" />
+<s c="RADIUS_XYLOGICS" />
+<s c="RADIUS_FRAMED_IP_ADDRESS" />
+<s c="RADIUS_FRAMED_IP_NETMASK" />
+<s c="RADIUS_FRAMED_ROUTING" />
+<s c="RADIUS_FILTER_ID" />
+<s c="RADIUS_FRAMED_MTU" />
+<s c="RADIUS_FRAMED_COMPRESSION" />
+<s c="RADIUS_COMP_NONE" />
+<s c="RADIUS_COMP_VJ" />
+<s c="RADIUS_COMP_IPXHDR" />
+<s c="RADIUS_LOGIN_IP_HOST" />
+<s c="RADIUS_LOGIN_SERVICE" />
+<s c="RADIUS_LOGIN_TCP_PORT" />
+<s c="RADIUS_REPLY_MESSAGE" />
+<s c="RADIUS_CALLBACK_NUMBER" />
+<s c="RADIUS_CALLBACK_ID" />
+<s c="RADIUS_FRAMED_ROUTE" />
+<s c="RADIUS_FRAMED_IPX_NETWORK" />
+<s c="RADIUS_STATE" />
+<s c="RADIUS_CLASS" />
+<s c="RADIUS_VENDOR_SPECIFIC" />
+<s c="RADIUS_SESSION_TIMEOUT" />
+<s c="RADIUS_IDLE_TIMEOUT" />
+<s c="RADIUS_TERMINATION_ACTION" />
+<s c="RADIUS_CALLED_STATION_ID" />
+<s c="RADIUS_CALLING_STATION_ID" />
+<s c="RADIUS_NAS_IDENTIFIER" />
+<s c="RADIUS_PROXY_STATE" />
+<s c="RADIUS_LOGIN_LAT_SERVICE" />
+<s c="RADIUS_LOGIN_LAT_NODE" />
+<s c="RADIUS_LOGIN_LAT_GROUP" />
+<s c="RADIUS_FRAMED_APPLETALK_LINK" />
+<s c="RADIUS_FRAMED_APPLETALK_NETWORK" />
+<s c="RADIUS_FRAMED_APPLETALK_ZONE" />
+<s c="RADIUS_CHAP_CHALLENGE" />
+<s c="RADIUS_NAS_PORT_TYPE" />
+<s c="RADIUS_ASYNC" />
+<s c="RADIUS_SYNC" />
+<s c="RADIUS_ISDN_SYNC" />
+<s c="RADIUS_ISDN_ASYNC_V120" />
+<s c="RADIUS_ISDN_ASYNC_V110" />
+<s c="RADIUS_VIRTUAL" />
+<s c="RADIUS_PIAFS" />
+<s c="RADIUS_HDLC_CLEAR_CHANNEL" />
+<s c="RADIUS_X_25" />
+<s c="RADIUS_X_75" />
+<s c="RADIUS_G_3_FAX" />
+<s c="RADIUS_SDSL" />
+<s c="RADIUS_ADSL_CAP" />
+<s c="RADIUS_ADSL_DMT" />
+<s c="RADIUS_IDSL" />
+<s c="RADIUS_ETHERNET" />
+<s c="RADIUS_XDSL" />
+<s c="RADIUS_CABLE" />
+<s c="RADIUS_WIRELESS_OTHER" />
+<s c="RADIUS_WIRELESS_IEEE_802_11" />
+<s c="RADIUS_PORT_LIMIT" />
+<s c="RADIUS_LOGIN_LAT_PORT" />
+<s c="RADIUS_CONNECT_INFO" />
+<s c="RADIUS_ACCT_STATUS_TYPE" />
+<s c="RADIUS_START" />
+<s c="RADIUS_STOP" />
+<s c="RADIUS_ACCOUNTING_ON" />
+<s c="RADIUS_ACCOUNTING_OFF" />
+<s c="RADIUS_ACCT_DELAY_TIME" />
+<s c="RADIUS_ACCT_INPUT_OCTETS" />
+<s c="RADIUS_ACCT_OUTPUT_OCTETS" />
+<s c="RADIUS_ACCT_SESSION_ID" />
+<s c="RADIUS_ACCT_AUTHENTIC" />
+<s c="RADIUS_AUTH_RADIUS" />
+<s c="RADIUS_AUTH_LOCAL" />
+<s c="RADIUS_AUTH_REMOTE" />
+<s c="RADIUS_ACCT_SESSION_TIME" />
+<s c="RADIUS_ACCT_INPUT_PACKETS" />
+<s c="RADIUS_ACCT_OUTPUT_PACKETS" />
+<s c="RADIUS_ACCT_TERMINATE_CAUSE" />
+<s c="RADIUS_TERM_USER_REQUEST" />
+<s c="RADIUS_TERM_LOST_CARRIER" />
+<s c="RADIUS_TERM_LOST_SERVICE" />
+<s c="RADIUS_TERM_IDLE_TIMEOUT" />
+<s c="RADIUS_TERM_SESSION_TIMEOUT" />
+<s c="RADIUS_TERM_ADMIN_RESET" />
+<s c="RADIUS_TERM_ADMIN_REBOOT" />
+<s c="RADIUS_TERM_PORT_ERROR" />
+<s c="RADIUS_TERM_NAS_ERROR" />
+<s c="RADIUS_TERM_NAS_REQUEST" />
+<s c="RADIUS_TERM_NAS_REBOOT" />
+<s c="RADIUS_TERM_PORT_UNNEEDED" />
+<s c="RADIUS_TERM_PORT_PREEMPTED" />
+<s c="RADIUS_TERM_PORT_SUSPENDED" />
+<s c="RADIUS_TERM_SERVICE_UNAVAILABLE" />
+<s c="RADIUS_TERM_CALLBACK" />
+<s c="RADIUS_TERM_USER_ERROR" />
+<s c="RADIUS_TERM_HOST_REQUEST" />
+<s c="RADIUS_ACCT_MULTI_SESSION_ID" />
+<s c="RADIUS_ACCT_LINK_COUNT" />
+<s c="RADIUS_VENDOR_MICROSOFT" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_RESPONSE" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_ERROR" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_PW_1" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_PW_2" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_LM_ENC_PW" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_NT_ENC_PW" />
+<s c="RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY" />
+<s c="RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES" />
+<s c="RADIUS_MICROSOFT_MS_RAS_VENDOR" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_DOMAIN" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_CHALLENGE" />
+<s c="RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS" />
+<s c="RADIUS_MICROSOFT_MS_BAP_USAGE" />
+<s c="RADIUS_MICROSOFT_MS_LINK_UTILIZATION_THRESHOLD" />
+<s c="RADIUS_MICROSOFT_MS_LINK_DROP_TIME_LIMIT" />
+<s c="RADIUS_MICROSOFT_MS_MPPE_SEND_KEY" />
+<s c="RADIUS_MICROSOFT_MS_MPPE_RECV_KEY" />
+<s c="RADIUS_MICROSOFT_MS_RAS_VERSION" />
+<s c="RADIUS_MICROSOFT_MS_OLD_ARAP_PASSWORD" />
+<s c="RADIUS_MICROSOFT_MS_NEW_ARAP_PASSWORD" />
+<s c="RADIUS_MICROSOFT_MS_ARAP_PASSWORD_CHANGE_REASON" />
+<s c="RADIUS_MICROSOFT_MS_FILTER" />
+<s c="RADIUS_MICROSOFT_MS_ACCT_AUTH_TYPE" />
+<s c="RADIUS_MICROSOFT_MS_ACCT_EAP_TYPE" />
+<s c="RADIUS_MICROSOFT_MS_CHAP2_RESPONSE" />
+<s c="RADIUS_MICROSOFT_MS_CHAP2_SUCCESS" />
+<s c="RADIUS_MICROSOFT_MS_CHAP2_PW" />
+<s c="RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER" />
+<s c="RADIUS_MICROSOFT_MS_SECONDARY_DNS_SERVER" />
+<s c="RADIUS_MICROSOFT_MS_PRIMARY_NBNS_SERVER" />
+<s c="RADIUS_MICROSOFT_MS_SECONDARY_NBNS_SERVER" />
+<s c="RADIUS_MICROSOFT_MS_ARAP_CHALLENGE" />
+<s c="KRB5_KDB_DISALLOW_POSTDATED">KRB5_KDB_DISALLOW_FORWARDABLE</s>
+<s c="KRB5_KDB_DISALLOW_TGT_BASED">KRB5_KDB_DISALLOW_RENEWABLE</s>
+<s c="KRB5_KDB_DISALLOW_PROXIABLE">KRB5_KDB_DISALLOW_DUP_SKEY</s>
+<s c="KRB5_KDB_DISALLOW_ALL_TIX">KRB5_KDB_REQUIRES_PRE_AUTH</s>
+<s c="KRB5_KDB_REQUIRES_HW_AUTH">KRB5_KDB_REQUIRES_PWCHANGE</s>
+<s c="KRB5_KDB_DISALLOW_SVR">KRB5_KDB_PWCHANGE_SERVER</s>
+<s c="KRB5_KDB_SUPPORT_DESMD5">KRB5_KDB_NEW_PRINC</s>
+<s c="KADM5_PRINCIPAL">long</s>
+<s c="KADM5_PRINC_EXPIRE_TIME">long</s>
+<s c="KADM5_LAST_PW_CHANGE">long</s>
+<s c="KADM5_PW_EXPIRATION">long</s>
+<s c="KADM5_MAX_LIFE">long</s>
+<s c="KADM5_MAX_RLIFE">long</s>
+<s c="KADM5_MOD_NAME">string</s>
+<s c="KADM5_MOD_TIME">long</s>
+<s c="KADM5_KVNO">long</s>
+<s c="KADM5_POLICY">string</s>
+<s c="KADM5_CLEARPOLICY">long</s>
+<s c="KADM5_LAST_SUCCESS">long</s>
+<s c="KADM5_LAST_FAILED">long</s>
+<s c="KADM5_FAIL_AUTH_COUNT">long</s>
+<s c="KADM5_RANDKEY">long</s>
+<s c="KADM5_ATTRIBUTES">long</s>
+<s c="INPUT_POST" />
+<s c="INPUT_GET" />
+<s c="INPUT_COOKIE" />
+<s c="INPUT_ENV" />
+<s c="INPUT_SERVER" />
+<s c="INPUT_SESSION" />
+<s c="INPUT_REQUEST" />
+<s c="FILTER_FLAG_NONE" />
+<s c="FILTER_REQUIRE_SCALAR" />
+<s c="FILTER_REQUIRE_ARRAY" />
+<s c="FILTER_FORCE_ARRAY" />
+<s c="FILTER_NULL_ON_FAILURE" />
+<s c="FILTER_VALIDATE_INT" />
+<s c="FILTER_VALIDATE_BOOLEAN" />
+<s c="FILTER_VALIDATE_FLOAT" />
+<s c="FILTER_VALIDATE_REGEXP" />
+<s c="FILTER_VALIDATE_URL" />
+<s c="FILTER_VALIDATE_EMAIL" />
+<s c="FILTER_VALIDATE_IP" />
+<s c="FILTER_DEFAULT" />
+<s c="FILTER_UNSAFE_RAW" />
+<s c="FILTER_SANITIZE_STRING" />
+<s c="FILTER_SANITIZE_STRIPPED" />
+<s c="FILTER_SANITIZE_ENCODED" />
+<s c="FILTER_SANITIZE_SPECIAL_CHARS" />
+<s c="FILTER_SANITIZE_EMAIL" />
+<s c="FILTER_SANITIZE_URL" />
+<s c="FILTER_SANITIZE_NUMBER_INT" />
+<s c="FILTER_SANITIZE_NUMBER_FLOAT" />
+<s c="FILTER_SANITIZE_MAGIC_QUOTES" />
+<s c="FILTER_CALLBACK" />
+<s c="FILTER_FLAG_ALLOW_OCTAL" />
+<s c="FILTER_FLAG_ALLOW_HEX" />
+<s c="FILTER_FLAG_STRIP_LOW" />
+<s c="FILTER_FLAG_STRIP_HIGH" />
+<s c="FILTER_FLAG_ENCODE_LOW" />
+<s c="FILTER_FLAG_ENCODE_HIGH" />
+<s c="FILTER_FLAG_ENCODE_AMP" />
+<s c="FILTER_FLAG_NO_ENCODE_QUOTES" />
+<s c="FILTER_FLAG_EMPTY_STRING_NULL" />
+<s c="FILTER_FLAG_ALLOW_FRACTION" />
+<s c="FILTER_FLAG_ALLOW_THOUSAND" />
+<s c="FILTER_FLAG_ALLOW_SCIENTIFIC" />
+<s c="FILTER_FLAG_SCHEME_REQUIRED" />
+<s c="FILTER_FLAG_HOST_REQUIRED" />
+<s c="FILTER_FLAG_PATH_REQUIRED" />
+<s c="FILTER_FLAG_QUERY_REQUIRED" />
+<s c="FILTER_FLAG_IPV4" />
+<s c="FILTER_FLAG_IPV6" />
+<s c="FILTER_FLAG_NO_RES_RANGE" />
+<s c="FILTER_FLAG_NO_PRIV_RANGE" />
+<s c="GD_VERSION" />
+<s c="GD_MAJOR_VERSION" />
+<s c="GD_MINOR_VERSION" />
+<s c="GD_RELEASE_VERSION" />
+<s c="GD_EXTRA_VERSION" />
+<s c="GD_BUNDLE" />
+<s c="IMG_GIF" />
+<s c="IMG_JPG" />
+<s c="IMG_JPEG" />
+<s c="IMG_PNG" />
+<s c="IMG_WBMP" />
+<s c="IMG_XPM" />
+<s c="IMG_COLOR_TILED" />
+<s c="IMG_COLOR_STYLED" />
+<s c="IMG_COLOR_BRUSHED" />
+<s c="IMG_COLOR_STYLEDBRUSHED" />
+<s c="IMG_COLOR_TRANSPARENT" />
+<s c="IMG_ARC_ROUNDED" />
+<s c="IMG_ARC_PIE" />
+<s c="IMG_ARC_CHORD" />
+<s c="IMG_ARC_NOFILL" />
+<s c="IMG_ARC_EDGED" />
+<s c="IMG_GD2_RAW" />
+<s c="IMG_GD2_COMPRESSED" />
+<s c="IMG_EFFECT_REPLACE" />
+<s c="IMG_EFFECT_ALPHABLEND" />
+<s c="IMG_EFFECT_NORMAL" />
+<s c="IMG_EFFECT_OVERLAY" />
+<s c="IMG_FILTER_NEGATE" />
+<s c="IMG_FILTER_GRAYSCALE" />
+<s c="IMG_FILTER_BRIGHTNESS" />
+<s c="IMG_FILTER_CONTRAST" />
+<s c="IMG_FILTER_COLORIZE" />
+<s c="IMG_FILTER_EDGEDETECT" />
+<s c="IMG_FILTER_GAUSSIAN_BLUR" />
+<s c="IMG_FILTER_SELECTIVE_BLUR" />
+<s c="IMG_FILTER_EMBOSS" />
+<s c="IMG_FILTER_MEAN_REMOVAL" />
+<s c="IMG_FILTER_SMOOTH" />
+<s c="IMG_FILTER_PIXELATE" />
+<s c="IMAGETYPE_GIF" />
+<s c="IMAGETYPE_JPEG" />
+<s c="IMAGETYPE_PNG" />
+<s c="IMAGETYPE_SWF" />
+<s c="IMAGETYPE_PSD" />
+<s c="IMAGETYPE_BMP" />
+<s c="IMAGETYPE_WBMP" />
+<s c="IMAGETYPE_XBM" />
+<s c="IMAGETYPE_TIFF_II" />
+<s c="IMAGETYPE_TIFF_MM" />
+<s c="IMAGETYPE_IFF" />
+<s c="IMAGETYPE_JB2" />
+<s c="IMAGETYPE_JPC" />
+<s c="IMAGETYPE_JP2" />
+<s c="IMAGETYPE_JPX" />
+<s c="IMAGETYPE_SWC" />
+<s c="IMAGETYPE_ICO" />
+<s c="PNG_NO_FILTER" />
+<s c="PNG_FILTER_NONE" />
+<s c="PNG_FILTER_SUB" />
+<s c="PNG_FILTER_UP" />
+<s c="PNG_FILTER_AVG" />
+<s c="PNG_FILTER_PAETH" />
+<s c="PNG_ALL_FILTERS" />
+<s c="MSG_IPC_NOWAIT">integer</s>
+<s c="MSG_EAGAIN">integer</s>
+<s c="MSG_ENOMSG">integer</s>
+<s c="MSG_NOERROR">integer</s>
+<s c="MSG_EXCEPT">integer</s>
+<s c="DB2_BINARY" />
+<s c="DB2_CONVERT" />
+<s c="DB2_PASSTHRU" />
+<s c="DB2_SCROLLABLE" />
+<s c="DB2_FORWARD_ONLY" />
+<s c="DB2_PARAM_IN" />
+<s c="DB2_PARAM_OUT" />
+<s c="DB2_PARAM_INOUT" />
+<s c="DB2_PARAM_FILE" />
+<s c="DB2_AUTOCOMMIT_ON" />
+<s c="DB2_AUTOCOMMIT_OFF" />
+<s c="DB2_DOUBLE" />
+<s c="DB2_LONG" />
+<s c="DB2_CHAR" />
+<s c="DB2_CASE_NATURAL" />
+<s c="DB2_CASE_LOWER" />
+<s c="DB2_CASE_UPPER" />
+<s c="DB2_DEFERRED_PREPARE_ON" />
+<s c="DB2_DEFERRED_PREPARE_OFF" />
+<s c="MSQL_ASSOC" />
+<s c="MSQL_NUM" />
+<s c="MSQL_BOTH" />
+<s c="ODBC_TYPE" />
+<s c="ODBC_BINMODE_PASSTHRU" />
+<s c="ODBC_BINMODE_RETURN" />
+<s c="ODBC_BINMODE_CONVERT" />
+<s c="SQL_ODBC_CURSORS" />
+<s c="SQL_CUR_USE_DRIVER" />
+<s c="SQL_CUR_USE_IF_NEEDED" />
+<s c="SQL_CUR_USE_ODBC" />
+<s c="SQL_CONCURRENCY" />
+<s c="SQL_CONCUR_READ_ONLY" />
+<s c="SQL_CONCUR_LOCK" />
+<s c="SQL_CONCUR_ROWVER" />
+<s c="SQL_CONCUR_VALUES" />
+<s c="SQL_CURSOR_TYPE" />
+<s c="SQL_CURSOR_FORWARD_ONLY" />
+<s c="SQL_CURSOR_KEYSET_DRIVEN" />
+<s c="SQL_CURSOR_DYNAMIC" />
+<s c="SQL_CURSOR_STATIC" />
+<s c="SQL_KEYSET_SIZE" />
+<s c="SQL_CHAR" />
+<s c="SQL_VARCHAR" />
+<s c="SQL_LONGVARCHAR" />
+<s c="SQL_DECIMAL" />
+<s c="SQL_NUMERIC" />
+<s c="SQL_BIT" />
+<s c="SQL_TINYINT" />
+<s c="SQL_SMALLINT" />
+<s c="SQL_INTEGER" />
+<s c="SQL_BIGINT" />
+<s c="SQL_REAL" />
+<s c="SQL_FLOAT" />
+<s c="SQL_DOUBLE" />
+<s c="SQL_BINARY" />
+<s c="SQL_VARBINARY" />
+<s c="SQL_LONGVARBINARY" />
+<s c="SQL_DATE" />
+<s c="SQL_TIME" />
+<s c="SQL_TIMESTAMP" />
+<s c="SQL_TYPE_DATE" />
+<s c="SQL_TYPE_TIME" />
+<s c="SQL_TYPE_TIMESTAMP" />
+<s c="SQL_BEST_ROWID" />
+<s c="SQL_ROWVER" />
+<s c="SQL_SCOPE_CURROW" />
+<s c="SQL_SCOPE_TRANSACTION" />
+<s c="SQL_SCOPE_SESSION" />
+<s c="SQL_NO_NULLS" />
+<s c="SQL_NULLABLE" />
+<s c="SQL_INDEX_UNIQUE" />
+<s c="SQL_INDEX_ALL" />
+<s c="SQL_ENSURE" />
+<s c="SQL_QUICK" />
+<s c="IFX_SCROLL" />
+<s c="IFX_HOLD" />
+<s c="IFX_LO_RDONLY" />
+<s c="IFX_LO_WRONLY" />
+<s c="IFX_LO_APPEND" />
+<s c="IFX_LO_RDWR" />
+<s c="IFX_LO_BUFFER" />
+<s c="IFX_LO_NOBUFFER" />
+<s c="XSL_CLONE_AUTO" />
+<s c="XSL_CLONE_NEVER" />
+<s c="XSL_CLONE_ALWAYS" />
+<s c="LIBXSLT_VERSION" />
+<s c="LIBXSLT_DOTTED_VERSION" />
+<s c="LIBEXSLT_VERSION" />
+<s c="LIBEXSLT_DOTTED_VERSION" />
+<s c="FAMC">Some value which can be obtained with fstat(1) changed for a file or directory.</s>
+<s c="FAMD">A file or directory was deleted or renamed.</s>
+<s c="FAMC">A file was created in a directory.</s>
+<s c="FAMM">This event never occurs.</s>
+<s c="FAMA">An event in response to fam_cancel_monitor .</s>
+<s c="FAME">An event upon request to monitor a file or directory. When a directory is monitored, an event for that directory and every file contained in that directory is issued.</s>
+<s c="MB_OVERLOAD_MAIL" />
+<s c="MB_OVERLOAD_STRING" />
+<s c="MB_OVERLOAD_REGEX" />
+<s c="MB_CASE_UPPER" />
+<s c="MB_CASE_LOWER" />
+<s c="MB_CASE_TITLE" />
+<s c="HW_ATTR_LANG" />
+<s c="HW_ATTR_NR" />
+<s c="HW_ATTR_NONE" />
+<s c="SUNFUNCS_RET_TIMESTAMP" />
+<s c="SUNFUNCS_RET_STRING" />
+<s c="SUNFUNCS_RET_DOUBLE" />
+<s c="PDO::MYSQL_ATTR_USE_BUFFERED_QUERY" />
+<s c="PDO::MYSQL_ATTR_LOCAL_INFILE" />
+<s c="PDO::MYSQL_ATTR_INIT_COMMAND" />
+<s c="PDO::MYSQL_ATTR_READ_DEFAULT_FILE" />
+<s c="PDO::MYSQL_ATTR_READ_DEFAULT_GROUP" />
+<s c="MYSQL_READ_DEFAULT_FILE" />
+<s c="PDO::MYSQL_ATTR_MAX_BUFFER_SIZE" />
+<s c="PDO::MYSQL_ATTR_DIRECT_QUERY" />
+<s c="FUNCTION_TRACE">1</s>
+<s c="ARGS_TRACE">2</s>
+<s c="ASSIGNMENT_TRACE">4</s>
+<s c="STATEMENT_TRACE">8</s>
+<s c="MEMORY_TRACE">16</s>
+<s c="TIMING_TRACE">32</s>
+<s c="SUMMARY_TRACE">64</s>
+<s c="ERROR_TRACE">128</s>
+<s c="PROF_TRACE">256</s>
+<s c="APD_VERSION">example: 1.0.2-dev</s>
+<s c="SNMP_OID_OUTPUT_FULL" />
+<s c="SNMP_OID_OUTPUT_NUMERIC" />
+<s c="SNMP_VALUE_LIBRARY" />
+<s c="SNMP_VALUE_PLAIN" />
+<s c="SNMP_VALUE_OBJECT" />
+<s c="SNMP_BIT_STR" />
+<s c="SNMP_OCTET_STR" />
+<s c="SNMP_OPAQUE" />
+<s c="SNMP_NULL" />
+<s c="SNMP_OBJECT_ID" />
+<s c="SNMP_IPADDRESS" />
+<s c="SNMP_COUNTER" />
+<s c="SNMP_UNSIGNED" />
+<s c="SNMP_TIMETICKS" />
+<s c="SNMP_UINTEGER" />
+<s c="SNMP_INTEGER" />
+<s c="SNMP_COUNTER64" />
+<s c="EXP_GLOB" />
+<s c="EXP_EXACT" />
+<s c="EXP_REGEXP" />
+<s c="EXP_EOF" />
+<s c="EXP_TIMEOUT" />
+<s c="EXP_FULLBUFFER" />
+<s c="SQLITE_ASSOC" />
+<s c="SQLITE_BOTH" />
+<s c="SQLITE_NUM" />
+<s c="SQLITE_OK" />
+<s c="SQLITE_ERROR" />
+<s c="SQLITE_INTERNAL" />
+<s c="SQLITE_PERM" />
+<s c="SQLITE_ABORT" />
+<s c="SQLITE_BUSY" />
+<s c="SQLITE_LOCKED" />
+<s c="SQLITE_NOMEM" />
+<s c="SQLITE_READONLY" />
+<s c="SQLITE_INTERRUPT" />
+<s c="SQLITE_IOERR" />
+<s c="SQLITE_CORRUPT" />
+<s c="SQLITE_NOTFOUND" />
+<s c="SQLITE_FULL" />
+<s c="SQLITE_CANTOPEN" />
+<s c="SQLITE_PROTOCOL" />
+<s c="SQLITE_EMPTY" />
+<s c="SQLITE_SCHEMA" />
+<s c="SQLITE_TOOBIG" />
+<s c="SQLITE_CONSTRAINT" />
+<s c="SQLITE_MISMATCH" />
+<s c="SQLITE_MISUSE" />
+<s c="SQLITE_NOLFS" />
+<s c="SQLITE_AUTH" />
+<s c="SQLITE_ROW" />
+<s c="SQLITE_DONE" />
+<s c="MHASH_ADLER32" />
+<s c="MHASH_CRC32" />
+<s c="MHASH_CRC32B" />
+<s c="MHASH_GOST" />
+<s c="MHASH_HAVAL128" />
+<s c="MHASH_HAVAL160" />
+<s c="MHASH_HAVAL192" />
+<s c="MHASH_HAVAL256" />
+<s c="MHASH_MD4" />
+<s c="MHASH_MD5" />
+<s c="MHASH_RIPEMD160" />
+<s c="MHASH_SHA1" />
+<s c="MHASH_SHA256" />
+<s c="MHASH_TIGER" />
+<s c="MHASH_TIGER128" />
+<s c="MHASH_TIGER160" />
+<s c="AF_UNIX" />
+<s c="AF_INET" />
+<s c="AF_INET6" />
+<s c="SOCK_STREAM" />
+<s c="SOCK_DGRAM" />
+<s c="SOCK_RAW" />
+<s c="SOCK_SEQPACKET" />
+<s c="SOCK_RDM" />
+<s c="MSG_OOB" />
+<s c="MSG_WAITALL" />
+<s c="MSG_PEEK" />
+<s c="MSG_DONTROUTE" />
+<s c="MSG_EOR" />
+<s c="MSG_EOF" />
+<s c="SO_DEBUG" />
+<s c="SO_REUSEADDR" />
+<s c="SO_KEEPALIVE" />
+<s c="SO_DONTROUTE" />
+<s c="SO_LINGER" />
+<s c="SO_BROADCAST" />
+<s c="SO_OOBINLINE" />
+<s c="SO_SNDBUF" />
+<s c="SO_RCVBUF" />
+<s c="SO_SNDLOWAT" />
+<s c="SO_RCVLOWAT" />
+<s c="SO_SNDTIMEO" />
+<s c="SO_RCVTIMEO" />
+<s c="SO_TYPE" />
+<s c="SO_ERROR" />
+<s c="SOL_SOCKET" />
+<s c="PHP_NORMAL_READ" />
+<s c="PHP_BINARY_READ" />
+<s c="SOL_TCP" />
+<s c="SOL_UDP" />
+<s c="SOCKET_EINTR" />
+<s c="SOCKET_EBADF" />
+<s c="SOCKET_EACCES" />
+<s c="SOCKET_EFAULT" />
+<s c="SOCKET_EINVAL" />
+<s c="SOCKET_EMFILE" />
+<s c="SOCKET_EWOULDBLOCK" />
+<s c="SOCKET_EINPROGRESS" />
+<s c="SOCKET_EALREADY" />
+<s c="SOCKET_ENOTSOCK" />
+<s c="SOCKET_EDESTADDRREQ" />
+<s c="SOCKET_EMSGSIZE" />
+<s c="SOCKET_EPROTOTYPE" />
+<s c="SOCKET_ENOPROTOOPT" />
+<s c="SOCKET_EPROTONOSUPPORT" />
+<s c="SOCKET_ESOCKTNOSUPPORT" />
+<s c="SOCKET_EOPNOTSUPP" />
+<s c="SOCKET_EPFNOSUPPORT" />
+<s c="SOCKET_EAFNOSUPPORT" />
+<s c="SOCKET_EADDRINUSE" />
+<s c="SOCKET_EADDRNOTAVAIL" />
+<s c="SOCKET_ENETDOWN" />
+<s c="SOCKET_ENETUNREACH" />
+<s c="SOCKET_ENETRESET" />
+<s c="SOCKET_ECONNABORTED" />
+<s c="SOCKET_ECONNRESET" />
+<s c="SOCKET_ENOBUFS" />
+<s c="SOCKET_EISCONN" />
+<s c="SOCKET_ENOTCONN" />
+<s c="SOCKET_ESHUTDOWN" />
+<s c="SOCKET_ETOOMYREFS" />
+<s c="SOCKET_ETIMEDOUT" />
+<s c="SOCKET_ECONNREFUSED" />
+<s c="SOCKET_ELOOP" />
+<s c="SOCKET_ENAMETOOLONG" />
+<s c="SOCKET_EHOSTDOWN" />
+<s c="SOCKET_EHOSTUNREACH" />
+<s c="SOCKET_ENOTEMPTY" />
+<s c="SOCKET_EPROCLIM" />
+<s c="SOCKET_EUSERS" />
+<s c="SOCKET_EDUOT" />
+<s c="SOCKET_ESTALE" />
+<s c="SOCKET_EREMOTE" />
+<s c="SOCKET_EDISCON" />
+<s c="SOCKET_SYSNOTREADY" />
+<s c="SOCKET_VERNOTSUPPORTED" />
+<s c="SOCKET_NOTINITIALISED" />
+<s c="SOCKET_HOST_NOT_FOUND" />
+<s c="SOCKET_TRY_AGAIN" />
+<s c="SOCKET_NO_RECOVERY" />
+<s c="SOCKET_NO_DATA" />
+<s c="SOCKET_NO_ADDRESS" />
+<s c="SOCKET_EPERM" />
+<s c="SOCKET_ENOENT" />
+<s c="SOCKET_EIO" />
+<s c="SOCKET_ENXIO" />
+<s c="SOCKET_E2BIG" />
+<s c="SOCKET_EAGAIN" />
+<s c="SOCKET_ENOMEM" />
+<s c="SOCKET_ENOTBLK" />
+<s c="SOCKET_EBUSY" />
+<s c="SOCKET_EEXIST" />
+<s c="SOCKET_EXDEV" />
+<s c="SOCKET_ENODEV" />
+<s c="SOCKET_ENOTDIR" />
+<s c="SOCKET_EISDIR" />
+<s c="SOCKET_ENFILE" />
+<s c="SOCKET_ENOTTY" />
+<s c="SOCKET_ENOSPC" />
+<s c="SOCKET_ESPIPE" />
+<s c="SOCKET_EROFS" />
+<s c="SOCKET_EMLINK" />
+<s c="SOCKET_EPIPE" />
+<s c="SOCKET_ENOLCK" />
+<s c="SOCKET_ENOSYS" />
+<s c="SOCKET_ENOMSG" />
+<s c="SOCKET_EIDRM" />
+<s c="SOCKET_ECHRNG" />
+<s c="SOCKET_EL2NSYNC" />
+<s c="SOCKET_EL3HLT" />
+<s c="SOCKET_EL3RST" />
+<s c="SOCKET_ELNRNG" />
+<s c="SOCKET_EUNATCH" />
+<s c="SOCKET_ENOCSI" />
+<s c="SOCKET_EL2HLT" />
+<s c="SOCKET_EBADE" />
+<s c="SOCKET_EBADR" />
+<s c="SOCKET_EXFULL" />
+<s c="SOCKET_ENOANO" />
+<s c="SOCKET_EBADRQC" />
+<s c="SOCKET_EBADSLT" />
+<s c="SOCKET_ENOSTR" />
+<s c="SOCKET_ENODATA" />
+<s c="SOCKET_ETIME" />
+<s c="SOCKET_ENOSR" />
+<s c="SOCKET_ENONET" />
+<s c="SOCKET_ENOLINK" />
+<s c="SOCKET_EADV" />
+<s c="SOCKET_ESRMNT" />
+<s c="SOCKET_ECOMM" />
+<s c="SOCKET_EPROTO" />
+<s c="SOCKET_EMULTIHOP" />
+<s c="SOCKET_EBADMSG" />
+<s c="SOCKET_ENOTUNIQ" />
+<s c="SOCKET_EBADFD" />
+<s c="SOCKET_ERMCHG" />
+<s c="SOCKET_ERESTART" />
+<s c="SOCKET_ESTRPIPE" />
+<s c="SOCKET_EPROTOOPT" />
+<s c="SOCKET_ADDRINUSE" />
+<s c="SOCKET_ETOOMANYREFS" />
+<s c="SOCKET_EISNAM" />
+<s c="SOCKET_EREMOTEIO" />
+<s c="SOCKET_EDQUOT" />
+<s c="SOCKET_ENOMEDIUM" />
+<s c="SOCKET_EMEDIUMTYPE" />
+<s c="INGRES_ASSOC" />
+<s c="INGRES_NUM" />
+<s c="INGRES_BOTH" />
+<s c="INGRES_EXT_VERSION" />
+<s c="INGRES_API_VERSION" />
+<s c="INGRES_CURSOR_READONLY" />
+<s c="INGRES_CURSOR_UPDATE" />
+<s c="INGRES_DATE_MULTINATIONAL" />
+<s c="INGRES_DATE_MULTINATIONAL4" />
+<s c="INGRES_DATE_FINNISH" />
+<s c="INGRES_DATE_ISO" />
+<s c="INGRES_DATE_ISO4" />
+<s c="INGRES_DATE_GERMAN" />
+<s c="INGRES_DATE_MDY" />
+<s c="INGRES_DATE_DMY" />
+<s c="INGRES_DATE_YMD" />
+<s c="INGRES_MONEY_LEADING" />
+<s c="INGRES_MONEY_TRAILING" />
+<s c="INGRES_STRUCTURE_BTREE" />
+<s c="INGRES_STRUCTURE_CBTREE" />
+<s c="INGRES_STRUCTURE_HASH" />
+<s c="INGRES_STRUCTURE_CHASH" />
+<s c="INGRES_STRUCTURE_HEAP" />
+<s c="INGRES_STRUCTURE_CHEAP" />
+<s c="INGRES_STRUCTURE_ISAM" />
+<s c="INGRES_STRUCTURE_CISAM" />
+<s c="CDATA">XMLReader::ENTITY_REF ( integer )</s>
+<s c="10">Document Type node</s>
+<s c="11">Document Fragment node</s>
+<s c="12">Notation node</s>
+<s c="13">Whitespace node</s>
+<s c="14">Significant Whitespace node</s>
+<s c="15">End Element</s>
+<s c="16">End Entity</s>
+<s c="17">XML Declaration node</s>
+<s c="PX_FIELD_ALPHA">Character data with fixed length</s>
+<s c="PX_FIELD_DATE">Date, number of days since 1.1.0000</s>
+<s c="PX_FIELD_SHORT">Short integer (2 Bytes)</s>
+<s c="PX_FIELD_LONG">Long integer (4 Bytes)</s>
+<s c="PX_FIELD_CURRENCY">same as PX_FIELD_NUMBER</s>
+<s c="PX_FIELD_NUMBER">Double</s>
+<s c="PX_FIELD_LOGICAL">Boolean</s>
+<s c="PX_FIELD_MEMOBLOB">Binary large object</s>
+<s c="PX_FIELD_BLOB">Binary large object (not supported)</s>
+<s c="PX_FIELD_FMTMEMOBLOB">Binary large object</s>
+<s c="PX_FIELD_OLE">OLE object (basically a blob, not supported)</s>
+<s c="PX_FIELD_GRAPHIC">Graphic (basically a blob, not supported)</s>
+<s c="PX_FIELD_TIME">time, number of milli seconds since midnight</s>
+<s c="PX_FIELD_TIMESTAMP">timestamp, number of milli seconds since 1.1.0000</s>
+<s c="PX_FIELD_AUTOINC">Auto incrementing interger (like PX_FIELD_LONG)</s>
+<s c="PX_FIELD_BCD">Decimal number stored in bcd format (not supported)</s>
+<s c="PX_FIELD_BYTES">Array of Bytes with not more than 255 bytes (not supported)</s>
+<s c="PX_KEYTOLOWER">Turn all field names into lower case</s>
+<s c="PX_KEYTOUPPER">Turn all field names into upper case</s>
+<s c="PX_FILE_INDEX_DB">Indexed database</s>
+<s c="PX_FILE_PRIM_INDEX">Primary index</s>
+<s c="PX_FILE_NON_INDEX_DB">None indexed database</s>
+<s c="PX_FILE_NON_INC_SEC_INDEX">None incremental secondary index</s>
+<s c="PX_FILE_SEC_INDEX">Secondary index</s>
+<s c="PX_FILE_INC_SEC_INDEX">Incremental secondary index</s>
+<s c="PX_FILE_NON_INC_SEC_INDEX_G">Non incremental secondary index</s>
+<s c="PX_FILE_SEC_INDEX_G">Secondary index</s>
+<s c="PX_FILE_INC_SEC_INDEX_G">Non incremental secondary index</s>
+<s c="UDM_FIELD_URLID" />
+<s c="UDM_FIELD_URL" />
+<s c="UDM_FIELD_CONTENT" />
+<s c="UDM_FIELD_TITLE" />
+<s c="UDM_FIELD_KEYWORDS" />
+<s c="UDM_FIELD_DESC" />
+<s c="UDM_FIELD_DESCRIPTION" />
+<s c="UDM_FIELD_TEXT" />
+<s c="UDM_FIELD_SIZE" />
+<s c="UDM_FIELD_RATING" />
+<s c="UDM_FIELD_SCORE" />
+<s c="UDM_FIELD_MODIFIED" />
+<s c="UDM_FIELD_ORDER" />
+<s c="UDM_FIELD_CRC" />
+<s c="UDM_FIELD_CATEGORY" />
+<s c="UDM_FIELD_LANG" />
+<s c="UDM_FIELD_CHARSET" />
+<s c="UDM_PARAM_PAGE_SIZE" />
+<s c="UDM_PARAM_PAGE_NUM" />
+<s c="UDM_PARAM_SEARCH_MODE" />
+<s c="UDM_PARAM_CACHE_MODE" />
+<s c="UDM_PARAM_TRACK_MODE" />
+<s c="UDM_PARAM_PHRASE_MODE" />
+<s c="UDM_PARAM_CHARSET" />
+<s c="UDM_PARAM_LOCAL_CHARSET" />
+<s c="UDM_PARAM_BROWSER_CHARSET" />
+<s c="UDM_PARAM_STOPTABLE" />
+<s c="UDM_PARAM_STOP_TABLE" />
+<s c="UDM_PARAM_STOPFILE" />
+<s c="UDM_PARAM_STOP_FILE" />
+<s c="UDM_PARAM_WEIGHT_FACTOR" />
+<s c="UDM_PARAM_WORD_MATCH" />
+<s c="UDM_PARAM_MAX_WORD_LEN" />
+<s c="UDM_PARAM_MAX_WORDLEN" />
+<s c="UDM_PARAM_MIN_WORD_LEN" />
+<s c="UDM_PARAM_MIN_WORDLEN" />
+<s c="UDM_PARAM_ISPELL_PREFIXES" />
+<s c="UDM_PARAM_ISPELL_PREFIX" />
+<s c="UDM_PARAM_PREFIXES" />
+<s c="UDM_PARAM_PREFIX" />
+<s c="UDM_PARAM_CROSS_WORDS" />
+<s c="UDM_PARAM_CROSSWORDS" />
+<s c="UDM_PARAM_VARDIR" />
+<s c="UDM_PARAM_DATADIR" />
+<s c="UDM_PARAM_HLBEG" />
+<s c="UDM_PARAM_HLEND" />
+<s c="UDM_PARAM_SYNONYM" />
+<s c="UDM_PARAM_SEARCHD" />
+<s c="UDM_PARAM_QSTRING" />
+<s c="UDM_PARAM_REMOTE_ADDR" />
+<s c="UDM_LIMIT_CAT" />
+<s c="UDM_LIMIT_URL" />
+<s c="UDM_LIMIT_TAG" />
+<s c="UDM_LIMIT_LANG" />
+<s c="UDM_LIMIT_DATE" />
+<s c="UDM_PARAM_FOUND" />
+<s c="UDM_PARAM_NUM_ROWS" />
+<s c="UDM_PARAM_WORDINFO" />
+<s c="UDM_PARAM_WORD_INFO" />
+<s c="UDM_PARAM_SEARCHTIME" />
+<s c="UDM_PARAM_SEARCH_TIME" />
+<s c="UDM_PARAM_FIRST_DOC" />
+<s c="UDM_PARAM_LAST_DOC" />
+<s c="UDM_MODE_ALL" />
+<s c="UDM_MODE_ANY" />
+<s c="UDM_MODE_BOOL" />
+<s c="UDM_MODE_PHRASE" />
+<s c="UDM_CACHE_ENABLED" />
+<s c="UDM_CACHE_DISABLED" />
+<s c="UDM_TRACK_ENABLED" />
+<s c="UDM_TRACK_DISABLED" />
+<s c="UDM_PHRASE_ENABLED" />
+<s c="UDM_PHRASE_DISABLED" />
+<s c="UDM_CROSS_WORDS_ENABLED" />
+<s c="UDM_CROSSWORDS_ENABLED" />
+<s c="UDM_CROSS_WORDS_DISABLED" />
+<s c="UDM_CROSSWORDS_DISABLED" />
+<s c="UDM_PREFIXES_ENABLED" />
+<s c="UDM_PREFIX_ENABLED" />
+<s c="UDM_ISPELL_PREFIXES_ENABLED" />
+<s c="UDM_ISPELL_PREFIX_ENABLED" />
+<s c="UDM_PREFIXES_DISABLED" />
+<s c="UDM_PREFIX_DISABLED" />
+<s c="UDM_ISPELL_PREFIXES_DISABLED" />
+<s c="UDM_ISPELL_PREFIX_DISABLED" />
+<s c="UDM_ISPELL_TYPE_AFFIX" />
+<s c="UDM_ISPELL_TYPE_SPELL" />
+<s c="UDM_ISPELL_TYPE_DB" />
+<s c="UDM_ISPELL_TYPE_SERVER" />
+<s c="UDM_MATCH_WORD" />
+<s c="UDM_MATCH_BEGIN" />
+<s c="UDM_MATCH_SUBSTR" />
+<s c="UDM_MATCH_END" />
+<s c="EXIF_USE_MBSTRING" />
+<s c="SAM_AUTO" />
+<s c="SAM_BOOLEAN" />
+<s c="SAM_BUS" />
+<s c="SAM_BYTE" />
+<s c="SAM_BYTES" />
+<s c="SAM_CORRELID" />
+<s c="SAM_DELIVERYMODE" />
+<s c="SAM_DOUBLE" />
+<s c="SAM_ENDPOINTS" />
+<s c="SAM_FLOAT" />
+<s c="SAM_HOST" />
+<s c="SAM_INT" />
+<s c="SAM_LONG" />
+<s c="SAM_MANUAL" />
+<s c="SAM_MESSAGEID" />
+<s c="SAM_MQTT" />
+<s c="SAM_MQTT_CLEANSTART" />
+<s c="SAM_NON_PERSISTENT" />
+<s c="SAM_PASSWORD" />
+<s c="SAM_PERSISTENT" />
+<s c="SAM_PORT" />
+<s c="SAM_PRIORITY" />
+<s c="SAM_REPLY_TO" />
+<s c="SAM_RTT" />
+<s c="SAM_STRING" />
+<s c="SAM_TARGETCHAIN" />
+<s c="SAM_TEXT" />
+<s c="SAM_TIMETOLIVE" />
+<s c="SAM_TRANSACTIONS" />
+<s c="SAM_USERID" />
+<s c="SAM_WAIT" />
+<s c="SAM_WMQ" />
+<s c="SAM_WMQ_BINDINGS" />
+<s c="SAM_WMQ_CLIENT" />
+<s c="SAM_WMQ_TARGET_CLIENT" />
+<s c="SAM_WPM" />
+<s c="FORCE_GZIP" />
+<s c="FORCE_DEFLATE" />
+<s c="MAXDB_COMPNAME">The component name used to initialise the SQLDBC runtime environment.</s>
+<s c="MAXDB_APPLICATION">The application to be connected to the database.</s>
+<s c="MAXDB_APPVERSION">The version of the application.</s>
+<s c="MAXDB_SQLMODE">The SQL mode.</s>
+<s c="MAXDB_UNICODE">TRUE, if the connection is an unicode (UCS2) client or FALSE, if not.</s>
+<s c="MAXDB_TIMEOUT">The maximum allowed time of inactivity after which the connection to the database is closed by the system.</s>
+<s c="MAXDB_ISOLATIONLEVEL">Specifies whether and how shared locks and exclusive locks are implicitly requested or released.</s>
+<s c="MAXDB_PACKETCOUNT">The number of different request packets used for the connection.</s>
+<s c="MAXDB_STATEMENTCACHESIZE">The number of prepared statements to be cached for the connection for re-use.</s>
+<s c="MAXDB_CURSORPREFIX">The prefix to use for result tables that are automatically named.</s>
+<s c="MAXDB_ASSOC">Columns are returned into the array having the fieldname as the array index.</s>
+<s c="MAXDB_ASSOC_UPPER">Columns are returned into the array having the upper case fieldname as the array index.</s>
+<s c="MAXDB_ASSOC_LOWER">Columns are returned into the array having the lower case fieldname as the array index.</s>
+<s c="MAXDB_BOTH">Columns are returned into the array having both a numerical index and the fieldname as the array index.</s>
+<s c="MAXDB_NUM">Columns are returned into the array having a numerical index to the fields. This index starts with 0, the first field in the result.</s>
+<s c="MAILPARSE_EXTRACT_OUTPUT" />
+<s c="MAILPARSE_EXTRACT_STREAM" />
+<s c="MAILPARSE_EXTRACT_RETURN" />
+<s c="XSLT_OPT_SILENT" />
+<s c="XSLT_SABOPT_PARSE_PUBLIC_ENTITIES" />
+<s c="XSLT_SABOPT_DISABLE_ADDING_META" />
+<s c="XSLT_SABOPT_DISABLE_STRIPPING" />
+<s c="XSLT_SABOPT_IGNORE_DOC_NOT_FOUND" />
+<s c="XSLT_SABOPT_FILES_TO_HANDLER" />
+<s c="XSLT_ERR_UNSUPPORTED_SCHEME" />
+<s c="TIDY_TAG_UNKNOWN">TIDY_TAG_A</s>
+<s c="TIDY_TAG_ABBR">TIDY_TAG_ACRONYM</s>
+<s c="TIDY_TAG_ALIGN">TIDY_TAG_APPLET</s>
+<s c="TIDY_TAG_AREA">TIDY_TAG_B</s>
+<s c="TIDY_TAG_BASE">TIDY_TAG_BASEFONT</s>
+<s c="TIDY_TAG_BDO">TIDY_TAG_BGSOUND</s>
+<s c="TIDY_TAG_BIG">TIDY_TAG_BLINK</s>
+<s c="TIDY_TAG_BLOCKQUOTE">TIDY_TAG_BODY</s>
+<s c="TIDY_TAG_BR">TIDY_TAG_BUTTON</s>
+<s c="TIDY_TAG_CAPTION">TIDY_TAG_CENTER</s>
+<s c="TIDY_TAG_CITE">TIDY_TAG_CODE</s>
+<s c="TIDY_TAG_COL">TIDY_TAG_COLGROUP</s>
+<s c="TIDY_TAG_COMMENT">TIDY_TAG_DD</s>
+<s c="TIDY_TAG_DEL">TIDY_TAG_DFN</s>
+<s c="TIDY_TAG_DIR">TIDY_TAG_DIV</s>
+<s c="TIDY_TAG_DL">TIDY_TAG_DT</s>
+<s c="TIDY_TAG_EM">TIDY_TAG_EMBED</s>
+<s c="TIDY_TAG_FIELDSET">TIDY_TAG_FONT</s>
+<s c="TIDY_TAG_FORM">TIDY_TAG_FRAME</s>
+<s c="TIDY_TAG_FRAMESET">TIDY_TAG_H1</s>
+<s c="TIDY_TAG_H2">TIDY_TAG_H3</s>
+<s c="TIDY_TAG_H4">TIDY_TAG_H5</s>
+<s c="TIDY_TAG_H6">TIDY_TAG_HEAD</s>
+<s c="TIDY_TAG_HR">TIDY_TAG_HTML</s>
+<s c="TIDY_TAG_I">TIDY_TAG_IFRAME</s>
+<s c="TIDY_TAG_ILAYER">TIDY_TAG_IMG</s>
+<s c="TIDY_TAG_INPUT">TIDY_TAG_INS</s>
+<s c="TIDY_TAG_ISINDEX">TIDY_TAG_KBD</s>
+<s c="TIDY_TAG_KEYGEN">TIDY_TAG_LABEL</s>
+<s c="TIDY_TAG_LAYER">TIDY_TAG_LEGEND</s>
+<s c="TIDY_TAG_LI">TIDY_TAG_LINK</s>
+<s c="TIDY_TAG_LISTING">TIDY_TAG_MAP</s>
+<s c="TIDY_TAG_MARQUEE">TIDY_TAG_MENU</s>
+<s c="TIDY_TAG_META">TIDY_TAG_MULTICOL</s>
+<s c="TIDY_TAG_NOBR">TIDY_TAG_NOEMBED</s>
+<s c="TIDY_TAG_NOFRAMES">TIDY_TAG_NOLAYER</s>
+<s c="TIDY_TAG_NOSAVE">TIDY_TAG_NOSCRIPT</s>
+<s c="TIDY_TAG_OBJECT">TIDY_TAG_OL</s>
+<s c="TIDY_TAG_OPTGROUP">TIDY_TAG_OPTION</s>
+<s c="TIDY_TAG_P">TIDY_TAG_PARAM</s>
+<s c="TIDY_TAG_PLAINTEXT">TIDY_TAG_PRE</s>
+<s c="TIDY_TAG_Q">TIDY_TAG_RP</s>
+<s c="TIDY_TAG_RT">TIDY_TAG_RTC</s>
+<s c="TIDY_TAG_RUBY">TIDY_TAG_S</s>
+<s c="TIDY_TAG_SAMP">TIDY_TAG_SCRIPT</s>
+<s c="TIDY_TAG_SELECT">TIDY_TAG_SERVER</s>
+<s c="TIDY_TAG_SERVLET">TIDY_TAG_SMALL</s>
+<s c="TIDY_TAG_SPACER">TIDY_TAG_SPAN</s>
+<s c="TIDY_TAG_STRIKE">TIDY_TAG_STRONG</s>
+<s c="TIDY_TAG_STYLE">TIDY_TAG_SUB</s>
+<s c="TIDY_TAG_TABLE">TIDY_TAG_TBODY</s>
+<s c="TIDY_TAG_TD">TIDY_TAG_TEXTAREA</s>
+<s c="TIDY_TAG_TFOOT">TIDY_TAG_TH</s>
+<s c="TIDY_TAG_THEAD">TIDY_TAG_TITLE</s>
+<s c="TIDY_TAG_TR">TIDY_TAG_TR</s>
+<s c="TIDY_TAG_TT">TIDY_TAG_U</s>
+<s c="TIDY_TAG_UL">TIDY_TAG_VAR</s>
+<s c="TIDY_TAG_WBR">TIDY_TAG_XMP</s>
+<s c="TIDY_ATTR_UNKNOWN">TIDY_ATTR_ABBR</s>
+<s c="TIDY_ATTR_ACCEPT">TIDY_ATTR_ACCEPT_CHARSET</s>
+<s c="TIDY_ATTR_ACCESSKEY">TIDY_ATTR_ACTION</s>
+<s c="TIDY_ATTR_ADD_DATE">TIDY_ATTR_ALIGN</s>
+<s c="TIDY_ATTR_ALINK">TIDY_ATTR_ALT</s>
+<s c="TIDY_ATTR_ARCHIVE">TIDY_ATTR_AXIS</s>
+<s c="TIDY_ATTR_BACKGROUND">TIDY_ATTR_BGCOLOR</s>
+<s c="TIDY_ATTR_BGPROPERTIES">TIDY_ATTR_BORDER</s>
+<s c="TIDY_ATTR_BORDERCOLOR">TIDY_ATTR_BOTTOMMARGIN</s>
+<s c="TIDY_ATTR_CELLPADDING">TIDY_ATTR_CELLSPACING</s>
+<s c="TIDY_ATTR_CHAR">TIDY_ATTR_CHAROFF</s>
+<s c="TIDY_ATTR_CHARSET">TIDY_ATTR_CHECKED</s>
+<s c="TIDY_ATTR_CITE">TIDY_ATTR_CLASS</s>
+<s c="TIDY_ATTR_CLASSID">TIDY_ATTR_CLEAR</s>
+<s c="TIDY_ATTR_CODE">TIDY_ATTR_CODEBASE</s>
+<s c="TIDY_ATTR_CODETYPE">TIDY_ATTR_COLOR</s>
+<s c="TIDY_ATTR_COLS">TIDY_ATTR_COLSPAN</s>
+<s c="TIDY_ATTR_COMPACT">TIDY_ATTR_CONTENT</s>
+<s c="TIDY_ATTR_COORDS">TIDY_ATTR_DATA</s>
+<s c="TIDY_ATTR_DATAFLD">TIDY_ATTR_DATAPAGESIZE</s>
+<s c="TIDY_ATTR_DATASRC">TIDY_ATTR_DATETIME</s>
+<s c="TIDY_ATTR_DECLARE">TIDY_ATTR_DEFER</s>
+<s c="TIDY_ATTR_DIR">TIDY_ATTR_DISABLED</s>
+<s c="TIDY_ATTR_ENCODING">TIDY_ATTR_ENCTYPE</s>
+<s c="TIDY_ATTR_FACE">TIDY_ATTR_FOR</s>
+<s c="TIDY_ATTR_FRAME">TIDY_ATTR_FRAMEBORDER</s>
+<s c="TIDY_ATTR_FRAMESPACING">TIDY_ATTR_GRIDX</s>
+<s c="TIDY_ATTR_GRIDY">TIDY_ATTR_HEADERS</s>
+<s c="TIDY_ATTR_HEIGHT">TIDY_ATTR_HREF</s>
+<s c="TIDY_ATTR_HREFLANG">TIDY_ATTR_HSPACE</s>
+<s c="TIDY_ATTR_HTTP_EQUIV">TIDY_ATTR_ID</s>
+<s c="TIDY_ATTR_ISMAP">TIDY_ATTR_LABEL</s>
+<s c="TIDY_ATTR_LANG">TIDY_ATTR_LANGUAGE</s>
+<s c="TIDY_ATTR_LAST_MODIFIED">TIDY_ATTR_LAST_VISIT</s>
+<s c="TIDY_ATTR_LEFTMARGIN">TIDY_ATTR_LINK</s>
+<s c="TIDY_ATTR_LONGDESC">TIDY_ATTR_LOWSRC</s>
+<s c="TIDY_ATTR_MARGINHEIGHT">TIDY_ATTR_MARGINWIDTH</s>
+<s c="TIDY_ATTR_MAXLENGTH">TIDY_ATTR_MEDIA</s>
+<s c="TIDY_ATTR_METHOD">TIDY_ATTR_MULTIPLE</s>
+<s c="TIDY_ATTR_NAME">TIDY_ATTR_NOHREF</s>
+<s c="TIDY_ATTR_NORESIZE">TIDY_ATTR_NOSHADE</s>
+<s c="TIDY_ATTR_NOWRAP">TIDY_ATTR_OBJECT</s>
+<s c="TIDY_ATTR_PROFILE">TIDY_ATTR_PROMPT</s>
+<s c="TIDY_ATTR_RBSPAN">TIDY_ATTR_READONLY</s>
+<s c="TIDY_ATTR_REL">TIDY_ATTR_REV</s>
+<s c="TIDY_ATTR_RIGHTMARGIN">TIDY_ATTR_ROWS</s>
+<s c="TIDY_ATTR_ROWSPAN">TIDY_ATTR_RULES</s>
+<s c="TIDY_ATTR_SCHEME">TIDY_ATTR_SCOPE</s>
+<s c="TIDY_ATTR_SCROLLING">TIDY_ATTR_SELECTED</s>
+<s c="TIDY_ATTR_SHAPE">TIDY_ATTR_SHOWGRID</s>
+<s c="TIDY_ATTR_SHOWGRIDX">TIDY_ATTR_SHOWGRIDY</s>
+<s c="TIDY_ATTR_SIZE">TIDY_ATTR_SPAN</s>
+<s c="TIDY_ATTR_SRC">TIDY_ATTR_STANDBY</s>
+<s c="TIDY_ATTR_START">TIDY_ATTR_STYLE</s>
+<s c="TIDY_ATTR_SUMMARY">TIDY_ATTR_TABINDEX</s>
+<s c="TIDY_ATTR_TARGET">TIDY_ATTR_TEXT</s>
+<s c="TIDY_ATTR_TITLE">TIDY_ATTR_TOPMARGIN</s>
+<s c="TIDY_ATTR_TYPE">TIDY_ATTR_USEMAP</s>
+<s c="TIDY_ATTR_VALIGN">TIDY_ATTR_VALUE</s>
+<s c="TIDY_ATTR_VALUETYPE">TIDY_ATTR_VERSION</s>
+<s c="TIDY_ATTR_VLINK">TIDY_ATTR_VSPACE</s>
+<s c="TIDY_ATTR_WIDTH">TIDY_ATTR_WRAP</s>
+<s c="TIDY_ATTR_XML_LANG">TIDY_ATTR_XML_SPACE</s>
+<s c="TIDY_ATTR_XMLNS">constant</s>
+<s c="TIDY_NODETYPE_ROOT">root node</s>
+<s c="TIDY_NODETYPE_DOCTYPE">doctype</s>
+<s c="TIDY_NODETYPE_COMMENT">HTML comment</s>
+<s c="TIDY_NODETYPE_PROCINS">Processing Instruction</s>
+<s c="TIDY_NODETYPE_TEXT">Text</s>
+<s c="TIDY_NODETYPE_START">start tag</s>
+<s c="TIDY_NODETYPE_END">end tag</s>
+<s c="TIDY_NODETYPE_STARTEND">empty tag</s>
+<s c="TIDY_NODETYPE_CDATA">CDATA</s>
+<s c="TIDY_NODETYPE_SECTION">XML section</s>
+<s c="TIDY_NODETYPE_ASP">ASP code</s>
+<s c="TIDY_NODETYPE_JSTE">JSTE code</s>
+<s c="TIDY_NODETYPE_PHP">PHP code</s>
+<s c="TIDY_NODETYPE_XMLDECL">XML declaration</s>
+<s c="NEWT_EXIT_HOTKEY">hotkey defined by newt_form_add_hot_key was pressed</s>
+<s c="NEWT_EXIT_COMPONENT">some component has caused form to exit</s>
+<s c="NEWT_EXIT_FDREADY">file descriptor specified in newt_form_watch_fd is ready to be read or written to</s>
+<s c="NEWT_EXIT_TIMER">time specified in newt_form_set_timer has elapsed</s>
+<s c="NEWT_COLORSET_ROOT" /> 
+<s c="NEWT_COLORSET_BORDER" /> 
+<s c="NEWT_COLORSET_WINDOW" /> 
+<s c="NEWT_COLORSET_SHADOW" /> 
+<s c="NEWT_COLORSET_TITLE" /> 
+<s c="NEWT_COLORSET_BUTTON" /> 
+<s c="NEWT_COLORSET_ACTBUTTON" /> 
+<s c="NEWT_COLORSET_CHECKBOX" /> 
+<s c="NEWT_COLORSET_ACTCHECKBOX" /> 
+<s c="NEWT_COLORSET_ENTRY" /> 
+<s c="NEWT_COLORSET_LABEL" /> 
+<s c="NEWT_COLORSET_LISTBOX" /> 
+<s c="NEWT_COLORSET_ACTLISTBOX" /> 
+<s c="NEWT_COLORSET_TEXTBOX" /> 
+<s c="NEWT_COLORSET_ACTTEXTBOX" /> 
+<s c="NEWT_COLORSET_HELPLINE" /> 
+<s c="NEWT_COLORSET_ROOTTEXT" /> 
+<s c="NEWT_COLORSET_ROOTTEXT" /> 
+<s c="NEWT_COLORSET_EMPTYSCALE" /> 
+<s c="NEWT_COLORSET_FULLSCALE" /> 
+<s c="NEWT_COLORSET_DISENTRY" /> 
+<s c="NEWT_COLORSET_COMPACTBUTTON" /> 
+<s c="NEWT_COLORSET_ACTSELLISTBOX" /> 
+<s c="NEWT_COLORSET_SELLISTBOX" /> 
+<s c="NEWT_ARG_LAST" /> 
+<s c="NEWT_ARG_APPEND" /> 
+<s c="NEWT_FLAGS_SET" /> 
+<s c="NEWT_FLAGS_RESET" /> 
+<s c="NEWT_FLAGS_TOGGLE" /> 
+<s c="NEWT_FLAG_RETURNEXIT">Exit form, when component is activated</s>
+<s c="NEWT_FLAG_HIDDEN">Component is hidden</s>
+<s c="NEWT_FLAG_SCROLL">Component is scrollable</s>
+<s c="NEWT_FLAG_DISABLED">Component is disabled</s>
+<s c="NEWT_FLAG_BORDER" /> 
+<s c="NEWT_FLAG_WRAP">Wrap text</s>
+<s c="NEWT_FLAG_NOF12">Don't exit form on pressing F12</s>
+<s c="NEWT_FLAG_MULTIPLE" /> 
+<s c="NEWT_FLAG_SELECTED">Component is selected</s>
+<s c="NEWT_FLAG_CHECKBOX">Component is checkbox</s>
+<s c="NEWT_FLAG_PASSWORD">Entry component is password entry</s>
+<s c="NEWT_FLAG_SHOWCURSOR">Show cursor</s>
+<s c="NEWT_FD_READ" /> 
+<s c="NEWT_FD_WRITE" /> 
+<s c="NEWT_FD_EXCEPT" /> 
+<s c="NEWT_CHECKBOXTREE_UNSELECTABLE" /> 
+<s c="NEWT_CHECKBOXTREE_HIDE_BOX" /> 
+<s c="NEWT_CHECKBOXTREE_COLLAPSED" /> 
+<s c="NEWT_CHECKBOXTREE_EXPANDED" /> 
+<s c="NEWT_CHECKBOXTREE_UNSELECTED" /> 
+<s c="NEWT_CHECKBOXTREE_SELECTED" /> 
+<s c="NEWT_ENTRY_SCROLL" /> 
+<s c="NEWT_ENTRY_HIDDEN" /> 
+<s c="NEWT_ENTRY_RETURNEXIT" /> 
+<s c="NEWT_ENTRY_DISABLED" /> 
+<s c="NEWT_LISTBOX_RETURNEXIT" /> 
+<s c="NEWT_TEXTBOX_WRAP">Wrap text in the textbox</s>
+<s c="NEWT_TEXTBOX_SCROLL">Scroll text in the textbox</s>
+<s c="NEWT_FORM_NOF12">Don't exit form on F12 press</s>
+<s c="NEWT_KEY_TAB" /> 
+<s c="NEWT_KEY_ENTER" /> 
+<s c="NEWT_KEY_SUSPEND" /> 
+<s c="NEWT_KEY_ESCAPE" /> 
+<s c="NEWT_KEY_RETURN" /> 
+<s c="NEWT_KEY_EXTRA_BASE" /> 
+<s c="NEWT_KEY_UP" /> 
+<s c="NEWT_KEY_DOWN" /> 
+<s c="NEWT_KEY_LEFT" /> 
+<s c="NEWT_KEY_RIGHT" /> 
+<s c="NEWT_KEY_BKSPC" /> 
+<s c="NEWT_KEY_DELETE" /> 
+<s c="NEWT_KEY_HOME" /> 
+<s c="NEWT_KEY_END" /> 
+<s c="NEWT_KEY_UNTAB" /> 
+<s c="NEWT_KEY_PGUP" /> 
+<s c="NEWT_KEY_PGDN" /> 
+<s c="NEWT_KEY_INSERT" /> 
+<s c="NEWT_KEY_F1" /> 
+<s c="NEWT_KEY_F2" /> 
+<s c="NEWT_KEY_F3" /> 
+<s c="NEWT_KEY_F4" /> 
+<s c="NEWT_KEY_F5" /> 
+<s c="NEWT_KEY_F6" /> 
+<s c="NEWT_KEY_F7" /> 
+<s c="NEWT_KEY_F8" /> 
+<s c="NEWT_KEY_F9" /> 
+<s c="NEWT_KEY_F10" /> 
+<s c="NEWT_KEY_F11" /> 
+<s c="NEWT_KEY_F12" /> 
+<s c="NEWT_KEY_RESIZE" /> 
+<s c="NEWT_ANCHOR_LEFT" /> 
+<s c="NEWT_ANCHOR_RIGHT" /> 
+<s c="NEWT_ANCHOR_TOP" /> 
+<s c="NEWT_ANCHOR_BOTTOM" /> 
+<s c="NEWT_GRID_FLAG_GROWX" /> 
+<s c="NEWT_GRID_FLAG_GROWY" /> 
+<s c="NEWT_GRID_EMPTY" /> 
+<s c="NEWT_GRID_COMPONENT" /> 
+<s c="NEWT_GRID_SUBGRID" /> 
+<s c="PREG_PATTERN_ORDER">Orders results so that $matches[0] is an array of full pattern matches, $matches[1] is an array of strings matched by the first parenthesized subpattern, and so on. This flag is only used with preg_match_all .</s>
+<s c="PREG_SET_ORDER">Orders results so that $matches[0] is an array of first set of matches, $matches[1] is an array of second set of matches, and so on. This flag is only used with preg_match_all .</s>
+<s c="PREG_OFFSET_CAPTURE">See the description of PREG_SPLIT_OFFSET_CAPTURE . This flag is available since PHP 4.3.0.</s>
+<s c="PREG_SPLIT_NO_EMPTY">This flag tells preg_split to return only non-empty pieces.</s>
+<s c="PREG_SPLIT_DELIM_CAPTURE">This flag tells preg_split to capture parenthesized expression in the delimiter pattern as well. This flag is available since PHP 4.0.5.</s>
+<s c="PREG_SPLIT_OFFSET_CAPTURE">If this flag is set, for every occurring match the appendant string offset will also be returned. Note that this changes the return values in an array where every element is an array consisting of the matched string at offset 0 and its string offset within subject at offset 1. This flag is available since PHP 4.3.0 and is only used for preg_split .</s>
+<s c="PREG_NO_ERROR">Returned by preg_last_error if there were no errors. Available since PHP 5.2.0.</s>
+<s c="PREG_INTERNAL_ERROR">Returned by preg_last_error if there was an internal PCRE error. Available since PHP 5.2.0.</s>
+<s c="PREG_BACKTRACK_LIMIT_ERROR">Returned by preg_last_error if &lt;link linkend=&quot;ini.pcre.backtrack-limit&quot;&gt;backtrack limit was exhausted. Available since PHP 5.2.0.</s>
+<s c="PREG_RECURSION_LIMIT_ERROR">Returned by preg_last_error if &lt;link linkend=&quot;ini.pcre.recursion-limit&quot;&gt;recursion limit was exhausted. Available since PHP 5.2.0.</s>
+<s c="PREG_BAD_UTF8_ERROR">Returned by preg_last_error if the last error was caused by malformed UTF-8 data (only when running a regex in &lt;link linkend=&quot;reference.pcre.pattern.modifiers&quot;&gt;UTF-8 mode ). Available since PHP 5.2.0.</s>
+<s c="PREG_BAD_UTF8_OFFSET_ERROR">Returned by preg_last_error if the offset didn't correspond to the begin of a valid UTF-8 code point (only when running a regex in UTF-8 mode ). Available since PHP 5.3.0.</s>
+<s c="PCRE_VERSION">PCRE version and release date (e.g. &quot;7.0 18-Dec-2006&quot;). Available since PHP 5.2.4.</s>
+<s c="YPERR_ACCESS" />
+<s c="YPERR_BADARGS" />
+<s c="YPERR_BADDB" />
+<s c="YPERR_BUSY" />
+<s c="YPERR_DOMAIN" />
+<s c="YPERR_KEY" />
+<s c="YPERR_MAP" />
+<s c="YPERR_NODOM" />
+<s c="YPERR_NOMORE" />
+<s c="YPERR_PMAP" />
+<s c="YPERR_RESRC" />
+<s c="YPERR_RPC" />
+<s c="YPERR_YPBIND" />
+<s c="YPERR_YPERR" />
+<s c="YPERR_YPSERV" />
+<s c="YPERR_VERS" />
+<s c="SID" />
+<s c="DIRECTORY_SEPARATOR" />
+<s c="PATH_SEPARATOR" />
+<s c="WNOHANG" />
+<s c="WUNTRACED" />
+<s c="SIG_IGN" />
+<s c="SIG_DFL" />
+<s c="SIG_ERR" />
+<s c="SIGHUP" />
+<s c="SIGINT" />
+<s c="SIGQUIT" />
+<s c="SIGILL" />
+<s c="SIGTRAP" />
+<s c="SIGABRT" />
+<s c="SIGIOT" />
+<s c="SIGBUS" />
+<s c="SIGFPE" />
+<s c="SIGKILL" />
+<s c="SIGUSR1" />
+<s c="SIGSEGV" />
+<s c="SIGUSR2" />
+<s c="SIGPIPE" />
+<s c="SIGALRM" />
+<s c="SIGTERM" />
+<s c="SIGSTKFLT" />
+<s c="SIGCLD" />
+<s c="SIGCHLD" />
+<s c="SIGCONT" />
+<s c="SIGSTOP" />
+<s c="SIGTSTP" />
+<s c="SIGTTIN" />
+<s c="SIGTTOU" />
+<s c="SIGURG" />
+<s c="SIGXCPU" />
+<s c="SIGXFSZ" />
+<s c="SIGVTALRM" />
+<s c="SIGPROF" />
+<s c="SIGWINCH" />
+<s c="SIGPOLL" />
+<s c="SIGIO" />
+<s c="SIGPWR" />
+<s c="SIGSYS" />
+<s c="SIGBABY" />
+<s c="SIG_BLOCK" />
+<s c="SIG_UNBLOCK" />
+<s c="SIG_SETMASK" />
+<s c="SI_USER" />
+<s c="SI_NOINFO" />
+<s c="SI_KERNEL" />
+<s c="SI_QUEUE" />
+<s c="SI_TIMER" />
+<s c="SI_MSGGQ" />
+<s c="SI_ASYNCIO" />
+<s c="SI_SIGIO" />
+<s c="SI_TKILL" />
+<s c="CLD_EXITED" />
+<s c="CLD_KILLED" />
+<s c="CLD_DUMPED" />
+<s c="CLD_TRAPPED" />
+<s c="CLD_STOPPED" />
+<s c="CLD_CONTINUED" />
+<s c="TRAP_BRKPT" />
+<s c="TRAP_TRACE" />
+<s c="POLL_IN" />
+<s c="POLL_OUT" />
+<s c="POLL_MSG" />
+<s c="POLL_ERR" />
+<s c="POLL_PRI" />
+<s c="POLL_HUP" />
+<s c="ILL_ILLOPC" />
+<s c="ILL_ILLOPN" />
+<s c="ILL_ILLADR" />
+<s c="ILL_ILLTRP" />
+<s c="ILL_PRVOPC" />
+<s c="ILL_PRVREG" />
+<s c="ILL_COPROC" />
+<s c="ILL_BADSTK" />
+<s c="FPE_INTDIV" />
+<s c="FPE_INTOVF" />
+<s c="FPE_FLTDIV" />
+<s c="FPE_FLTOVF" />
+<s c="FPE_FLTUND" />
+<s c="FPE_FLTRES" />
+<s c="FPE_FLTINV" />
+<s c="FPE_FLTSUB" />
+<s c="SEGV_MAPERR" />
+<s c="SEGV_ACCERR" />
+<s c="BUS_ADRALN" />
+<s c="BUS_ADRERR" />
+<s c="BUS_OBJERR" />
+<s c="Swish::META_TYPE_UNDEF" />
+<s c="Swish::META_TYPE_STRING" />
+<s c="Swish::META_TYPE_ULONG" />
+<s c="Swish::META_TYPE_DATE" />
+<s c="Swish::IN_FILE_BIT" />
+<s c="Swish::IN_TITLE_BIT" />
+<s c="Swish::IN_HEAD_BIT" />
+<s c="Swish::IN_BODY_BIT" />
+<s c="Swish::IN_COMMENTS_BIT" />
+<s c="Swish::IN_HEADER_BIT" />
+<s c="Swish::IN_EMPHASIZED_BIT" />
+<s c="Swish::IN_META_BIT" />
+<s c="Swish::IN_FILE" />
+<s c="Swish::IN_TITLE" />
+<s c="Swish::IN_HEAD" />
+<s c="Swish::IN_BODY" />
+<s c="Swish::IN_COMMENTS" />
+<s c="Swish::IN_HEADER" />
+<s c="Swish::IN_EMPHASIZED" />
+<s c="Swish::IN_META" />
+<s c="Swish::IN_ALL" />
+<s c="XDIFF_PATCH_NORMAL" />
+<s c="XDIFF_PATCH_REVERSE" />
+<s c="CREDITS_GROUP">1</s>
+<s c="CREDITS_GENERAL">2</s>
+<s c="CREDITS_SAPI">4</s>
+<s c="CREDITS_MODULES">8</s>
+<s c="CREDITS_DOCS">16</s>
+<s c="CREDITS_FULLPAGE">32</s>
+<s c="CREDITS_QA">64</s>
+<s c="CREDITS_ALL">-1</s>
+<s c="INFO_GENERAL">1</s>
+<s c="INFO_CREDITS">2</s>
+<s c="INFO_CONFIGURATION">4</s>
+<s c="INFO_MODULES">8</s>
+<s c="INFO_ENVIRONMENT">16</s>
+<s c="INFO_VARIABLES">32</s>
+<s c="INFO_LICENSE">64</s>
+<s c="INFO_ALL">-1</s>
+<s c="imagick::COLOR_BLACK" />
+<s c="imagick::COLOR_BLUE" />
+<s c="imagick::COLOR_CYAN" />
+<s c="imagick::COLOR_GREEN" />
+<s c="imagick::COLOR_RED" />
+<s c="imagick::COLOR_YELLOW" />
+<s c="imagick::COLOR_MAGENTA" />
+<s c="imagick::COLOR_OPACITY" />
+<s c="imagick::COLOR_ALPHA" />
+<s c="imagick::COLOR_FUZZ" />
+<s c="imagick::DISPOSE_UNRECOGNIZED" />
+<s c="imagick::DISPOSE_UNDEFINED" />
+<s c="imagick::DISPOSE_NONE" />
+<s c="imagick::DISPOSE_BACKGROUND" />
+<s c="imagick::DISPOSE_PREVIOUS" />
+<s c="imagick::COMPOSITE_DEFAULT" />
+<s c="imagick::COMPOSITE_UNDEFINED" />
+<s c="imagick::COMPOSITE_NO" />
+<s c="imagick::COMPOSITE_ADD" />
+<s c="imagick::COMPOSITE_ATOP" />
+<s c="imagick::COMPOSITE_BLEND" />
+<s c="imagick::COMPOSITE_BUMPMAP" />
+<s c="imagick::COMPOSITE_CLEAR" />
+<s c="imagick::COMPOSITE_COLORBURN" />
+<s c="imagick::COMPOSITE_COLORDODGE" />
+<s c="imagick::COMPOSITE_COLORIZE" />
+<s c="imagick::COMPOSITE_COPYBLACK" />
+<s c="imagick::COMPOSITE_COPYBLUE" />
+<s c="imagick::COMPOSITE_COPY" />
+<s c="imagick::COMPOSITE_COPYCYAN" />
+<s c="imagick::COMPOSITE_COPYGREEN" />
+<s c="imagick::COMPOSITE_COPYMAGENTA" />
+<s c="imagick::COMPOSITE_COPYOPACITY" />
+<s c="imagick::COMPOSITE_COPYRED" />
+<s c="imagick::COMPOSITE_COPYYELLOW" />
+<s c="imagick::COMPOSITE_DARKEN" />
+<s c="imagick::COMPOSITE_DSTATOP" />
+<s c="imagick::COMPOSITE_DST" />
+<s c="imagick::COMPOSITE_DSTIN" />
+<s c="imagick::COMPOSITE_DSTOUT" />
+<s c="imagick::COMPOSITE_DSTOVER" />
+<s c="imagick::COMPOSITE_DIFFERENCE" />
+<s c="imagick::COMPOSITE_DISPLACE" />
+<s c="imagick::COMPOSITE_DISSOLVE" />
+<s c="imagick::COMPOSITE_EXCLUSION" />
+<s c="imagick::COMPOSITE_HARDLIGHT" />
+<s c="imagick::COMPOSITE_HUE" />
+<s c="imagick::COMPOSITE_IN" />
+<s c="imagick::COMPOSITE_LIGHTEN" />
+<s c="imagick::COMPOSITE_LUMINIZE" />
+<s c="imagick::COMPOSITE_MINUS" />
+<s c="imagick::COMPOSITE_MODULATE" />
+<s c="imagick::COMPOSITE_MULTIPLY" />
+<s c="imagick::COMPOSITE_OUT" />
+<s c="imagick::COMPOSITE_OVER" />
+<s c="imagick::COMPOSITE_OVERLAY" />
+<s c="imagick::COMPOSITE_PLUS" />
+<s c="imagick::COMPOSITE_REPLACE" />
+<s c="imagick::COMPOSITE_SATURATE" />
+<s c="imagick::COMPOSITE_SCREEN" />
+<s c="imagick::COMPOSITE_SOFTLIGHT" />
+<s c="imagick::COMPOSITE_SRCATOP" />
+<s c="imagick::COMPOSITE_SRC" />
+<s c="imagick::COMPOSITE_SRCIN" />
+<s c="imagick::COMPOSITE_SRCOUT" />
+<s c="imagick::COMPOSITE_SRCOVER" />
+<s c="imagick::COMPOSITE_SUBTRACT" />
+<s c="imagick::COMPOSITE_THRESHOLD" />
+<s c="imagick::COMPOSITE_XOR" />
+<s c="imagick::MONTAGEMODE_FRAME" />
+<s c="imagick::MONTAGEMODE_UNFRAME" />
+<s c="imagick::MONTAGEMODE_CONCATENATE" />
+<s c="imagick::STYLE_NORMAL" />
+<s c="imagick::STYLE_ITALIC" />
+<s c="imagick::STYLE_OBLIQUE" />
+<s c="imagick::STYLE_ANY" />
+<s c="imagick::FILTER_UNDEFINED" />
+<s c="imagick::FILTER_POINT" />
+<s c="imagick::FILTER_BOX" />
+<s c="imagick::FILTER_TRIANGLE" />
+<s c="imagick::FILTER_HERMITE" />
+<s c="imagick::FILTER_HANNING" />
+<s c="imagick::FILTER_HAMMING" />
+<s c="imagick::FILTER_BLACKMAN" />
+<s c="imagick::FILTER_GAUSSIAN" />
+<s c="imagick::FILTER_QUADRATIC" />
+<s c="imagick::FILTER_CUBIC" />
+<s c="imagick::FILTER_CATROM" />
+<s c="imagick::FILTER_MITCHELL" />
+<s c="imagick::FILTER_LANCZOS" />
+<s c="imagick::FILTER_BESSEL" />
+<s c="imagick::FILTER_SINC" />
+<s c="imagick::IMGTYPE_UNDEFINED" />
+<s c="imagick::IMGTYPE_BILEVEL" />
+<s c="imagick::IMGTYPE_GRAYSCALE" />
+<s c="imagick::IMGTYPE_GRAYSCALEMATTE" />
+<s c="imagick::IMGTYPE_PALETTE" />
+<s c="imagick::IMGTYPE_PALETTEMATTE" />
+<s c="imagick::IMGTYPE_TRUECOLOR" />
+<s c="imagick::IMGTYPE_TRUECOLORMATTE" />
+<s c="imagick::IMGTYPE_COLORSEPARATION" />
+<s c="imagick::IMGTYPE_COLORSEPARATIONMATTE" />
+<s c="imagick::IMGTYPE_OPTIMIZE" />
+<s c="imagick::RESOLUTION_UNDEFINED" />
+<s c="imagick::RESOLUTION_PIXELSPERINCH" />
+<s c="imagick::RESOLUTION_PIXELSPERCENTIMETER" />
+<s c="imagick::COMPRESSION_UNDEFINED" />
+<s c="imagick::COMPRESSION_NO" />
+<s c="imagick::COMPRESSION_BZIP" />
+<s c="imagick::COMPRESSION_FAX" />
+<s c="imagick::COMPRESSION_GROUP4" />
+<s c="imagick::COMPRESSION_JPEG" />
+<s c="imagick::COMPRESSION_JPEG2000" />
+<s c="imagick::COMPRESSION_LOSSLESSJPEG" />
+<s c="imagick::COMPRESSION_LZW" />
+<s c="imagick::COMPRESSION_RLE" />
+<s c="imagick::COMPRESSION_ZIP" />
+<s c="imagick::PAINT_POINT" />
+<s c="imagick::PAINT_REPLACE" />
+<s c="imagick::PAINT_FLOODFILL" />
+<s c="imagick::PAINT_FILLTOBORDER" />
+<s c="imagick::PAINT_RESET" />
+<s c="imagick::GRAVITY_NORTHWEST" />
+<s c="imagick::GRAVITY_NORTH" />
+<s c="imagick::GRAVITY_NORTHEAST" />
+<s c="imagick::GRAVITY_WEST" />
+<s c="imagick::GRAVITY_CENTER" />
+<s c="imagick::GRAVITY_EAST" />
+<s c="imagick::GRAVITY_SOUTHWEST" />
+<s c="imagick::GRAVITY_SOUTH" />
+<s c="imagick::GRAVITY_SOUTHEAST" />
+<s c="imagick::STRETCH_NORMAL" />
+<s c="imagick::STRETCH_ULTRACONDENSED" />
+<s c="imagick::STRETCH_CONDENSED" />
+<s c="imagick::STRETCH_SEMICONDENSED" />
+<s c="imagick::STRETCH_SEMIEXPANDED" />
+<s c="imagick::STRETCH_EXPANDED" />
+<s c="imagick::STRETCH_EXTRAEXPANDED" />
+<s c="imagick::STRETCH_ULTRAEXPANDED" />
+<s c="imagick::STRETCH_ANY" />
+<s c="imagick::ALIGN_UNDEFINED" />
+<s c="imagick::ALIGN_LEFT" />
+<s c="imagick::ALIGN_CENTER" />
+<s c="imagick::ALIGN_RIGHT" />
+<s c="imagick::DECORATION_NO" />
+<s c="imagick::DECORATION_UNDERLINE" />
+<s c="imagick::DECORATION_OVERLINE" />
+<s c="imagick::DECORATION_LINETROUGH" />
+<s c="imagick::NOISE_UNIFORM" />
+<s c="imagick::NOISE_GAUSSIAN" />
+<s c="imagick::NOISE_MULTIPLICATIVEGAUSSIAN" />
+<s c="imagick::NOISE_IMPULSE" />
+<s c="imagick::NOISE_LAPLACIAN" />
+<s c="imagick::NOISE_POISSON" />
+<s c="imagick::CHANNEL_UNDEFINED" />
+<s c="imagick::CHANNEL_RED" />
+<s c="imagick::CHANNEL_GRAY" />
+<s c="imagick::CHANNEL_CYAN" />
+<s c="imagick::CHANNEL_GREEN" />
+<s c="imagick::CHANNEL_MAGENTA" />
+<s c="imagick::CHANNEL_BLUE" />
+<s c="imagick::CHANNEL_YELLOW" />
+<s c="imagick::CHANNEL_ALPHA" />
+<s c="imagick::CHANNEL_OPACITY" />
+<s c="imagick::CHANNEL_MATTE" />
+<s c="imagick::CHANNEL_BLACK" />
+<s c="imagick::CHANNEL_INDEX" />
+<s c="imagick::CHANNEL_ALL" />
+<s c="imagick::METRIC_UNDEFINED" />
+<s c="imagick::METRIC_MEANABSOLUTEERROR" />
+<s c="imagick::METRIC_MEANSQUAREERROR" />
+<s c="imagick::METRIC_PEAKABSOLUTEERROR" />
+<s c="imagick::METRIC_PEAKSIGNALTONOISERATIO" />
+<s c="imagick::METRIC_ROOTMEANSQUAREDERROR" />
+<s c="imagick::PIXEL_CHAR" />
+<s c="imagick::PIXEL_DOUBLE" />
+<s c="imagick::PIXEL_FLOAT" />
+<s c="imagick::PIXEL_INTEGER" />
+<s c="imagick::PIXEL_LONG" />
+<s c="imagick::PIXEL_QUANTUM" />
+<s c="imagick::PIXEL_SHORT" />
+<s c="imagick::EVALUATE_UNDEFINED" />
+<s c="imagick::EVALUATE_ADD" />
+<s c="imagick::EVALUATE_AND" />
+<s c="imagick::EVALUATE_DIVIDE" />
+<s c="imagick::EVALUATE_LEFTSHIFT" />
+<s c="imagick::EVALUATE_MAX" />
+<s c="imagick::EVALUATE_MIN" />
+<s c="imagick::EVALUATE_MULTIPLY" />
+<s c="imagick::EVALUATE_OR" />
+<s c="imagick::EVALUATE_RIGHTSHIFT" />
+<s c="imagick::EVALUATE_SET" />
+<s c="imagick::EVALUATE_SUBTRACT" />
+<s c="imagick::EVALUATE_XOR" />
+<s c="imagick::COLORSPACE_UNDEFINED" />
+<s c="imagick::COLORSPACE_RGB" />
+<s c="imagick::COLORSPACE_GRAY" />
+<s c="imagick::COLORSPACE_TRANSPARENT" />
+<s c="imagick::COLORSPACE_OHTA" />
+<s c="imagick::COLORSPACE_LAB" />
+<s c="imagick::COLORSPACE_XYZ" />
+<s c="imagick::COLORSPACE_YCBCR" />
+<s c="imagick::COLORSPACE_YCC" />
+<s c="imagick::COLORSPACE_YIQ" />
+<s c="imagick::COLORSPACE_YPBPR" />
+<s c="imagick::COLORSPACE_YUV" />
+<s c="imagick::COLORSPACE_CMYK" />
+<s c="imagick::COLORSPACE_SRGB" />
+<s c="imagick::COLORSPACE_HSB" />
+<s c="imagick::COLORSPACE_HSL" />
+<s c="imagick::COLORSPACE_HWB" />
+<s c="imagick::COLORSPACE_REC601LUMA" />
+<s c="imagick::COLORSPACE_REC709LUMA" />
+<s c="imagick::COLORSPACE_LOG" />
+<s c="imagick::VIRTUALPIXELMETHOD_UNDEFINED" />
+<s c="imagick::VIRTUALPIXELMETHOD_BACKGROUND" />
+<s c="imagick::VIRTUALPIXELMETHOD_CONSTANT" />
+<s c="imagick::VIRTUALPIXELMETHOD_EDGE" />
+<s c="imagick::VIRTUALPIXELMETHOD_MIRROR" />
+<s c="imagick::VIRTUALPIXELMETHOD_TILE" />
+<s c="imagick::VIRTUALPIXELMETHOD_TRANSPARENT" />
+<s c="imagick::PREVIEW_UNDEFINED" />
+<s c="imagick::PREVIEW_ROTATE" />
+<s c="imagick::PREVIEW_SHEAR" />
+<s c="imagick::PREVIEW_ROLL" />
+<s c="imagick::PREVIEW_HUE" />
+<s c="imagick::PREVIEW_SATURATION" />
+<s c="imagick::PREVIEW_BRIGHTNESS" />
+<s c="imagick::PREVIEW_GAMMA" />
+<s c="imagick::PREVIEW_SPIFF" />
+<s c="imagick::PREVIEW_DULL" />
+<s c="imagick::PREVIEW_GRAYSCALE" />
+<s c="imagick::PREVIEW_QUANTIZE" />
+<s c="imagick::PREVIEW_DESPECKLE" />
+<s c="imagick::PREVIEW_REDUCENOISE" />
+<s c="imagick::PREVIEW_ADDNOISE" />
+<s c="imagick::PREVIEW_SHARPEN" />
+<s c="imagick::PREVIEW_BLUR" />
+<s c="imagick::PREVIEW_THRESHOLD" />
+<s c="imagick::PREVIEW_EDGEDETECT" />
+<s c="imagick::PREVIEW_SPREAD" />
+<s c="imagick::PREVIEW_SOLARIZE" />
+<s c="imagick::PREVIEW_SHADE" />
+<s c="imagick::PREVIEW_RAISE" />
+<s c="imagick::PREVIEW_SEGMENT" />
+<s c="imagick::PREVIEW_SWIRL" />
+<s c="imagick::PREVIEW_IMPLODE" />
+<s c="imagick::PREVIEW_WAVE" />
+<s c="imagick::PREVIEW_OILPAINT" />
+<s c="imagick::PREVIEW_CHARCOALDRAWING" />
+<s c="imagick::PREVIEW_JPEG" />
+<s c="imagick::RENDERINGINTENT_UNDEFINED" />
+<s c="imagick::RENDERINGINTENT_SATURATION" />
+<s c="imagick::RENDERINGINTENT_PERCEPTUAL" />
+<s c="imagick::RENDERINGINTENT_ABSOLUTE" />
+<s c="imagick::RENDERINGINTENT_RELATIVE" />
+<s c="imagick::INTERLACE_UNDEFINED" />
+<s c="imagick::INTERLACE_NO" />
+<s c="imagick::INTERLACE_LINE" />
+<s c="imagick::INTERLACE_PLANE" />
+<s c="imagick::INTERLACE_PARTITION" />
+<s c="imagick::INTERLACE_JPEG" />
+<s c="imagick::INTERLACE_GIF" />
+<s c="imagick::INTERLACE_PNG" />
+<s c="imagick::FILLRULE_UNDEFINED" />
+<s c="imagick::FILLRULE_EVENODD" />
+<s c="imagick::FILLRULE_NONZERO" />
+<s c="imagick::PATHUNITS_UNDEFINED" />
+<s c="imagick::PATHUNITS_USERSPACE" />
+<s c="imagick::PATHUNITS_USERSPACEONUSE" />
+<s c="imagick::PATHUNITS_OBJECTBOUNDINGBOX" />
+<s c="imagick::LINECAP_UNDEFINED" />
+<s c="imagick::LINECAP_BUTT" />
+<s c="imagick::LINECAP_ROUND" />
+<s c="imagick::LINECAP_SQUARE" />
+<s c="imagick::LINEJOIN_UNDEFINED" />
+<s c="imagick::LINEJOIN_MITER" />
+<s c="imagick::LINEJOIN_ROUND" />
+<s c="imagick::LINEJOIN_BEVEL" />
+<s c="imagick::RESOURCETYPE_UNDEFINED" />
+<s c="imagick::RESOURCETYPE_AREA" />
+<s c="imagick::RESOURCETYPE_DISK" />
+<s c="imagick::RESOURCETYPE_FILE" />
+<s c="imagick::RESOURCETYPE_MAP" />
+<s c="imagick::RESOURCETYPE_MEMORY" />
+<s c="imagick::LAYERMETHOD_UNDEFINED" />
+<s c="imagick::LAYERMETHOD_COALESCE" />
+<s c="imagick::LAYERMETHOD_COMPAREANY" />
+<s c="imagick::LAYERMETHOD_COMPARECLEAR" />
+<s c="imagick::LAYERMETHOD_COMPAREOVERLAY" />
+<s c="imagick::LAYERMETHOD_DISPOSE" />
+<s c="imagick::LAYERMETHOD_OPTIMIZE" />
+<s c="imagick::LAYERMETHOD_OPTIMIZEIMAGE" />
+<s c="imagick::LAYERMETHOD_OPTIMIZEPLUS" />
+<s c="imagick::LAYERMETHOD_OPTIMIZETRANS" />
+<s c="imagick::LAYERMETHOD_REMOVEDUPS" />
+<s c="imagick::LAYERMETHOD_REMOVEZERO" />
+<s c="imagick::LAYERMETHOD_COMPOSITE" />
+<s c="imagick::ORIENTATION_UNDEFINED" />
+<s c="imagick::ORIENTATION_TOPLEFT" />
+<s c="imagick::ORIENTATION_TOPRIGHT" />
+<s c="imagick::ORIENTATION_BOTTOMRIGHT" />
+<s c="imagick::ORIENTATION_BOTTOMLEFT" />
+<s c="imagick::ORIENTATION_LEFTTOP" />
+<s c="imagick::ORIENTATION_RIGHTTOP" />
+<s c="imagick::ORIENTATION_RIGHTBOTTOM" />
+<s c="imagick::ORIENTATION_LEFTBOTTOM" />
+<s c="imagick::DISTORTION_UNDEFINED" />
+<s c="imagick::DISTORTION_AFFINE" />
+<s c="imagick::DISTORTION_AFFINEPROJECTION" />
+<s c="imagick::DISTORTION_ARC" />
+<s c="imagick::DISTORTION_BILINEAR" />
+<s c="imagick::DISTORTION_PERSPECTIVE" />
+<s c="imagick::DISTORTION_PERSPECTIVEPROJECTION" />
+<s c="imagick::DISTORTION_SCALEROTATETRANSLATE" />
+</phpstandardsyntax>
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/togglepresentation.gif b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/togglepresentation.gif
new file mode 100644 (file)
index 0000000..a0831f0
Binary files /dev/null and b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/togglepresentation.gif differ
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/HTMLWordDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/HTMLWordDetector.java
new file mode 100644 (file)
index 0000000..517c1c7
--- /dev/null
@@ -0,0 +1,38 @@
+package net.sourceforge.phpeclipse.phpeditor.util;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * A Java aware word detector.
+ */
+public class HTMLWordDetector implements IWordDetector {
+
+       /*
+        * (non-Javadoc) Method declared on IWordDetector.
+        */
+       public boolean isWordPart(char character) {
+               return Scanner.isPHPIdentifierPart(character) || (character == '/')
+                               || (character == '>');
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IWordDetector.
+        */
+       public boolean isWordStart(char character) {
+               return character == '<';
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPColorProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPColorProvider.java
new file mode 100644 (file)
index 0000000..972a207
--- /dev/null
@@ -0,0 +1,86 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Manager for colors used in the Java editor
+ */
+public class PHPColorProvider {
+
+       public static final RGB MULTI_LINE_COMMENT = new RGB(63, 127, 95);
+
+       public static final RGB SINGLE_LINE_COMMENT = new RGB(63, 127, 95);
+
+       public static final RGB TAG = new RGB(255, 0, 128);
+
+       public static final RGB KEYWORD = new RGB(127, 0, 85);
+
+       public static final RGB VARIABLE = new RGB(127, 159, 191);
+
+       public static final /*RGB*/String FUNCTION_NAME = "127, 127, 159"; //new RGB(127, 127, 159);
+
+       public static final RGB STRING_DQ = new RGB(42, 0, 255);
+
+       public static final RGB STRING_SQ = new RGB(42, 0, 255);
+
+       public static final RGB DEFAULT = new RGB(0, 0, 0);
+
+       public static final RGB TYPE = new RGB(127, 0, 85);
+
+       public static final RGB CONSTANT = new RGB(127, 0, 85);
+
+       public static final RGB BACKGROUND = new RGB(255, 255, 255);
+
+       // public static final RGB LINKED_POSITION_COLOR = new RGB(0, 0, 0);
+
+       // public static final RGB LINE_NUMBER_COLOR = new RGB(0, 0, 0);
+       // public static final RGB BACKGROUND_COLOR = new RGB(255, 255, 255);
+
+       public static final RGB PHPDOC_TAG = new RGB(63, 127, 95);
+
+       public static final RGB PHPDOC_LINK = new RGB(63, 63, 191);
+
+       public static final RGB PHPDOC_DEFAULT = new RGB(63, 95, 191);
+
+       public static final RGB PHPDOC_KEYWORD = new RGB(127, 159, 191);
+
+       protected Map fColorTable = new HashMap(10);
+
+       /**
+        * Release all of the color resources held onto by the receiver.
+        */
+       public void dispose() {
+               Iterator e = fColorTable.values().iterator();
+               while (e.hasNext())
+                       ((Color) e.next()).dispose();
+       }
+
+       /**
+        * Return the Color that is stored in the Color table as rgb.
+        */
+       public Color getColor(RGB rgb) {
+               Color color = (Color) fColorTable.get(rgb);
+               if (color == null) {
+                       color = new Color(Display.getCurrent(), rgb);
+                       fColorTable.put(rgb, color);
+               }
+               return color;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPVariableDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPVariableDetector.java
new file mode 100644 (file)
index 0000000..b1c4b1b
--- /dev/null
@@ -0,0 +1,37 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.util;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * A PHP aware variable detector (i.e. a PHP identifier starting with a '$'
+ * character).
+ */
+public class PHPVariableDetector implements IWordDetector {
+
+       /*
+        * (non-Javadoc) Method declared on IWordDetector.
+        */
+       public boolean isWordPart(char character) {
+               return Scanner.isPHPIdentifierPart(character);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IWordDetector.
+        */
+       public boolean isWordStart(char character) {
+               return character == '$';
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPWhitespaceDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPWhitespaceDetector.java
new file mode 100644 (file)
index 0000000..65337cf
--- /dev/null
@@ -0,0 +1,27 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.util;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+/**
+ * A java aware white space detector.
+ */
+public class PHPWhitespaceDetector implements IWhitespaceDetector {
+
+       /*
+        * (non-Javadoc) Method declared on IWhitespaceDetector
+        */
+       public boolean isWhitespace(char character) {
+               return Character.isWhitespace(character);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPWordDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/util/PHPWordDetector.java
new file mode 100644 (file)
index 0000000..c799309
--- /dev/null
@@ -0,0 +1,36 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.util;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * A PHP aware word detector.
+ */
+public class PHPWordDetector implements IWordDetector {
+
+       /*
+        * (non-Javadoc) Method declared on IWordDetector.
+        */
+       public boolean isWordPart(char character) {
+               return Scanner.isPHPIdentifierPart(character);
+       }
+
+       /*
+        * (non-Javadoc) Method declared on IWordDetector.
+        */
+       public boolean isWordStart(char character) {
+               return Scanner.isPHPIdentOrVarStart(character);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/ColorEditor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/ColorEditor.java
new file mode 100644 (file)
index 0000000..5a2cef9
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpeclipse.preferences;
+
+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.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.ColorDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A "button" of a certain color determined by the color picker.
+ */
+public class ColorEditor {
+
+       private Point fExtent;
+
+       private Image fImage;
+
+       private RGB fColorValue;
+
+       private Color fColor;
+
+       private Button fButton;
+
+       public ColorEditor(Composite parent) {
+
+               fButton = new Button(parent, SWT.PUSH);
+               fExtent = computeImageSize(parent);
+               fImage = new Image(parent.getDisplay(), fExtent.x, fExtent.y);
+
+               GC gc = new GC(fImage);
+               gc.setBackground(fButton.getBackground());
+               gc.fillRectangle(0, 0, fExtent.x, fExtent.y);
+               gc.dispose();
+
+               fButton.setImage(fImage);
+               fButton.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent event) {
+                               ColorDialog colorDialog = new ColorDialog(fButton.getShell());
+                               colorDialog.setRGB(fColorValue);
+                               RGB newColor = colorDialog.open();
+                               if (newColor != null) {
+                                       fColorValue = newColor;
+                                       updateColorImage();
+                               }
+                       }
+               });
+
+               fButton.addDisposeListener(new DisposeListener() {
+                       public void widgetDisposed(DisposeEvent event) {
+                               if (fImage != null) {
+                                       fImage.dispose();
+                                       fImage = null;
+                               }
+                               if (fColor != null) {
+                                       fColor.dispose();
+                                       fColor = null;
+                               }
+                       }
+               });
+       }
+
+       public RGB getColorValue() {
+               return fColorValue;
+       }
+
+       public void setColorValue(RGB rgb) {
+               fColorValue = rgb;
+               updateColorImage();
+       }
+
+       public Button getButton() {
+               return fButton;
+       }
+
+       protected void updateColorImage() {
+
+               Display display = fButton.getDisplay();
+
+               GC gc = new GC(fImage);
+               gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
+               gc.drawRectangle(0, 2, fExtent.x - 1, fExtent.y - 4);
+
+               if (fColor != null)
+                       fColor.dispose();
+
+               fColor = new Color(display, fColorValue);
+               gc.setBackground(fColor);
+               gc.fillRectangle(1, 3, fExtent.x - 2, fExtent.y - 5);
+               gc.dispose();
+
+               fButton.setImage(fImage);
+       }
+
+       protected Point computeImageSize(Control window) {
+               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;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/OverlayPreferenceStore.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/OverlayPreferenceStore.java
new file mode 100644 (file)
index 0000000..917e813
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+package net.sourceforge.phpeclipse.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * An overlaying preference store.
+ */
+public class OverlayPreferenceStore implements IPreferenceStore {
+
+       public static final class TypeDescriptor {
+               private TypeDescriptor() {
+               }
+       };
+
+       public static final TypeDescriptor BOOLEAN = new TypeDescriptor();
+
+       public static final TypeDescriptor DOUBLE = new TypeDescriptor();
+
+       public static final TypeDescriptor FLOAT = new TypeDescriptor();
+
+       public static final TypeDescriptor INT = new TypeDescriptor();
+
+       public static final TypeDescriptor LONG = new TypeDescriptor();
+
+       public static final TypeDescriptor STRING = new TypeDescriptor();
+
+       public static class OverlayKey {
+
+               TypeDescriptor fDescriptor;
+
+               String fKey;
+
+               public OverlayKey(TypeDescriptor descriptor, String key) {
+                       fDescriptor = descriptor;
+                       fKey = key;
+               }
+       };
+
+       private class PropertyListener implements IPropertyChangeListener {
+
+               /*
+                * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+                */
+               public void propertyChange(PropertyChangeEvent event) {
+                       OverlayKey key = findOverlayKey(event.getProperty());
+                       if (key != null)
+                               propagateProperty(fParent, key, fStore);
+               }
+       };
+
+       private IPreferenceStore fParent;
+
+       private IPreferenceStore fStore;
+
+       private OverlayKey[] fOverlayKeys;
+
+       private PropertyListener fPropertyListener;
+
+       public OverlayPreferenceStore(IPreferenceStore parent,
+                       OverlayKey[] overlayKeys) {
+               fParent = parent;
+               fOverlayKeys = overlayKeys;
+               fStore = new PreferenceStore();
+       }
+
+       private OverlayKey findOverlayKey(String key) {
+               for (int i = 0; i < fOverlayKeys.length; i++) {
+                       if (fOverlayKeys[i].fKey.equals(key))
+                               return fOverlayKeys[i];
+               }
+               return null;
+       }
+
+       private boolean covers(String key) {
+               return (findOverlayKey(key) != null);
+       }
+
+       private void propagateProperty(IPreferenceStore orgin, OverlayKey key,
+                       IPreferenceStore target) {
+
+               if (orgin.isDefault(key.fKey)) {
+                       if (!target.isDefault(key.fKey))
+                               target.setToDefault(key.fKey);
+                       return;
+               }
+
+               TypeDescriptor d = key.fDescriptor;
+               if (BOOLEAN == d) {
+
+                       boolean originValue = orgin.getBoolean(key.fKey);
+                       boolean targetValue = target.getBoolean(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (DOUBLE == d) {
+
+                       double originValue = orgin.getDouble(key.fKey);
+                       double targetValue = target.getDouble(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (FLOAT == d) {
+
+                       float originValue = orgin.getFloat(key.fKey);
+                       float targetValue = target.getFloat(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (INT == d) {
+
+                       int originValue = orgin.getInt(key.fKey);
+                       int targetValue = target.getInt(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (LONG == d) {
+
+                       long originValue = orgin.getLong(key.fKey);
+                       long targetValue = target.getLong(key.fKey);
+                       if (targetValue != originValue)
+                               target.setValue(key.fKey, originValue);
+
+               } else if (STRING == d) {
+
+                       String originValue = orgin.getString(key.fKey);
+                       String targetValue = target.getString(key.fKey);
+                       if (targetValue != null && originValue != null
+                                       && !targetValue.equals(originValue))
+                               target.setValue(key.fKey, originValue);
+
+               }
+       }
+
+       public void propagate() {
+               for (int i = 0; i < fOverlayKeys.length; i++)
+                       propagateProperty(fStore, fOverlayKeys[i], fParent);
+       }
+
+       private void loadProperty(IPreferenceStore orgin, OverlayKey key,
+                       IPreferenceStore target, boolean forceInitialization) {
+               TypeDescriptor d = key.fDescriptor;
+               if (BOOLEAN == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, true);
+                       target.setValue(key.fKey, orgin.getBoolean(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultBoolean(key.fKey));
+
+               } else if (DOUBLE == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, 1.0D);
+                       target.setValue(key.fKey, orgin.getDouble(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultDouble(key.fKey));
+
+               } else if (FLOAT == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, 1.0F);
+                       target.setValue(key.fKey, orgin.getFloat(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultFloat(key.fKey));
+
+               } else if (INT == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, 1);
+                       target.setValue(key.fKey, orgin.getInt(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultInt(key.fKey));
+
+               } else if (LONG == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, 1L);
+                       target.setValue(key.fKey, orgin.getLong(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultLong(key.fKey));
+
+               } else if (STRING == d) {
+
+                       if (forceInitialization)
+                               target.setValue(key.fKey, "1"); //$NON-NLS-1$
+                       target.setValue(key.fKey, orgin.getString(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultString(key.fKey));
+
+               }
+       }
+
+       public void load() {
+               for (int i = 0; i < fOverlayKeys.length; i++)
+                       loadProperty(fParent, fOverlayKeys[i], fStore, true);
+       }
+
+       public void loadDefaults() {
+               for (int i = 0; i < fOverlayKeys.length; i++)
+                       setToDefault(fOverlayKeys[i].fKey);
+       }
+
+       public void start() {
+               if (fPropertyListener == null) {
+                       fPropertyListener = new PropertyListener();
+                       fParent.addPropertyChangeListener(fPropertyListener);
+               }
+       }
+
+       public void stop() {
+               if (fPropertyListener != null) {
+                       fParent.removePropertyChangeListener(fPropertyListener);
+                       fPropertyListener = null;
+               }
+       }
+
+       /*
+        * @see IPreferenceStore#addPropertyChangeListener(IPropertyChangeListener)
+        */
+       public void addPropertyChangeListener(IPropertyChangeListener listener) {
+               fStore.addPropertyChangeListener(listener);
+       }
+
+       /*
+        * @see IPreferenceStore#removePropertyChangeListener(IPropertyChangeListener)
+        */
+       public void removePropertyChangeListener(IPropertyChangeListener listener) {
+               fStore.removePropertyChangeListener(listener);
+       }
+
+       /*
+        * @see IPreferenceStore#firePropertyChangeEvent(String, Object, Object)
+        */
+       public void firePropertyChangeEvent(String name, Object oldValue,
+                       Object newValue) {
+               fStore.firePropertyChangeEvent(name, oldValue, newValue);
+       }
+
+       /*
+        * @see IPreferenceStore#contains(String)
+        */
+       public boolean contains(String name) {
+               return fStore.contains(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getBoolean(String)
+        */
+       public boolean getBoolean(String name) {
+               return fStore.getBoolean(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultBoolean(String)
+        */
+       public boolean getDefaultBoolean(String name) {
+               return fStore.getDefaultBoolean(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultDouble(String)
+        */
+       public double getDefaultDouble(String name) {
+               return fStore.getDefaultDouble(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultFloat(String)
+        */
+       public float getDefaultFloat(String name) {
+               return fStore.getDefaultFloat(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultInt(String)
+        */
+       public int getDefaultInt(String name) {
+               return fStore.getDefaultInt(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultLong(String)
+        */
+       public long getDefaultLong(String name) {
+               return fStore.getDefaultLong(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDefaultString(String)
+        */
+       public String getDefaultString(String name) {
+               return fStore.getDefaultString(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getDouble(String)
+        */
+       public double getDouble(String name) {
+               return fStore.getDouble(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getFloat(String)
+        */
+       public float getFloat(String name) {
+               return fStore.getFloat(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getInt(String)
+        */
+       public int getInt(String name) {
+               return fStore.getInt(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getLong(String)
+        */
+       public long getLong(String name) {
+               return fStore.getLong(name);
+       }
+
+       /*
+        * @see IPreferenceStore#getString(String)
+        */
+       public String getString(String name) {
+               return fStore.getString(name);
+       }
+
+       /*
+        * @see IPreferenceStore#isDefault(String)
+        */
+       public boolean isDefault(String name) {
+               return fStore.isDefault(name);
+       }
+
+       /*
+        * @see IPreferenceStore#needsSaving()
+        */
+       public boolean needsSaving() {
+               return fStore.needsSaving();
+       }
+
+       /*
+        * @see IPreferenceStore#putValue(String, String)
+        */
+       public void putValue(String name, String value) {
+               if (covers(name))
+                       fStore.putValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, double)
+        */
+       public void setDefault(String name, double value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, float)
+        */
+       public void setDefault(String name, float value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, int)
+        */
+       public void setDefault(String name, int value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, long)
+        */
+       public void setDefault(String name, long value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, String)
+        */
+       public void setDefault(String name, String value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setDefault(String, boolean)
+        */
+       public void setDefault(String name, boolean value) {
+               if (covers(name))
+                       fStore.setDefault(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setToDefault(String)
+        */
+       public void setToDefault(String name) {
+               fStore.setToDefault(name);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, double)
+        */
+       public void setValue(String name, double value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, float)
+        */
+       public void setValue(String name, float value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, int)
+        */
+       public void setValue(String name, int value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, long)
+        */
+       public void setValue(String name, long value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, String)
+        */
+       public void setValue(String name, String value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+
+       /*
+        * @see IPreferenceStore#setValue(String, boolean)
+        */
+       public void setValue(String name, boolean value) {
+               if (covers(name))
+                       fStore.setValue(name, value);
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPPreferencesMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPPreferencesMessages.java
new file mode 100644 (file)
index 0000000..1c60d30
--- /dev/null
@@ -0,0 +1,42 @@
+package net.sourceforge.phpeclipse.preferences;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class PHPPreferencesMessages {
+
+       private static final String RESOURCE_BUNDLE = PHPPreferencesMessages.class
+                       .getName();
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private PHPPreferencesMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key
+        *            the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPPreferencesMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPPreferencesMessages.properties
new file mode 100644 (file)
index 0000000..6d1f225
--- /dev/null
@@ -0,0 +1,94 @@
+#########################################
+# PHPProjectLibraryPage 
+#########################################
+
+PHPProjectLibraryPage.elementNotIProject=ERROR: Element not IProject
+PHPProjectLibraryPage.project=Project
+PHPProjectLibraryPage.tabName=Projects
+
+
+#########################################
+# Property Pages
+#########################################
+
+PHPProjectPropertyPage.phpProjectClosed=The project selected is a PHP project, but is closed.
+PHPProjectPropertyPage.performOkExceptionDialogTitle=Unable to save
+PHPProjectPropertyPage.performOkExceptionDialogMessage=ERROR: Unable to save project properties.
+
+PHPMiscProjectPreferences.localhost=Localhost
+PHPMiscProjectPreferences.documentroot=DocumentRoot
+PHPMiscProjectPreferences.bookmark=SQL default bookmark:
+
+PHPMiscProjectPreferences.obfuscator=Obfuscator directory:
+
+PHPPreviewProjectPreferences.auto_preview=Refresh PHP browser view when opening editor
+PHPPreviewProjectPreferences.bring_to_top_preview=Show PHP browser view when opening editor
+PHPPreviewProjectPreferences.show_html_files_local=Show HTML files as local resources (no 'http://' url)
+
+#########################################
+# Preference Pages
+#########################################
+PHPBasePreferencePage.description=PHP Preferences
+PHPBasePreferencePage.websettingsGroup=Webserver Settings
+PHPBasePreferencePage.websettingsGroup.localhost=Localhost
+PHPBasePreferencePage.websettingsGroup.docroot=DocumentRoot
+PHPBasePreferencePage.websettingsGroup.browser=External browser command
+PHPBasePreferencePage.websettingsGroup.useexternal=Use external browser
+#PHPBasePreferencePage.websettingsGroup.showexternalpreview=Show preview on editor load (win32 only)
+PHPBasePreferencePage.apacheGroup=Apache Settings
+PHPBasePreferencePage.apacheGroup.xampp_start=XAMPP Start
+PHPBasePreferencePage.apacheGroup.xampp_stop=XAMPP Stop
+PHPBasePreferencePage.apacheGroup.run=Apache
+PHPBasePreferencePage.apacheGroup.httpdconf=httpd.conf
+PHPBasePreferencePage.apacheGroup.etchosts=etc/hosts
+PHPBasePreferencePage.apacheGroup.start=Start Apache
+PHPBasePreferencePage.apacheGroup.start_background=Run in background mode
+PHPBasePreferencePage.apacheGroup.stop=Stop Apache
+PHPBasePreferencePage.apacheGroup.stop_background=Run in background mode
+PHPBasePreferencePage.apacheGroup.restart=Restart Apache
+PHPBasePreferencePage.apacheGroup.restart_background=Run in background mode
+PHPBasePreferencePage.console.php=Run PHP command
+PHPBasePreferencePage.mySQLGroup=MySQL Settings
+PHPBasePreferencePage.mySQLGroup.run=MySQL
+PHPBasePreferencePage.mySQLGroup.start_background=Run in background mode
+PHPBasePreferencePage.mySQLGroup.command=Start MySQL
+PHPBasePreferencePage.parsers=Parsing settings
+PHPBasePreferencePage.parsers.pos=Parse on save
+PHPBasePreferencePage.parsers.external=External
+PHPBasePreferencePage.parsers.internal=Internal
+PHPBasePreferencePage.parsers.extcommand=Parser command
+PHPBasePreferencePage.parsers.choose=Choose PHP Parser
+PHPBasePreferencePage.phpExtensionPrefs=PHP file extensions (internal Parser)
+
+PHPEditorSyntaxPreferencePage.description:PHP Editor Preferences
+PHPEditorSyntaxPreferencePage.background:Background settings
+PHPEditorSyntaxPreferencePage.foreground:Foreground settings
+PHPEditorSyntaxPreferencePage.syntax:Syntax highlighting
+PHPEditorSyntaxPreferencePage.color:Colour
+PHPEditorSyntaxPreferencePage.bold:Bold
+PHPEditorSyntaxPreferencePage.italic:Italic
+PHPEditorSyntaxPreferencePage.underline:Underline
+PHPEditorSyntaxPreferencePage.multiLineComment=Multi-line comment
+PHPEditorSyntaxPreferencePage.singleLineComment=Single-line comment
+PHPEditorSyntaxPreferencePage.tags=PHP Tags
+PHPEditorSyntaxPreferencePage.keywords=Keywords
+PHPEditorSyntaxPreferencePage.variables='$' Variables
+PHPEditorSyntaxPreferencePage.variables_dollar='$_' Variables
+PHPEditorSyntaxPreferencePage.types=Types
+PHPEditorSyntaxPreferencePage.functions=Functions
+PHPEditorSyntaxPreferencePage.constants=Constants
+PHPEditorSyntaxPreferencePage.strings_dq=Double Quoted Strings
+PHPEditorSyntaxPreferencePage.strings_sq=Single Quoted Strings
+PHPEditorSyntaxPreferencePage.others=Others
+PHPEditorSyntaxPreferencePage.syntaxdialog=Custom PHP Syntax File:
+PHPEditorSyntaxPreferencePage.browse=Browse..
+PHPEditorSyntaxPreferencePage.textfont=Text font
+
+PHPLanguagePreferencePage.description=PHP Editor Language
+PHPLanguagePreferencePage.preflingo=PHP Language Preference
+PHPLanguagePreferencePage.choose=Choose Language
+PHPLanguagePreferencePage.english=English
+PHPLanguagePreferencePage.german=German
+PHPLanguagePreferencePage.french=French
+PHPLanguagePreferencePage.spanish=Spanish
+PHPLanguagePreferencePage.japanese=Japanese
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPProjectLibraryPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPProjectLibraryPage.java
new file mode 100644 (file)
index 0000000..9922f48
--- /dev/null
@@ -0,0 +1,165 @@
+package net.sourceforge.phpeclipse.preferences;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.core.JavaProject;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.ide.IDE.SharedImages;
+
+public class PHPProjectLibraryPage {
+       protected JavaProject workingProject;
+
+       protected PHPProjectLibraryPage(JavaProject theWorkingProject) {
+               super();
+               workingProject = theWorkingProject;
+       }
+
+       protected Control getControl(Composite parent) {
+               Composite composite = new Composite(parent, SWT.NONE);
+               composite.setLayout(new FillLayout());
+
+               Table projectsTable = new Table(composite, SWT.CHECK | SWT.BORDER
+                               | SWT.MULTI | SWT.FULL_SELECTION);
+               projectsTable.setHeaderVisible(false);
+               projectsTable.setLinesVisible(false);
+               projectsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+               TableColumn tableColumn = new TableColumn(projectsTable, SWT.NONE);
+               tableColumn.setWidth(200);
+               tableColumn.setText(PHPPreferencesMessages
+                               .getString("PHPEditorPreferencePageLibraryPage.project")); //$NON-NLS-1$
+
+               CheckboxTableViewer projectsTableViewer = new CheckboxTableViewer(
+                               projectsTable);
+               projectsTableViewer.addCheckStateListener(new ICheckStateListener() {
+                       public void checkStateChanged(CheckStateChangedEvent event) {
+                               projectCheckedUnchecked(event);
+                       }
+               });
+
+               projectsTableViewer.setContentProvider(getContentProvider());
+               projectsTableViewer.setLabelProvider(getLabelProvider());
+
+               projectsTableViewer.setInput(getWorkspaceProjects());
+               projectsTableViewer.setCheckedElements(workingProject
+                               .getReferencedProjects().toArray());
+
+               return composite;
+       }
+
+       protected void projectCheckedUnchecked(CheckStateChangedEvent event) {
+               IProject checkEventProject = (IProject) event.getElement();
+               if (event.getChecked())
+                       getWorkingProject().addLoadPathEntry(checkEventProject);
+               else
+                       getWorkingProject().removeLoadPathEntry(checkEventProject);
+       }
+
+       protected JavaProject getWorkingProject() {
+               return workingProject;
+       }
+
+       protected List getWorkspaceProjects() {
+               IWorkspaceRoot root = PHPeclipsePlugin.getWorkspace().getRoot();
+               return Arrays.asList(root.getProjects());
+       }
+
+       protected ITableLabelProvider getLabelProvider() {
+               ITableLabelProvider labelProvider = new ITableLabelProvider() {
+                       public Image getColumnImage(Object element, int columnIndex) {
+                               IWorkbench workbench = WebUI.getDefault()
+                                               .getWorkbench();
+                               return workbench.getSharedImages().getImage(
+                                               SharedImages.IMG_OBJ_PROJECT);
+                       }
+
+                       public String getColumnText(Object element, int columnIndex) {
+                               if (element instanceof IProject)
+                                       return ((IProject) element).getName();
+
+                               return PHPPreferencesMessages
+                                               .getString("PHPEditorPreferencePageLibraryPage.elementNotIProject"); //$NON-NLS-1$
+                       }
+
+                       public void addListener(ILabelProviderListener listener) {
+                       }
+
+                       public void dispose() {
+                       }
+
+                       public boolean isLabelProperty(Object element, String property) {
+                               return false;
+                       }
+
+                       public void removeListener(ILabelProviderListener listener) {
+                       }
+               };
+
+               return labelProvider;
+       }
+
+       protected IContentProvider getContentProvider() {
+               IStructuredContentProvider contentProvider = new IStructuredContentProvider() {
+                       protected List PHPEditorPreferencePages;
+
+                       public Object[] getElements(Object inputElement) {
+                               return PHPEditorPreferencePages.toArray();
+                       }
+
+                       public void dispose() {
+                       }
+
+                       public void inputChanged(Viewer viewer, Object oldInput,
+                                       Object newInput) {
+                               PHPEditorPreferencePages = new ArrayList();
+
+                               if (!(newInput instanceof List))
+                                       return;
+
+                               Iterator workspaceProjectsIterator = ((List) newInput)
+                                               .iterator();
+                               while (workspaceProjectsIterator.hasNext()) {
+                                       Object anObject = workspaceProjectsIterator.next();
+                                       if (anObject instanceof IProject) {
+                                               IProject project = (IProject) anObject;
+                                               if (project.getName() != workingProject.getProject()
+                                                               .getName()) {
+                                                       try {
+                                                               if (project
+                                                                               .hasNature(PHPeclipsePlugin.PHP_NATURE_ID))
+                                                                       PHPEditorPreferencePages.add(project);
+                                                       } catch (CoreException e) {
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               };
+
+               return contentProvider;
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPProjectPropertyPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/preferences/PHPProjectPropertyPage.java
new file mode 100644 (file)
index 0000000..2f3ba51
--- /dev/null
@@ -0,0 +1,102 @@
+package net.sourceforge.phpeclipse.preferences;
+
+import net.sourceforge.phpdt.internal.core.JavaProject;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.IWorkbenchPropertyPage;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+public class PHPProjectPropertyPage extends PropertyPage implements
+               IWorkbenchPropertyPage {
+       protected PHPProjectLibraryPage projectsPage;
+
+       protected JavaProject workingProject;
+
+       public PHPProjectPropertyPage() {
+       }
+
+       protected Control createContents(Composite parent) {
+               noDefaultAndApplyButton();
+
+               workingProject = getPHPProject();
+               if (workingProject == null || !workingProject.getProject().isOpen())
+                       return createClosedProjectPageContents(parent);
+
+               return createProjectPageContents(parent);
+       }
+
+       protected JavaProject getPHPProject() {
+               IAdaptable selectedElement = getElement();
+               if (selectedElement == null)
+                       return null;
+
+               if (selectedElement instanceof JavaProject)
+                       return (JavaProject) selectedElement;
+
+               if (selectedElement instanceof IProject) {
+                       IProject simpleProject = (IProject) selectedElement;
+                       try {
+                               if (simpleProject.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
+                                       JavaProject phpProject = new JavaProject();
+                                       phpProject.setProject(simpleProject);
+                                       return phpProject;
+                               }
+                       } catch (CoreException e) {
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+
+               return null;
+       }
+
+       protected Control createClosedProjectPageContents(Composite parent) {
+               Label label = new Label(parent, SWT.NONE);
+               label.setText(PHPPreferencesMessages
+                               .getString("PHPProjectPropertyPage.phpProjectClosed")); //$NON-NLS-1$
+
+               return label;
+       }
+
+       protected Control createProjectPageContents(Composite parent) {
+               TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+               tabFolder.setLayout(new GridLayout());
+               tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));
+               tabFolder.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               // tabChanged(e.item);
+                       }
+               });
+
+               projectsPage = new PHPProjectLibraryPage(workingProject);
+               TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
+               tabItem.setText(PHPPreferencesMessages
+                               .getString("PHPProjectLibraryPage.tabName")); //$NON-NLS-1$
+               // tabItem.setData(projectsPage);
+               tabItem.setControl(projectsPage.getControl(tabFolder));
+
+               return tabFolder;
+       }
+
+       public boolean performOk() {
+               try {
+                       projectsPage.getWorkingProject().save();
+               } catch (CoreException e) {
+                       PHPeclipsePlugin.log(e);
+               }
+               return super.performOk();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/HTMLFileWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/HTMLFileWizard.java
new file mode 100644 (file)
index 0000000..b4f5554
--- /dev/null
@@ -0,0 +1,194 @@
+package net.sourceforge.phpeclipse.wizards;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+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.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWizard;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+
+/**
+ * This wizard creates one file with the extension "html".
+ */
+public class HTMLFileWizard extends Wizard implements INewWizard {
+
+       private HTMLFileWizardPage page;
+
+       private ISelection selection;
+
+       public HTMLFileWizard() {
+               super();
+               setNeedsProgressMonitor(true);
+               setWindowTitle(PHPWizardMessages
+                               .getString("WizardNewProjectCreationPage.html.windowTitle"));
+       }
+
+       /**
+        * Adding the page to the wizard.
+        */
+       public void addPages() {
+               page = new HTMLFileWizardPage(selection);
+               addPage(page);
+       }
+
+       /**
+        * This method is called when 'Finish' button is pressed in the wizard. We
+        * will create an operation and run it using wizard as execution context.
+        */
+       public boolean performFinish() {
+               final String containerName = page.getContainerName();
+               final String fileName = page.getFileName();
+               IRunnableWithProgress op = new IRunnableWithProgress() {
+                       public void run(IProgressMonitor monitor)
+                                       throws InvocationTargetException {
+                               try {
+                                       doFinish(containerName, fileName, monitor);
+                               } catch (CoreException e) {
+                                       throw new InvocationTargetException(e);
+                               } finally {
+                                       monitor.done();
+                               }
+                       }
+               };
+               try {
+                       getContainer().run(true, false, op);
+               } catch (InterruptedException e) {
+                       return false;
+               } catch (InvocationTargetException e) {
+                       Throwable realException = e.getTargetException();
+                       MessageDialog.openError(getShell(), PHPWizardMessages
+                                       .getString("Wizard.error"), realException.getMessage());
+                       return false;
+               }
+               return true;
+       }
+
+       /**
+        * The worker method. It will find the container, create the file if missing
+        * or just replace its contents, and open the editor on the newly created
+        * file.
+        */
+       private void doFinish(String containerName, String fileName,
+                       IProgressMonitor monitor) throws CoreException {
+               // create a sample file
+               monitor.beginTask(PHPWizardMessages
+                               .getString("Wizard.Monitor.creating")
+                               + " " + fileName, 2);
+               IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+               IResource resource = root.findMember(new Path(containerName));
+               if (!resource.exists() || !(resource instanceof IContainer)) {
+                       throwCoreException(PHPWizardMessages
+                                       .getString("Wizard.Monitor.containerDoesNotExistException"));
+               }
+               IContainer container = (IContainer) resource;
+               final IFile file = container.getFile(new Path(fileName));
+               IProject project = file.getProject();
+               String projectName = project.getName();
+               try {
+                       InputStream stream;
+                       stream = openContentStream(fileName, projectName);
+                       if (file.exists()) {
+                               file.setContents(stream, true, true, monitor);
+                       } else {
+                               file.create(stream, true, monitor);
+                       }
+                       stream.close();
+               } catch (IOException e) {
+               }
+               monitor.worked(1);
+               monitor.setTaskName(PHPWizardMessages
+                               .getString("Wizard.Monitor.openingFile"));
+               getShell().getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               IWorkbenchPage page = PlatformUI.getWorkbench()
+                                               .getActiveWorkbenchWindow().getActivePage();
+                               try {
+                                       IDE.openEditor(page, file, true);
+                               } catch (PartInitException e) {
+                               }
+                       }
+               });
+               monitor.worked(1);
+       }
+
+       /**
+        * We will initialize file contents with a sample text.
+        */
+       private InputStream openContentStream(String fileName, String projectname) {
+               try {
+                       Template template = WebUI.getDefault()
+                                       .getCodeTemplateStore().findTemplate(
+                                                       CodeTemplateContextType.NEWHTML);
+                       if (template == null) {
+                               return null;
+                       }
+                       String lineDelimiter = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+                       CodeTemplateContext context = new CodeTemplateContext(template
+                                       .getContextTypeId(), null, lineDelimiter);
+                       context.setFileNameVariable(fileName, projectname);
+                       return new ByteArrayInputStream(StubUtility.evaluateTemplate(
+                                       context, template).getBytes());
+               } catch (CoreException e) {
+                       e.printStackTrace();
+                       return null;
+               }
+       }
+
+       private void throwCoreException(String message) throws CoreException {
+               IStatus status = new Status(IStatus.ERROR,
+                               "net.sourceforge.phpeclipse.wizards", IStatus.OK, message, null);
+               throw new CoreException(status);
+       }
+
+       /**
+        * We will accept the selection in the workbench to see if we can initialize
+        * from it.
+        * 
+        * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
+        */
+       public void init(IWorkbench workbench, IStructuredSelection selection) {
+               this.selection = selection;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/HTMLFileWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/HTMLFileWizardPage.java
new file mode 100644 (file)
index 0000000..40f8127
--- /dev/null
@@ -0,0 +1,244 @@
+package net.sourceforge.phpeclipse.wizards;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.IDialogPage;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well
+ * as the file name. The page will only accept file name without the extension
+ * OR with the extension that matches the expected one (cs).
+ */
+
+public class HTMLFileWizardPage extends WizardPage {
+       private static final String INITIAL_FILENAME = "file.html";
+
+       private Text containerText;
+
+       private Text fileText;
+
+       private ISelection selection;
+
+       /**
+        * Constructor for SampleNewWizardPage.
+        * 
+        * @param pageName
+        */
+       public HTMLFileWizardPage(ISelection selection) {
+               super("wizardPage");
+               setTitle(PHPWizardMessages.getString("WizardPage.html.title"));
+               setDescription(PHPWizardMessages
+                               .getString("WizardPage.html.description"));
+               this.selection = selection;
+       }
+
+       /**
+        * @see IDialogPage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               Composite container = new Composite(parent, SWT.NULL);
+               GridLayout layout = new GridLayout();
+               container.setLayout(layout);
+               layout.numColumns = 3;
+               layout.verticalSpacing = 9;
+               Label label = new Label(container, SWT.NULL);
+               label.setText(PHPWizardMessages.getString("WizardPage.containerLabel"));
+
+               containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
+               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+               containerText.setLayoutData(gd);
+               containerText.addModifyListener(new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               dialogChanged();
+                       }
+               });
+
+               Button button = new Button(container, SWT.PUSH);
+               button.setText(PHPWizardMessages
+                               .getString("WizardPage.browseButtonText"));
+               button.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               handleBrowse();
+                       }
+               });
+               label = new Label(container, SWT.NULL);
+               label.setText(PHPWizardMessages.getString("WizardPage.fileLabel"));
+
+               fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               fileText.setLayoutData(gd);
+               fileText.addModifyListener(new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               dialogChanged();
+                       }
+               });
+               initialize();
+               dialogChanged();
+               setControl(container);
+       }
+
+       /**
+        * Tests if the current workbench selection is a suitable container to use.
+        */
+
+       private void initialize() {
+               if (selection != null && selection.isEmpty() == false
+                               && selection instanceof IStructuredSelection) {
+                       IStructuredSelection ssel = (IStructuredSelection) selection;
+                       if (ssel.size() > 1)
+                               return;
+                       Object obj = ssel.getFirstElement();
+                       if (obj instanceof IResource) {
+                               IContainer container;
+                               if (obj instanceof IContainer)
+                                       container = (IContainer) obj;
+                               else
+                                       container = ((IResource) obj).getParent();
+                               containerText.setText(container.getFullPath().toString());
+                               fileText.setFocus();
+                       }
+               }
+               fileText.setText(INITIAL_FILENAME);
+       }
+
+       /**
+        * Uses the standard container selection dialog to choose the new value for
+        * the container field.
+        */
+
+       private void handleBrowse() {
+               ContainerSelectionDialog dialog = new ContainerSelectionDialog(
+                               getShell(), ResourcesPlugin.getWorkspace().getRoot(), false,
+                               PHPWizardMessages
+                                               .getString("WizardPage.selectNewFileContainer"));
+               if (dialog.open() == ContainerSelectionDialog.OK) {
+                       Object[] result = dialog.getResult();
+                       if (result.length == 1) {
+                               IContainer container = (IContainer) result[0];
+                               containerText.setText(container.getFullPath().toString());
+                       }
+               }
+       }
+
+       /**
+        * Ensures that both text fields are set.
+        */
+       private void dialogChanged() {
+               String container = getContainerName();
+               String fileName = getFileName();
+
+               if (container.length() == 0) {
+                       updateStatus(PHPWizardMessages
+                                       .getString("WizardPage.containerMustBeSpecified"));
+                       return;
+               }
+               if (fileName.length() == 0) {
+                       updateStatus("WizardPage.nameMustBeSpecified");
+                       return;
+               }
+
+               updateStatus(null);
+       }
+
+       private void updateStatus(String message) {
+               setErrorMessage(message);
+               setPageComplete(message == null);
+       }
+
+       public String getContainerName() {
+               return containerText.getText();
+       }
+
+       public String getFileName() {
+               return fileText.getText();
+       }
+
+       /**
+        * @see WizardPage#isPageComplete()
+        */
+       public boolean isPageComplete() {
+               return !checkFolderForExistingFile() && super.isPageComplete();
+       }
+
+       /**
+        * Finds the current directory where the file should be created
+        */
+       protected boolean checkFolderForExistingFile() {
+               IContainer container = getFileContainer();
+               if (container != null) {
+                       IResource file = container.getFile(new Path(fileText.getText()
+                                       .trim()));
+                       if (file != null && file.exists()) {
+                               this.setErrorMessage(PHPWizardMessages
+                                               .getString("WizardPage.fileAlreadyExists"));
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       private IContainer getFileContainer() {
+               if (containerText.getText() != null) {
+                       IPath containerPath = new Path(containerText.getText().trim());
+                       IContainer container;
+                       if (containerPath.segmentCount() > 1) {
+                               container = ResourcesPlugin.getWorkspace().getRoot().getFolder(
+                                               containerPath);
+                       } else {
+                               // this is a project
+                               container = ResourcesPlugin.getWorkspace().getRoot()
+                                               .getProject(containerText.getText().trim());
+                       }
+                       if (container != null && container.exists()) {
+                               return container;
+                       }
+               }
+               return null;
+       }
+
+       public void setVisible(boolean visible) {
+               super.setVisible(visible);
+               if (visible) {
+                       String fileName = fileText.getText().trim();
+                       if (getFileContainer() != null
+                                       && fileName.equalsIgnoreCase(INITIAL_FILENAME)) {
+                               fileText.setFocus();
+                               fileText.setText(fileName);
+                               fileText.setSelection(0, fileName.length()
+                                               - (new Path(INITIAL_FILENAME)).getFileExtension()
+                                                               .length() - 1);
+                       }
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/NewProjectCreationWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/NewProjectCreationWizard.java
new file mode 100644 (file)
index 0000000..28ce603
--- /dev/null
@@ -0,0 +1,122 @@
+package net.sourceforge.phpeclipse.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.ui.actions.OpenPHPPerspectiveAction;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation;
+import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
+import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
+import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
+
+public class NewProjectCreationWizard extends BasicNewResourceWizard implements
+               INewWizard, IExecutableExtension {
+       protected WizardNewProjectCreationPage projectPage;
+
+       protected IConfigurationElement configurationElement;
+
+       protected IProject newProject;
+
+       public NewProjectCreationWizard() {
+               setWindowTitle(PHPWizardMessages
+                               .getString("NewProjectCreationWizard.windowTitle"));
+       }
+
+       public boolean performFinish() {
+               IRunnableWithProgress projectCreationOperation = new WorkspaceModifyDelegatingOperation(
+                               getProjectCreationRunnable());
+
+               try {
+                       getContainer().run(false, true, projectCreationOperation);
+               } catch (Exception e) {
+                       PHPeclipsePlugin.log(e);
+                       return false;
+               }
+
+               BasicNewProjectResourceWizard.updatePerspective(configurationElement);
+               selectAndReveal(newProject);
+               // open the PHP perspective
+               new OpenPHPPerspectiveAction().run();
+               return true;
+       }
+
+       protected IRunnableWithProgress getProjectCreationRunnable() {
+               return new IRunnableWithProgress() {
+                       public void run(IProgressMonitor monitor)
+                                       throws InvocationTargetException, InterruptedException {
+                               int remainingWorkUnits = 10;
+                               monitor
+                                               .beginTask(
+                                                               PHPWizardMessages
+                                                                               .getString("NewProjectCreationWizard.projectCreationMessage"),
+                                                               remainingWorkUnits);
+
+                               IWorkspace workspace = PHPeclipsePlugin.getWorkspace();
+                               String projectName = projectPage.getProjectHandle().getName();
+                               newProject = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+                               IProjectDescription description = workspace
+                                               .newProjectDescription(projectName);
+                               
+                               URI uriPath = (!projectPage.useDefaults()) ? projectPage
+                               .getLocationURI() : null;
+                               if (uriPath != null) {                              
+                                       description.setLocationURI(uriPath);
+                               }
+
+                               try {
+                                       if (!newProject.exists()) {
+                                               newProject.create(description, new SubProgressMonitor(
+                                                               monitor, 1));
+                                               remainingWorkUnits--;
+                                       }
+                                       if (!newProject.isOpen()) {
+                                           newProject.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1));
+                                               remainingWorkUnits--;
+                                       }
+                                       JavaCore.addPHPNature(newProject, new SubProgressMonitor(
+                                                       monitor, remainingWorkUnits));
+
+                               } catch (CoreException e) {
+                                   System.out.println(e);
+                                       throw new InvocationTargetException(e);
+                               } finally {
+                                       monitor.done();
+                               }
+                       }
+               };
+       }
+
+       public void addPages() {
+               super.addPages();
+
+               projectPage = new WizardNewProjectCreationPage(PHPWizardMessages
+                               .getString("WizardNewProjectCreationPage.pageName"));
+               projectPage.setTitle(PHPWizardMessages
+                               .getString("WizardNewProjectCreationPage.pageTitle"));
+               projectPage.setDescription(PHPWizardMessages
+                               .getString("WizardNewProjectCreationPage.pageDescription"));
+
+               addPage(projectPage);
+       }
+
+       public void setInitializationData(IConfigurationElement config,
+                       String propertyName, Object data) throws CoreException {
+               configurationElement = config;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPFileWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPFileWizard.java
new file mode 100644 (file)
index 0000000..f0306af
--- /dev/null
@@ -0,0 +1,242 @@
+package net.sourceforge.phpeclipse.wizards;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.WebUI;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+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.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWizard;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+
+/**
+ * This wizard creates one file with the extension "php".
+ */
+public class PHPFileWizard extends Wizard implements INewWizard {
+
+       private PHPFileWizardPage page;
+
+       private ISelection selection;
+
+       public PHPFileWizard() {
+               super();
+               setNeedsProgressMonitor(true);
+               setWindowTitle(PHPWizardMessages
+                               .getString("WizardNewProjectCreationPage.windowTitle"));
+       }
+
+       /**
+        * Adding the page to the wizard.
+        */
+       public void addPages() {
+               page = new PHPFileWizardPage(selection);
+               addPage(page);
+       }
+
+       /**
+        * This method is called when 'Finish' button is pressed in the wizard. We
+        * will create an operation and run it using wizard as execution context.
+        */
+       public boolean performFinish() {
+               final String containerName = page.getContainerName();
+               final String fileName = page.getFileName();
+               IRunnableWithProgress op = new IRunnableWithProgress() {
+                       public void run(IProgressMonitor monitor)
+                                       throws InvocationTargetException {
+                               try {
+                                       doFinish(containerName, fileName, monitor);
+                               } catch (CoreException e) {
+                                       throw new InvocationTargetException(e);
+                               } finally {
+                                       monitor.done();
+                               }
+                       }
+               };
+               try {
+                       getContainer().run(true, false, op);
+               } catch (InterruptedException e) {
+                       return false;
+               } catch (InvocationTargetException e) {
+                       Throwable realException = e.getTargetException();
+                       MessageDialog.openError(getShell(), PHPWizardMessages
+                                       .getString("Wizard.error"), realException.getMessage());
+                       return false;
+               }
+               return true;
+       }
+
+       /**
+        * The worker method. It will find the container, create the file if missing
+        * or just replace its contents, and open the editor on the newly created
+        * file.
+        */
+       private void doFinish(String containerName, String fileName,
+                       IProgressMonitor monitor) throws CoreException {
+               // create a sample file
+               monitor.beginTask(PHPWizardMessages
+                               .getString("Wizard.Monitor.creating")
+                               + " " + fileName, 2);
+               IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+               IResource resource = root.findMember(new Path(containerName));
+               if (!resource.exists() || !(resource instanceof IContainer)) {
+                       throwCoreException(PHPWizardMessages
+                                       .getString("Wizard.Monitor.containerDoesNotExistException"));
+               }
+               IContainer container = (IContainer) resource;
+               final IFile file = container.getFile(new Path(fileName));
+               IProject project = file.getProject();
+               String projectName = project.getName();
+               String className = getClassName(fileName);
+
+               try {
+                       InputStream stream;
+                       if (className == null) {
+                               stream = openContentStream(fileName, projectName);
+                       } else {
+                               stream = openContentStreamClass(className);
+                       }
+                       if (file.exists()) {
+                               file.setContents(stream, true, true, monitor);
+                       } else {
+                               file.create(stream, true, monitor);
+                       }
+                       stream.close();
+               } catch (IOException e) {
+               }
+               monitor.worked(1);
+               monitor.setTaskName(PHPWizardMessages
+                               .getString("Wizard.Monitor.openingFile"));
+               getShell().getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               IWorkbenchPage page = PlatformUI.getWorkbench()
+                                               .getActiveWorkbenchWindow().getActivePage();
+                               try {
+                                       IDE.openEditor(page, file, true);
+                               } catch (PartInitException e) {
+                               }
+                       }
+               });
+               monitor.worked(1);
+       }
+
+       /**
+        * Check if the filename is like this anyname.class.php
+        * 
+        * @param fFileName
+        *            the filename
+        * @return the anyname or null
+        */
+       private static final String getClassName(final String fileName) {
+               final int lastDot = fileName.lastIndexOf('.');
+               if (lastDot == -1)
+                       return null;
+               final int precLastDot = fileName.lastIndexOf('.', lastDot - 1);
+               if (precLastDot == -1)
+                       return null;
+               if (!fileName.substring(precLastDot + 1, lastDot).toUpperCase().equals(
+                               "CLASS"))
+                       return null;
+               return fileName.substring(0, precLastDot);
+       }
+
+       /**
+        * We will initialize file contents for a class
+        * 
+        * @param className
+        *            the classname
+        */
+       private InputStream openContentStreamClass(final String className) {
+               StringBuffer contents = new StringBuffer("<?php\n\n");
+               contents.append("class ");
+               contents.append(className);
+               contents.append(" {\n\n");
+               contents.append("    function ");
+               contents.append(className);
+               contents.append("() {\n");
+               contents.append("    }\n}\n?>");
+               return new ByteArrayInputStream(contents.toString().getBytes());
+       }
+
+       /**
+        * We will initialize file contents with a sample text.
+        */
+       private InputStream openContentStream(String fileName, String projectname) {
+               try {
+                       Template template = WebUI.getDefault()
+                                       .getCodeTemplateStore().findTemplate(
+                                                       CodeTemplateContextType.NEWTYPE);
+                       if (template == null) {
+                               return null;
+                       }
+                       String lineDelimiter = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+                       CodeTemplateContext context = new CodeTemplateContext(template
+                                       .getContextTypeId(), null, lineDelimiter);
+                       context.setFileNameVariable(fileName, projectname);
+                       String content = StubUtility.evaluateTemplate(context, template);
+                       if (content == null) {
+                               content = "";
+                       }
+                       return new ByteArrayInputStream(content.getBytes());
+               } catch (CoreException e) {
+                       e.printStackTrace();
+                       return null;
+               }
+
+       }
+
+       private void throwCoreException(String message) throws CoreException {
+               IStatus status = new Status(IStatus.ERROR,
+                               "net.sourceforge.phpeclipse.wizards", IStatus.OK, message, null);
+               throw new CoreException(status);
+       }
+
+       /**
+        * We will accept the selection in the workbench to see if we can initialize
+        * from it.
+        * 
+        * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
+        */
+       public void init(IWorkbench workbench, IStructuredSelection selection) {
+               this.selection = selection;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPFileWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPFileWizardPage.java
new file mode 100644 (file)
index 0000000..f4ac33a
--- /dev/null
@@ -0,0 +1,248 @@
+package net.sourceforge.phpeclipse.wizards;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.IDialogPage;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well
+ * as the file name. The page will only accept file name without the extension
+ * OR with the extension that matches the expected one (cs).
+ */
+
+public class PHPFileWizardPage extends WizardPage {
+       private static final String INITIAL_FILENAME = "file.php";
+
+       private Text containerText;
+
+       private Text fileText;
+
+       private ISelection selection;
+
+       /**
+        * Constructor for SampleNewWizardPage.
+        * 
+        * @param pageName
+        */
+       public PHPFileWizardPage(ISelection selection) {
+               super("wizardPage");
+               setTitle(PHPWizardMessages.getString("WizardPage.title"));
+               setDescription(PHPWizardMessages.getString("WizardPage.description"));
+               this.selection = selection;
+       }
+
+       /**
+        * @see IDialogPage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               Composite container = new Composite(parent, SWT.NULL);
+               GridLayout layout = new GridLayout();
+               container.setLayout(layout);
+               layout.numColumns = 3;
+               layout.verticalSpacing = 9;
+               Label label = new Label(container, SWT.NULL);
+               label.setText(PHPWizardMessages.getString("WizardPage.containerLabel"));
+
+               containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
+               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+               containerText.setLayoutData(gd);
+               containerText.addModifyListener(new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               dialogChanged();
+                       }
+               });
+
+               Button button = new Button(container, SWT.PUSH);
+               button.setText(PHPWizardMessages
+                               .getString("WizardPage.browseButtonText"));
+               button.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               handleBrowse();
+                       }
+               });
+               label = new Label(container, SWT.NULL);
+               label.setText(PHPWizardMessages.getString("WizardPage.fileLabel"));
+
+               fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               fileText.setLayoutData(gd);
+               fileText.addModifyListener(new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               dialogChanged();
+                       }
+               });
+               initialize();
+               dialogChanged();
+               setControl(container);
+       }
+
+       /**
+        * Tests if the current workbench selection is a suitable container to use.
+        */
+
+       private void initialize() {
+               if (selection != null && selection.isEmpty() == false
+                               && selection instanceof IStructuredSelection) {
+                       IStructuredSelection ssel = (IStructuredSelection) selection;
+                       if (ssel.size() > 1)
+                               return;
+                       Object obj = ssel.getFirstElement();
+                       if (obj instanceof IResource) {
+                               IContainer container;
+                               if (obj instanceof IContainer)
+                                       container = (IContainer) obj;
+                               else
+                                       container = ((IResource) obj).getParent();
+                               containerText.setText(container.getFullPath().toString());
+                               fileText.setFocus();
+                       }
+               }
+               fileText.setText(INITIAL_FILENAME);
+       }
+
+       /**
+        * Uses the standard container selection dialog to choose the new value for
+        * the container field.
+        */
+
+       private void handleBrowse() {
+               ContainerSelectionDialog dialog = new ContainerSelectionDialog(
+                               getShell(), ResourcesPlugin.getWorkspace().getRoot(), false,
+                               PHPWizardMessages
+                                               .getString("WizardPage.selectNewFileContainer"));
+               if (dialog.open() == ContainerSelectionDialog.OK) {
+                       Object[] results = dialog.getResult();
+                       if (results.length == 1) {
+                               Object result = results[0];
+                               if (result instanceof IPath) {
+                                       IPath ipath = (IPath) result;
+                                       containerText.setText(ipath.toString());
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Ensures that both text fields are set.
+        */
+       private void dialogChanged() {
+               String container = getContainerName();
+               String fileName = getFileName();
+
+               if (container.length() == 0) {
+                       updateStatus(PHPWizardMessages
+                                       .getString("WizardPage.containerMustBeSpecified"));
+                       return;
+               }
+               if (fileName.length() == 0) {
+                       updateStatus("WizardPage.nameMustBeSpecified");
+                       return;
+               }
+
+               updateStatus(null);
+       }
+
+       private void updateStatus(String message) {
+               setErrorMessage(message);
+               setPageComplete(message == null);
+       }
+
+       public String getContainerName() {
+               return containerText.getText();
+       }
+
+       public String getFileName() {
+               return fileText.getText();
+       }
+
+       /**
+        * @see WizardPage#isPageComplete()
+        */
+       public boolean isPageComplete() {
+               return !checkFolderForExistingFile() && super.isPageComplete();
+       }
+
+       /**
+        * Finds the current directory where the file should be created
+        */
+       protected boolean checkFolderForExistingFile() {
+               IContainer container = getFileContainer();
+               if (container != null) {
+                       IResource file = container.getFile(new Path(fileText.getText()
+                                       .trim()));
+                       if (file != null && file.exists()) {
+                               this.setErrorMessage(PHPWizardMessages
+                                               .getString("WizardPage.fileAlreadyExists"));
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       private IContainer getFileContainer() {
+               if (containerText.getText() != null) {
+                       IPath containerPath = new Path(containerText.getText().trim());
+                       IContainer container = null;
+                       if (containerPath.segmentCount() > 1) {
+                               container = ResourcesPlugin.getWorkspace().getRoot().getFolder(
+                                               containerPath);
+                       } else {
+                               if (containerPath.segmentCount() == 1) {
+                                       // this is a project
+                                       container = ResourcesPlugin.getWorkspace().getRoot()
+                                                       .getProject(containerText.getText().trim());
+                               }
+                       }
+                       if (container != null && container.exists()) {
+                               return container;
+                       }
+               }
+               return null;
+       }
+
+       public void setVisible(boolean visible) {
+               super.setVisible(visible);
+               if (visible) {
+                       String fileName = fileText.getText().trim();
+                       if (getFileContainer() != null
+                                       && fileName.equalsIgnoreCase(INITIAL_FILENAME)) {
+                               fileText.setFocus();
+                               fileText.setText(fileName);
+                               fileText.setSelection(0, fileName.length()
+                                               - (new Path(INITIAL_FILENAME)).getFileExtension()
+                                                               .length() - 1);
+                       }
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPWizardMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPWizardMessages.java
new file mode 100644 (file)
index 0000000..a95f119
--- /dev/null
@@ -0,0 +1,36 @@
+package net.sourceforge.phpeclipse.wizards;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class PHPWizardMessages {
+
+       private static final String RESOURCE_BUNDLE = PHPWizardMessages.class
+                       .getName();//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private PHPWizardMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPWizardMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/PHPWizardMessages.properties
new file mode 100644 (file)
index 0000000..355c144
--- /dev/null
@@ -0,0 +1,34 @@
+###################################
+##
+##  PHP wizard strings
+##
+###################################
+
+WizardPage.title=PHP file
+WizardPage.description=This wizard creates a new PHP file.
+WizardPage.html.title=HTML file
+WizardPage.html.description=This wizard creates a new HTML file.
+WizardPage.containerLabel=&Container:
+WizardPage.fileLabel=&File name:
+WizardPage.browseButtonText=Browse...
+WizardPage.fileAlreadyExists=This name is already used by an existing file. Please choose another one.
+WizardPage.mustBePHP=File extension must be "php".
+WizardPage.nameMustBeSpecified=File name must be specified.
+WizardPage.containerMustBeSpecified=File container must be specified.
+WizardPage.selectNewFileContainer=Select new file container.
+
+
+
+Wizard.error=An error occured
+Wizard.Monitor.creating=Creating
+Wizard.Monitor.openingFile=Opening file for editing...
+Wizard.Monitor.containerDoesNotExistException=The given container does not exist.
+
+NewProjectCreationWizard.windowTitle=New PHP project
+NewProjectCreationWizard.projectCreationMessage=Creating new PHP Project
+
+WizardNewProjectCreationPage.windowTitle=New PHP file
+WizardNewProjectCreationPage.html.windowTitle=New HTML file
+WizardNewProjectCreationPage.pageName=Create PHP Project
+WizardNewProjectCreationPage.pageTitle=PHP Project
+WizardNewProjectCreationPage.pageDescription=Create a new PHP Project
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/TempnewPHPProject.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/TempnewPHPProject.java
new file mode 100644 (file)
index 0000000..05cace3
--- /dev/null
@@ -0,0 +1,103 @@
+package net.sourceforge.phpeclipse.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
+import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
+import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
+
+public class TempnewPHPProject extends BasicNewResourceWizard implements
+               INewWizard {
+       /*
+        * This class has been added to cvs to provide a project page that works
+        * correctly and doesn't freezde while i investigate the errors completely
+        */
+       private WizardNewProjectCreationPage phpProjPage;
+
+       private IConfigurationElement fConfigElement;
+
+       public TempnewPHPProject() {
+               setNeedsProgressMonitor(true);
+               setWindowTitle("New Project creation"); //$NON-NLS-1$
+
+       }
+
+       public void addPages() {
+               super.addPages();
+               phpProjPage = new WizardNewProjectCreationPage(
+                               "NewProjectCreationWizard"); //$NON-NLS-1$
+               phpProjPage.setTitle(PHPWizardMessages
+                               .getString("WizardNewProjectCreationPage.pageTitle")); //$NON-NLS-1$
+               phpProjPage.setDescription(PHPWizardMessages
+                               .getString("WizardNewProjectCreationPage.pageDescription")); //$NON-NLS-1$
+               addPage(phpProjPage);
+       }
+
+       public void setInitializationData(IConfigurationElement cfig,
+                       String propertyName, Object data) {
+               fConfigElement = cfig;
+       }
+
+       protected void initializeDefaultPageImageDescriptor() {
+               // not used yet
+       }
+
+       protected void finishPage() throws InterruptedException, CoreException {
+               createProject(phpProjPage.getProjectHandle(), phpProjPage
+                               .getLocationPath(), new NullProgressMonitor());
+               BasicNewProjectResourceWizard.updatePerspective(fConfigElement);
+               selectAndReveal(phpProjPage.getProjectHandle());
+       }
+
+       protected void handleFinishException(Shell shell,
+                       InvocationTargetException e) {
+               ExceptionHandler.handle(e, getShell(), "Error title", "Error message");
+       }
+
+       public boolean performFinish() {
+               try {
+                       finishPage();
+               } catch (InterruptedException e) {
+               } catch (CoreException e) {
+               }
+               return true;
+       }
+
+       public void createProject(IProject project, IPath locationPath,
+                       IProgressMonitor monitor) throws CoreException {
+               try {
+                       if (!project.exists()) {
+                               IProjectDescription desc = project.getWorkspace()
+                                               .newProjectDescription(project.getName());
+                               if (Platform.getLocation().equals(locationPath)) {
+                                       locationPath = null;
+                               }
+                               desc.setLocation(locationPath);
+                               project.create(desc, monitor);
+                               monitor = null;
+                       }
+                       if (!project.isOpen()) {
+                               project.open(monitor);
+                               monitor = null;
+                       }
+                       JavaCore.addPHPNature(project, new NullProgressMonitor());
+               } finally {
+                       if (monitor != null) {
+                               monitor.done();
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/EditElementWizard.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/EditElementWizard.java
new file mode 100644 (file)
index 0000000..c2be185
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * $Id: EditElementWizard.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * EditElementWizard. TODO: privides extension point element editor. pluggable
+ * element edit page.
+ */
+public class EditElementWizard extends Wizard {
+
+       static Object[] elementEditPages = new Object[] {
+                       // "a", AElementWizardPage.class,
+                       // "img", ImgElementWizardPage.class,
+                       "dl", ListElementWizardPage.class, "ul",
+                       ListElementWizardPage.class, "ol", ListElementWizardPage.class,
+                       "table", TableElementWizardPage.class };
+
+       String targetElemName;
+
+       ITextEditor htEditor;
+
+       EditElementWizardPage rootPage;
+
+       /**
+        * Second argument specify element name, If specify null, call new element
+        * edit wizard page.
+        */
+       public EditElementWizard(ITextEditor editor, String targetElemName) {
+               htEditor = editor;
+               this.targetElemName = targetElemName;
+
+               setWindowTitle("Edit HTML Element");
+               setDefaultPageImageDescriptor(PHPUiImages
+                               .getDescriptor("wizban/editelem_wiz.gif"));
+
+               setForcePreviousAndNextButtons(true);
+       }
+
+       public void addPages() {
+               if (targetElemName == null) {
+                       rootPage = new NewElementWizardPage();
+               } else {
+                       IDocument doc = getDocument();
+                       rootPage = createElementEditPage(targetElemName);
+                       rootPage.setEditType(EditElementWizardPage.MODIFY);
+               }
+               addPage(rootPage);
+       }
+
+       public boolean performFinish() {
+               IWizardPage page = rootPage;
+               for (IWizardPage p; (p = page.getNextPage()) != null;) {
+                       page = p;
+               }
+               if (page instanceof EditElementWizardPage) {
+                       ((EditElementWizardPage) page).performFinish();
+               }
+               return true;
+       }
+
+       public IDocument getDocument() {
+               return htEditor.getDocumentProvider().getDocument(
+                               htEditor.getEditorInput());
+       }
+
+       public ITextSelection getSelection() {
+               return (ITextSelection) htEditor.getSelectionProvider().getSelection();
+       }
+
+       public void setSelection(ITextSelection sel) {
+               htEditor.getSelectionProvider().setSelection(sel);
+       }
+
+       public IFile getCurrentEditFile() {
+               IEditorInput input = htEditor.getEditorInput();
+               return (input instanceof IFileEditorInput) ? ((IFileEditorInput) input)
+                               .getFile() : null;
+       }
+
+       /**
+        * If not edit target returns UnknownElementWizardPage.
+        */
+       public EditElementWizardPage createElementEditPage(String elementName) {
+               EditElementWizardPage page = null;
+               try {
+                       for (int i = 0; i < elementEditPages.length; i += 2) {
+                               if (((String) elementEditPages[i])
+                                               .equalsIgnoreCase(elementName)) {
+                                       Class klass = (Class) elementEditPages[i + 1];
+                                       page = (EditElementWizardPage) klass.newInstance();
+                               }
+                       }
+               } catch (InstantiationException e) {
+                       PHPeclipsePlugin.log(e);
+               } catch (IllegalAccessException e) {
+                       PHPeclipsePlugin.log(e);
+               }
+               if (page == null) {
+                       page = new UnknownElementWizardPage();
+               }
+               page.setElementName(elementName);
+               page.setWizard(this);
+
+               return page;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/EditElementWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/EditElementWizardPage.java
new file mode 100644 (file)
index 0000000..44d1a27
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * $Id: EditElementWizardPage.java,v 1.2 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.WizardPage;
+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.Text;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * 
+ * 
+ */
+public abstract class EditElementWizardPage extends WizardPage implements
+               IPreviewer {
+
+       final public static int NEW = 0, MODIFY = 1;
+
+       private static DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
+                       .newInstance();
+
+       Composite extendComp;
+
+       Text preview;
+
+       private String elementName = null;
+
+       int editType = NEW;
+
+       protected EditElementWizardPage(String pageName) {
+               super(pageName);
+       }
+
+       public void createControl(Composite parent) {
+               Composite base = new Composite(parent, SWT.NONE);
+               setControl(base);
+               base.setLayout(new GridLayout(1, false));
+
+               // create child control.
+               Composite childControlBase = new Composite(base, SWT.NONE);
+               childControlBase.setLayoutData(new GridData(GridData.FILL_BOTH));
+               try {
+                       createChildControl(childControlBase);
+               } catch (CoreException e) {
+                       PHPeclipsePlugin.log(e);
+                       return;
+               }
+
+               // preview components.
+               Composite previewBase = new Composite(base, SWT.NONE);
+
+               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+               previewBase.setLayoutData(gd);
+               previewBase.setLayout(new GridLayout(1, false));
+
+               Label labe = new Label(previewBase, SWT.NONE);
+               labe.setText("Preview:");
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               labe.setLayoutData(gd);
+
+               preview = new Text(previewBase, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY
+                               | SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL);
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.widthHint = 0;
+               gd.heightHint = preview.getLineHeight() * 4;
+               preview.setLayoutData(gd);
+
+               refreshPreview();
+       }
+
+       abstract protected void createChildControl(Composite parent)
+                       throws CoreException;
+
+       public abstract String getPreviewText();
+
+       public void refreshPreview() {
+               if (preview != null) {
+                       String text = getPreviewText();
+                       preview.setText(text == null ? "" : text);
+               }
+       }
+
+       public String getElementName() {
+               return elementName;
+       }
+
+       public void setElementName(String string) {
+               elementName = string;
+       }
+
+       protected IFile getEditFile() {
+               IFile file = null;
+               IWizard wiz = getWizard();
+               if (wiz instanceof EditElementWizard) {
+                       file = ((EditElementWizard) wiz).getCurrentEditFile();
+               }
+               return file;
+       }
+
+       protected void performFinish() {
+               EditElementWizard wiz = (EditElementWizard) getWizard();
+               ITextSelection sel = wiz.getSelection();
+               IDocument doc = wiz.getDocument();
+               int offset = sel.getOffset();
+               try {
+                       doc.replace(offset, sel.getLength(), getPreviewText());
+               } catch (BadLocationException e) {
+                       PHPeclipsePlugin.log(e);
+               }
+               int index = doc.get().indexOf('>', offset);
+               if (index != -1) {
+                       wiz.setSelection(new TextSelection(index + 1, 0));
+               }
+       }
+
+       /**
+        * Returns edit type.
+        */
+       public int getEditType() {
+               return editType;
+       }
+
+       /**
+        * Sets edit type that types are EditElementWizardPage.NEW,
+        * EditElementWizardPage.MODIFY. Default value is NEW.
+        */
+       public void setEditType(int i) {
+               editType = i;
+       }
+
+       protected String getSelectionText() {
+               return ((EditElementWizard) getWizard()).getSelection().getText();
+       }
+
+       protected Element getParsedSelectionText() {
+               String selText = getSelectionText();
+               try {
+                       InputSource source = new InputSource(new StringReader(selText));
+                       Document doc = docBuilderFactory.newDocumentBuilder().parse(source);
+                       return doc.getDocumentElement();
+               } catch (SAXException e) {
+               } catch (IOException e) {
+               } catch (ParserConfigurationException e) {
+               }
+               return null;
+
+       }
+
+       protected static String chooseContent(String text) {
+               int b = -1, e = -1, len = text.length();
+               for (int i = 0; i < len; i++) {
+                       if (text.charAt(i) == '>') {
+                               b = i + 1;
+                               break;
+                       }
+               }
+               for (int i = len - 1; i >= 0; i--) {
+                       if (text.charAt(i) == '<') {
+                               e = i;
+                               break;
+                       }
+               }
+               return (b != -1 && e != -1 && b < len && e < len) ? text
+                               .substring(b, e) : "";
+
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/ElementWriter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/ElementWriter.java
new file mode 100644 (file)
index 0000000..8bd46ee
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * $Id: ElementWriter.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.HashMap;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * ElementWriter provides destribute xml code.
+ */
+public class ElementWriter {
+
+       final public static int BEGIN_CHANGELINE = 1, END_CHANGELINE = 2;
+
+       boolean trim = true;
+
+       HashMap expandOptions = new HashMap();
+
+       int defaultExpandOption;
+
+       String indent;
+
+       public ElementWriter() {
+               this(0, "  ");
+       }
+
+       public ElementWriter(int defaultExpandOption, String indent) {
+               this.defaultExpandOption = defaultExpandOption;
+               this.indent = indent;
+       }
+
+       public void setExpandOption(String elementName, int value) {
+               expandOptions.put(elementName, new Integer(value));
+       }
+
+       public int getExpandOption(String elementName) {
+               if (expandOptions.containsKey(elementName)) {
+                       return ((Integer) expandOptions.get(elementName)).intValue();
+               }
+               return defaultExpandOption;
+       }
+
+       boolean isBeginChangeLine(String elementName) {
+               return (getExpandOption(elementName) & BEGIN_CHANGELINE) != 0;
+       }
+
+       boolean isEndChangeLine(String elementName) {
+               return (getExpandOption(elementName) & END_CHANGELINE) != 0;
+       }
+
+       public String expandTag(Element element) {
+               StringBuffer buff = new StringBuffer();
+               expandTag(element, 0, buff);
+               return buff.toString();
+       }
+
+       public void writeTag(Element element, OutputStream out) throws IOException {
+               OutputStreamWriter writer = new OutputStreamWriter(out);
+               try {
+                       writer.write("<?xml version=\"1.0\"?>\n\n");
+                       writer.write(new ElementWriter().expandTag(element));
+               } finally {
+                       if (writer != null) {
+                               writer.close();
+                       }
+               }
+       }
+
+       void expandTag(Element element, int level, StringBuffer buff) {
+               expandIndent(level, buff);
+
+               String elementName = element.getNodeName();
+               buff.append('<' + elementName);
+               NamedNodeMap attrs = element.getAttributes();
+               for (int i = 0; i < attrs.getLength(); i++) {
+                       Node n = attrs.item(i);
+                       String v = n.getNodeValue();
+                       if (v != null) {
+                               buff.append(' ' + n.getNodeName() + "=\""
+                                               + HTMLUtilities.escape(v) + "\"");
+                       }
+               }
+
+               boolean emptyElem = element.getChildNodes().getLength() == 0;
+               if (emptyElem) {
+                       buff.append(" /");
+               }
+               buff.append('>');
+               if (!emptyElem) {
+                       NodeList childElements = element.getChildNodes();
+                       if (isBeginChangeLine(elementName)) {
+                               buff.append('\n');
+                       }
+                       for (int i = 0; i < childElements.getLength(); i++) {
+                               Node node = childElements.item(i);
+                               if (node instanceof Element) {
+                                       expandTag((Element) node, level + 1, buff);
+                               } else if (node instanceof Text) {
+                                       String text = ((Text) node).getNodeValue();
+                                       if (trim && (text = text.trim()).length() == 0) {
+                                               continue;
+                                       }
+                                       buff.append(text);
+                               }
+                       }
+                       expandIndent(level, buff);
+                       buff.append("</" + elementName + '>');
+               }
+               // already inserted change line.
+               if (isEndChangeLine(elementName)) {
+                       buff.append('\n');
+               }
+       }
+
+       void expandIndent(int level, StringBuffer buff) {
+               if (indent != null) {
+                       for (int i = 0; i < level; i++) {
+                               buff.append(indent);
+                       }
+               }
+       }
+
+       public int getDefaultExpandOption() {
+               return defaultExpandOption;
+       }
+
+       public void setDefaultExpandOption(int i) {
+               defaultExpandOption = i;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/FormElementWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/FormElementWizardPage.java
new file mode 100644 (file)
index 0000000..d9ab7e7
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * $Id: FormElementWizardPage.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * 
+ */
+public class FormElementWizardPage extends EditElementWizardPage {
+
+       Text actionText;
+
+       Button postRadio, getRadio, multipartCheck;
+
+       Combo charsetCombo;
+
+       public FormElementWizardPage() {
+               super("FormElementWizardPage");
+       }
+
+       protected void createChildControl(Composite parent) throws CoreException {
+               postRadio = new Button(parent, SWT.RADIO);
+
+       }
+
+       public String getPreviewText() {
+               boolean controlCreated = actionText != null;
+
+               StringBuffer buff = new StringBuffer("<form action=\"");
+               if (controlCreated) {
+                       buff.append(actionText.getText());
+               }
+               buff.append("\" method=\"");
+               if (controlCreated && postRadio.getSelection()) {
+                       buff.append("POST\"");
+                       if (multipartCheck.getSelection()) {
+                               buff.append(" enctype=\"multipart/form-data\"");
+                       }
+
+               } else {
+                       buff.append("GET\"");
+               }
+
+               if (controlCreated) {
+                       String charset = charsetCombo.getText();
+                       if (charset != null) {
+                               buff.append(" accept-charset=\"" + charset + "\"");
+                       }
+               }
+
+               buff.append(">\n");
+               buff.append(getSelectionText());
+               buff.append("\n</form>\n");
+
+               return buff.toString();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/HTMLUtilities.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/HTMLUtilities.java
new file mode 100644 (file)
index 0000000..8f9db38
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * $Id: HTMLUtilities.java,v 1.2 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+/**
+ * 
+ */
+public class HTMLUtilities {
+
+       final static String[] specialMarks = { "&", "&amp;", "<", "&lt;", ">",
+                       "&gt;", "\"", "&quot;", };
+
+       public static String escape(String text) {
+               for (int i = 0; i < specialMarks.length; i += 2) {
+                       text = text.replaceAll(specialMarks[i], specialMarks[i + 1]);
+               }
+               return text;
+       }
+
+       public static String unescape(String text) {
+               for (int i = specialMarks.length - 1; i >= 0; i -= 2) {
+                       text = text.replaceAll(specialMarks[i], specialMarks[i - 1]);
+               }
+               return text;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/IPreviewer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/IPreviewer.java
new file mode 100644 (file)
index 0000000..7f1fc83
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * $Id: IPreviewer.java,v 1.2 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+/**
+ * 
+ */
+public interface IPreviewer {
+
+       String getPreviewText();
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/InsertHTMLElementAction.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/InsertHTMLElementAction.java
new file mode 100644 (file)
index 0000000..5ca0f4a
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * $Id: InsertHTMLElementAction.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * InsertTagAction
+ */
+public class InsertHTMLElementAction implements IEditorActionDelegate {
+
+       ITextEditor targetEditor = null;
+
+       public InsertHTMLElementAction() {
+       }
+
+       public void setActiveEditor(IAction action, IEditorPart targetEditor) {
+               if (targetEditor instanceof ITextEditor) {
+                       this.targetEditor = (ITextEditor) targetEditor;
+               }
+       }
+
+       public void run(IAction action) {
+
+               WizardDialog wizDialog = new WizardDialog(targetEditor.getSite()
+                               .getShell(), new EditElementWizard(targetEditor, null)) {
+
+                       protected int getShellStyle() {
+                               return super.getShellStyle() | SWT.RESIZE;
+                       }
+               };
+
+               wizDialog.open();
+       }
+
+       public void selectionChanged(IAction action, ISelection selection) {
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/ListElementWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/ListElementWizardPage.java
new file mode 100644 (file)
index 0000000..d49f96d
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * $Id: ListElementWizardPage.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+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.Label;
+
+/**
+ * 
+ */
+public class ListElementWizardPage extends EditElementWizardPage {
+
+       final static String[] LIST_TYPES = { "ul", "ol", "dl" };
+
+       Combo types;
+
+       public ListElementWizardPage() {
+               super("ListElementWizardPage");
+               setTitle("List");
+               setDescription("Editing list element.");
+       }
+
+       protected void createChildControl(Composite parent) {
+               parent.setLayout(new GridLayout(2, false));
+               Label labe = new Label(parent, SWT.NONE);
+               labe.setText("List &Type:");
+
+               types = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+               for (int i = 0; i < LIST_TYPES.length; i++) {
+                       String type = LIST_TYPES[i];
+                       types.add(type);
+                       if (getElementName().equals(type)) {
+                               types.select(i);
+                       }
+               }
+
+               types.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               types.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               setElementName(types.getText());
+                               refreshPreview();
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+       }
+
+       public String getPreviewText() {
+               String content = ((EditElementWizard) getWizard()).getSelection()
+                               .getText().trim();
+
+               String elemName = getElementName();
+               switch (getEditType()) {
+               case MODIFY:
+                       content = chooseContent(content).trim();
+                       break;
+
+               case NEW:
+                       String[] lines = content.split("\n+");
+                       StringBuffer result = new StringBuffer();
+                       for (int i = 0; i < lines.length; i++) {
+                               String itemElemName;
+                               if (elemName.equals("dl")) {
+                                       itemElemName = (i % 2 == 0) ? "dt" : "dd";
+                               } else {
+                                       itemElemName = "li";
+                               }
+                               result.append("<" + itemElemName + ">" + lines[i].trim() + "</"
+                                               + itemElemName + ">\n");
+                       }
+                       content = result.toString();
+                       break;
+               }
+
+               return "<" + elemName + ">\n" + content + "</" + elemName + ">\n";
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/NewElementWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/NewElementWizardPage.java
new file mode 100644 (file)
index 0000000..933317a
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * $Id: NewElementWizardPage.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+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.Text;
+
+/**
+ * 
+ */
+public class NewElementWizardPage extends EditElementWizardPage {
+
+       Text elementName;
+
+       EditElementWizardPage nextPage = null;
+
+       public NewElementWizardPage() {
+               super("NewElementPage");
+               setTitle("Create HTML Element");
+               setDescription("Specify new HTML tag (dl,ul,ol or table) and configure that tag.");
+       }
+
+       protected void createChildControl(Composite base) {
+               // create foundation component
+               base.setLayout(new GridLayout(1, false));
+
+               // element input components
+               new Label(base, SWT.NONE).setText("&Element Name:");
+
+               elementName = new Text(base, SWT.BORDER | SWT.SINGLE);
+               elementName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+               elementName.addModifyListener(new ModifyListener() {
+                       public void modifyText(ModifyEvent e) {
+                               String eName = elementName.getText();
+                               if (eName.indexOf(' ') != -1) {
+                                       setErrorMessage("Don't contain blink in speicfied element name.");
+                               } else if (eName.length() == 0) {
+                                       setErrorMessage("Need to specify element name.");
+                               } else {
+                                       setErrorMessage(null);
+                                       nextPage = ((EditElementWizard) getWizard())
+                                                       .createElementEditPage(eName);
+                                       nextPage.setElementName(eName);
+                                       if (nextPage instanceof UnknownElementWizardPage) {
+                                               setMessage("This editor does not known element name.",
+                                                               WARNING);
+                                       } else {
+                                               setMessage(null, NONE);
+                                       }
+                               }
+                               refreshPreview();
+                               getWizard().getContainer().updateButtons();
+                       }
+               });
+       }
+
+       public String getPreviewText() {
+               if (nextPage instanceof EditElementWizardPage) {
+                       return ((EditElementWizardPage) nextPage).getPreviewText();
+               }
+               return null;
+       }
+
+       public void setErrorMessage(String newMessage) {
+               super.setErrorMessage(newMessage);
+               if (newMessage != null) {
+                       nextPage = null;
+               }
+       }
+
+       public IWizardPage getNextPage() {
+               return nextPage;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/NumVerifyListener.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/NumVerifyListener.java
new file mode 100644 (file)
index 0000000..6cdfee5
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * $Id: NumVerifyListener.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+
+public class NumVerifyListener implements VerifyListener {
+
+       Pattern numPattern = Pattern.compile("^\\d+$");
+
+       public void verifyText(VerifyEvent ev) {
+               ev.doit = numPattern.matcher(ev.text).matches()
+                               || ev.keyCode == SWT.DEL || ev.character == SWT.BS;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/SomeItemInputDialog.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/SomeItemInputDialog.java
new file mode 100644 (file)
index 0000000..fdbfeb0
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * $Id: SomeItemInputDialog.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+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.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * 
+ */
+public class SomeItemInputDialog extends Dialog {
+
+       String dialogTitle;
+
+       String[] inputMessages;
+
+       IInputValidator[] validators;
+
+       Text[] texts;
+
+       Text error;
+
+       String[] errorMsgs;
+
+       String[] resultValues;
+
+       public SomeItemInputDialog(Shell parentShell, String dialogTitle,
+                       String[] inputMessages, IInputValidator[] validators) {
+               super(parentShell);
+               if (inputMessages.length != validators.length) {
+                       throw new IllegalArgumentException(
+                                       "Specify validator counts and input message count is not same.");
+               }
+
+               this.dialogTitle = dialogTitle;
+               this.inputMessages = (String[]) inputMessages.clone();
+               this.validators = (IInputValidator[]) validators.clone();
+               this.errorMsgs = new String[validators.length];
+
+               setShellStyle(SWT.RESIZE | getShellStyle());
+       }
+
+       protected void configureShell(Shell newShell) {
+               super.configureShell(newShell);
+               newShell.setText(dialogTitle);
+       }
+
+       protected Control createDialogArea(Composite parent) {
+               Composite base = (Composite) super.createDialogArea(parent);
+               GridLayout gl = new GridLayout(2, false);
+               gl.marginWidth = 4;
+               gl.marginHeight = 6;
+               base.setLayout(gl);
+
+               texts = new Text[inputMessages.length];
+               for (int i = 0; i < inputMessages.length; i++) {
+                       new Label(base, SWT.NONE).setText(inputMessages[i] + ":");
+
+                       final int index = i;
+                       Text t = new Text(base, SWT.BORDER);
+                       t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+                       t.addModifyListener(new ModifyListener() {
+                               public void modifyText(ModifyEvent e) {
+                                       refreshValidator(index);
+                               }
+                       });
+                       texts[i] = t;
+               }
+
+               error = new Text(base, SWT.READ_ONLY);
+               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalSpan = 2;
+               error.setLayoutData(gd);
+
+               return base;
+       }
+
+       void refreshValidator(int index) {
+               String data = texts[index].getText();
+               IInputValidator validator = validators[index];
+               if (validator != null) {
+                       errorMsgs[index] = validator.isValid(data);
+               }
+
+               Button okButton = getButton(IDialogConstants.OK_ID);
+               for (int i = 0; i < errorMsgs.length; i++) {
+                       String msg = errorMsgs[i];
+                       if (msg != null) {
+                               error.setText(msg);
+                               okButton.setEnabled(false);
+                               return;
+                       }
+               }
+               error.setText("");
+               okButton.setEnabled(true);
+       }
+
+       public String[] getValues() {
+               return (String[]) resultValues.clone();
+       }
+
+       protected Point getInitialSize() {
+               Point p = super.getInitialSize();
+               return new Point(p.x * 2, (int) (p.y * 1.25));
+       }
+
+       protected void okPressed() {
+               resultValues = new String[texts.length];
+               for (int i = 0; i < texts.length; i++) {
+                       resultValues[i] = texts[i].getText();
+               }
+               super.okPressed();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/StringDivider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/StringDivider.java
new file mode 100644 (file)
index 0000000..8439fbc
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * $Id: StringDivider.java,v 1.2 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+public class StringDivider {
+
+       static Pattern tagNameChoosePattern = Pattern
+                       .compile("<[\\s/]*(\\w+)\\s*.*>");
+
+       String[] splitRegexpCandidates = { "\t", ",", "\\s", "\\s+", };
+
+       public StringDivider() {
+       }
+
+       public String[][] divide(String content) {
+               return divide(content, getDivideSuitedRegexp(content));
+       }
+
+       public String[][] divide(String content, String regexp) {
+               String[] lines = content.split("\n");
+               int len = lines.length;
+               String[][] dist = new String[len][];
+
+               int max = Integer.MIN_VALUE;
+               for (int i = 0; i < len; i++) {
+                       String line = lines[i];
+                       String[] cells = line.split(regexp);
+                       dist[i] = cells;
+                       if (max < cells.length) {
+                               max = cells.length;
+                       }
+               }
+               for (int i = 0; i < len; i++) {
+                       String[] newArray = new String[max];
+                       Arrays.fill(newArray, "");
+                       System.arraycopy(dist[i], 0, newArray, 0, dist[i].length);
+                       dist[i] = newArray;
+               }
+               return dist;
+       }
+
+       public String getDivideSuitedRegexp(String content) {
+               String[] lines = content.split("\n");
+
+               String resultRegexp = null;
+               int score = Integer.MAX_VALUE, cellCount = Integer.MIN_VALUE;
+
+               for (int i = 0; i < splitRegexpCandidates.length; i++) {
+                       String regexp = splitRegexpCandidates[i];
+                       int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
+                       for (int j = 0; j < lines.length; j++) {
+                               String[] vals = lines[j].split(regexp);
+                               if (max < vals.length) {
+                                       max = vals.length;
+                               }
+                               if (min > vals.length) {
+                                       min = vals.length;
+                               }
+                       }
+                       int s = max - min;
+                       if (score > s || (score == s && max > cellCount)) {
+                               cellCount = max;
+                               score = s;
+                               resultRegexp = regexp;
+                       }
+               }
+               return resultRegexp;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementCellModifier.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementCellModifier.java
new file mode 100644 (file)
index 0000000..62e767d
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * $Id: TableElementCellModifier.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.swt.widgets.Item;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * 
+ */
+public class TableElementCellModifier implements ICellModifier {
+
+       DocumentBuilderFactory builderFactory;
+
+       IPropertyChangeListener listener;
+
+       public TableElementCellModifier(IPropertyChangeListener listener) {
+               builderFactory = DocumentBuilderFactory.newInstance();
+               this.listener = listener;
+       }
+
+       public boolean canModify(Object element, String property) {
+               return getValue(element, property) != null;
+       }
+
+       public Object getValue(Object trElem, String property) {
+               if (trElem instanceof Element) {
+                       Element e = (Element) trElem;
+                       if (e.getNodeName().equals("tr")) {
+                               int v = TableElementModel.toNumeric(property);
+                               Element[] cells = TableElementModel.chooseCellElements(e);
+                               if (v >= 0 && v < cells.length) {
+                                       NodeList nodes = cells[v].getChildNodes();
+                                       if (nodes.getLength() == 1) {
+                                               Node n = nodes.item(0);
+                                               if (n instanceof Text) {
+                                                       return n.getNodeValue();
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return null;
+       }
+
+       public void modify(Object element, String property, Object value) {
+               if (element instanceof Item) {
+                       element = ((Item) element).getData();
+               }
+               Element trElem = (Element) element;
+               int index = TableElementModel.toNumeric(property);
+               Element cellElem = TableElementModel.chooseCellElements(trElem)[index];
+
+               NodeList nodes = cellElem.getChildNodes();
+               for (int i = 0; i < nodes.getLength(); i++) {
+                       cellElem.removeChild(nodes.item(i));
+               }
+               Document doc = cellElem.getOwnerDocument();
+
+               if (value instanceof String) {
+                       cellElem.appendChild(doc.createTextNode((String) value));
+               }
+               // notify listener
+               if (listener != null) {
+                       String oldValue = nodes.item(0).getNodeValue();
+                       listener.propertyChange(new PropertyChangeEvent(this, property,
+                                       (String) value, oldValue));
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementContentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementContentProvider.java
new file mode 100644 (file)
index 0000000..8a3ba8c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * $Id: TableElementContentProvider.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * 
+ */
+public class TableElementContentProvider implements IStructuredContentProvider {
+
+       public TableElementContentProvider() {
+               super();
+       }
+
+       public Object[] getElements(Object inputElement) {
+               TableElementModel model = (TableElementModel) inputElement;
+               return model.getRows();
+       }
+
+       public void dispose() {
+       }
+
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementLabelProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementLabelProvider.java
new file mode 100644 (file)
index 0000000..7fb1752
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * $Id: TableElementLabelProvider.java,v 1.3 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * 
+ */
+public class TableElementLabelProvider implements ITableLabelProvider {
+
+       public Image getColumnImage(Object element, int columnIndex) {
+               return null;
+       }
+
+       public String getColumnText(Object element, int columnIndex) {
+               Element[] cells = TableElementModel
+                               .chooseCellElements((Element) element);
+               if (columnIndex < cells.length) {
+                       Element elem = cells[columnIndex];
+                       return elem.toString();
+               } else {
+                       throw new IllegalArgumentException("Invalid element:" + element);
+               }
+       }
+
+       public boolean isLabelProperty(Object element, String property) {
+               return TableElementModel.toNumeric(property) != -1;
+       }
+
+       public void addListener(ILabelProviderListener listener) {
+       }
+
+       public void removeListener(ILabelProviderListener listener) {
+       }
+
+       public void dispose() {
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementModel.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementModel.java
new file mode 100644 (file)
index 0000000..b9aeef8
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * $Id: TableElementModel.java,v 1.2 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * TableElementModel
+ */
+public class TableElementModel {
+
+       final static char[] CHAR_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+
+       StringDivider stringDivider = new StringDivider();
+
+       ElementWriter writer;
+
+       DocumentBuilder docBuilder;
+
+       Document document;
+
+       Element tableElement;
+
+       String[] columnProperties;
+
+       public TableElementModel(String content, boolean parse)
+                       throws FactoryConfigurationError, ParserConfigurationException,
+                       SAXException, IOException {
+               docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+               if (parse) {
+                       initAsParse(content);
+               } else {
+                       initModel(content);
+               }
+               columnProperties = createColumnProperties();
+
+               // create elementWriter
+               writer = new ElementWriter(0, null);
+               writer.setExpandOption("caption", ElementWriter.END_CHANGELINE);
+               writer.setExpandOption("table", ElementWriter.BEGIN_CHANGELINE
+                               | ElementWriter.END_CHANGELINE);
+               writer.setExpandOption("thead", ElementWriter.BEGIN_CHANGELINE
+                               | ElementWriter.END_CHANGELINE);
+               writer.setExpandOption("tfoot", ElementWriter.BEGIN_CHANGELINE
+                               | ElementWriter.END_CHANGELINE);
+               writer.setExpandOption("tbody", ElementWriter.BEGIN_CHANGELINE
+                               | ElementWriter.END_CHANGELINE);
+               writer.setExpandOption("tr", ElementWriter.END_CHANGELINE);
+       }
+
+       void initModel(String content) throws ParserConfigurationException,
+                       SAXException, IOException {
+               StringReader strReader = new StringReader(content);
+               InputSource inputSrc = new InputSource(strReader);
+
+               document = docBuilder.parse(inputSrc);
+               tableElement = document.getDocumentElement();
+
+               Element[] rows = getRows();
+               for (int i = 0; i < rows.length; i++) {
+                       Element[] cells = chooseCellElements(rows[i]);
+                       for (int j = 0; j < cells.length; j++) {
+                               Element cell = cells[j];
+                               if (!cell.hasChildNodes()) {
+                                       cell.appendChild(document.createTextNode(""));
+                               }
+                       }
+               }
+       }
+
+       public void initAsParse(String content)
+                       throws ParserConfigurationException, FactoryConfigurationError {
+               // create new table model.
+               document = docBuilder.newDocument();
+               tableElement = document.createElement("table");
+
+               String[][] cells = stringDivider.divide(content);
+               if (cells.length > 0) {
+                       for (int i = 0; i < cells.length; i++) {
+                               String[] rows = cells[i];
+                               Element tr = document.createElement("tr");
+                               for (int j = 0; j < rows.length; j++) {
+                                       Element e = document.createElement("td");
+                                       e.appendChild(document.createTextNode(rows[j]));
+                                       tr.appendChild(e);
+                               }
+                               tableElement.appendChild(tr);
+                       }
+
+                       setColumnCount(cells[0].length);
+               } else {
+                       Element tr = document.createElement("tr");
+                       Element td = document.createElement("td");
+                       td.appendChild(document.createTextNode(""));
+                       tr.appendChild(td);
+                       tableElement.appendChild(tr);
+
+                       setColumnCount(1);
+               }
+       }
+
+       String[] createColumnProperties() {
+               int len = getColumnCount();
+               String[] props = new String[len];
+               for (int i = 0; i < len; i++) {
+                       props[i] = toColumnName(i);
+               }
+               return props;
+       }
+
+       public void setRowCount(int rowCount) {
+               Element[] rows = getRows();
+               if (rowCount > rows.length) {
+                       for (int i = rows.length; i < rowCount; i++) {
+                               tableElement.appendChild(createRowElement());
+                       }
+               } else if (rowCount < rows.length) {
+                       for (int i = rowCount; i < rows.length; i++) {
+                               tableElement.removeChild(rows[i]);
+                       }
+               }
+       }
+
+       public Element[] getRows() {
+               ArrayList rows = new ArrayList();
+               NodeList nodes = tableElement.getElementsByTagName("tr");
+               for (int i = 0; i < nodes.getLength(); i++) {
+                       rows.add(nodes.item(i));
+               }
+               return (Element[]) rows.toArray(new Element[rows.size()]);
+       }
+
+       public int getRowCount() {
+               return getRows().length;
+       }
+
+       Element createRowElement() {
+               Element tr = document.createElement("tr");
+               for (int i = 0, columnCount = getColumnCount(); i < columnCount; i++) {
+                       Element td = document.createElement("td");
+                       td.appendChild(document.createTextNode(""));
+                       tr.appendChild(td);
+               }
+               return tr;
+       }
+
+       public void setColumnCount(int newLength) {
+               NodeList trs = tableElement.getElementsByTagName("tr");
+               for (int i = 0; i < trs.getLength(); i++) {
+                       Element tr = (Element) trs.item(i);
+                       Element[] cells = chooseCellElements(tr);
+                       int colLen = cells.length;
+
+                       if (newLength > colLen) {
+                               for (int j = 0, len = newLength - colLen; j < len; j++) {
+                                       Element cell = document.createElement("td");
+                                       cell.appendChild(document.createTextNode(""));
+                                       tr.appendChild(cell);
+                               }
+                       } else if (newLength < colLen) {
+                               for (int j = newLength; j < colLen; j++) {
+                                       tr.removeChild(cells[j]);
+                               }
+                       }
+               }
+               columnProperties = createColumnProperties();
+       }
+
+       public int getColumnCount() {
+               NodeList trs = tableElement.getElementsByTagName("tr");
+               if (trs.getLength() > 0) {
+                       Element tr = (Element) trs.item(0);
+                       return chooseCellElements(tr).length;
+               } else {
+                       return 0;
+               }
+       }
+
+       public static Element[] chooseCellElements(Element tr) {
+               NodeList nodeList = tr.getChildNodes();
+
+               ArrayList result = new ArrayList();
+               for (int i = 0; i < nodeList.getLength(); i++) {
+                       Node node = nodeList.item(i);
+                       if (node instanceof Element) {
+                               String nodeName = node.getNodeName();
+                               if (nodeName.equals("td") || nodeName.equals("th")) {
+                                       result.add(node);
+                               }
+                       }
+               }
+
+               return (Element[]) result.toArray(new Element[result.size()]);
+       }
+
+       public String expandCodes() {
+               return writer.expandTag(tableElement);
+       }
+
+       public static String toColumnName(int i) {
+               StringBuffer buff = new StringBuffer();
+               int u = i / CHAR_TABLE.length;
+               if (u > 0) {
+                       buff.append(CHAR_TABLE[u - 1]);
+               }
+               buff.append(CHAR_TABLE[i % CHAR_TABLE.length]);
+               return buff.toString();
+       }
+
+       /**
+        * Return index of char map. If can not parse values return -1.
+        */
+       public static int toNumeric(String code) {
+               int result = -1;
+               for (int i = 0; i < code.length(); i++) {
+                       char c = code.charAt(i);
+                       int match = Arrays.binarySearch(CHAR_TABLE, c);
+                       if (match >= 0) {
+                               if (result == -1) {
+                                       result = 0;
+                               }
+                               int v = match;
+                               int u = code.length() - 1 - i;
+                               if (u > 0) {
+                                       v = CHAR_TABLE.length * u * (v + 1);
+                               }
+                               result += v;
+                       }
+               }
+               return result;
+       }
+
+       public void move(Element tr, int moveCount) {
+               Element[] rows = getRows();
+               int index = -1;
+               for (int i = 0; i < rows.length; i++) {
+                       if (tr.equals(rows[i])) {
+                               index = i;
+                       }
+               }
+               if (index == -1) {
+                       throw new IllegalArgumentException(
+                                       "Invalid row node (not countained in this table):" + tr);
+               }
+               if (moveCount > 0) {
+                       // move down;
+                       for (int i = index; i < moveCount + index && i < rows.length - 1; i++) {
+                               tableElement.insertBefore(rows[i + 1], rows[i]);
+                       }
+               } else if (moveCount < 0) {
+                       // move up
+                       for (int i = index; i >= moveCount + index + 1 && i >= 1; i--) {
+                               tableElement.insertBefore(rows[index], rows[i - 1]);
+                       }
+               } else {
+                       return;
+               }
+       }
+
+       public void insertNewRowBefore(Element tr) {
+               Element newRow = createRowElement();
+               if (tr == null) {
+                       tableElement.appendChild(newRow);
+               } else {
+                       tableElement.insertBefore(newRow, tr);
+               }
+       }
+
+       public void removeRow(Element tr) {
+               tableElement.removeChild(tr);
+       }
+
+       public String[] getColumnProperties() {
+               return (String[]) columnProperties.clone();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/TableElementWizardPage.java
new file mode 100644 (file)
index 0000000..93b35ec
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * $Id: TableElementWizardPage.java,v 1.2 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/**
+ * TableElementWizardPage.
+ */
+public class TableElementWizardPage extends EditElementWizardPage {
+
+       final public static int COLUMNS_MAX = 32, ROWS_MAX = 256;
+
+       final static String[] expandStyleLabels = { "Flat", "Table", "Enumerate", };
+
+       TableElementModel model;
+
+       TableViewer viewer;
+
+       CellEditor[] editors;
+
+       Combo expandStyleCombo = null;
+
+       Text colsText, rowsText;
+
+       Button addButton, removeButton, upButton, downButton;
+
+       SelectionListener buttonListener = new SelectionListener() {
+               public void widgetSelected(SelectionEvent ev) {
+                       Element e = getCurrentSelection();
+                       if (ev.widget == addButton) {
+                               model.insertNewRowBefore(e);
+                       } else if (ev.widget == removeButton) {
+                               model.removeRow(e);
+                       } else if (ev.widget == upButton) {
+                               model.move(e, -1);
+                       } else if (ev.widget == downButton) {
+                               model.move(e, 1);
+                       }
+                       refreshAll();
+               }
+
+               public void widgetDefaultSelected(SelectionEvent e) {
+               }
+       };
+
+       ModifyListener cellCountChangeListener = new ModifyListener() {
+               public void modifyText(ModifyEvent e) {
+                       try {
+                               if (e.widget == colsText) {
+                                       int cols = Integer.parseInt(colsText.getText());
+                                       if (cols < 1)
+                                               cols = 1;
+                                       if (cols > COLUMNS_MAX)
+                                               cols = COLUMNS_MAX;
+                                       model.setColumnCount(cols);
+                               } else if (e.widget == rowsText) {
+                                       int rows = Integer.parseInt(rowsText.getText());
+                                       if (rows < 1)
+                                               rows = 1;
+                                       if (rows > ROWS_MAX)
+                                               rows = ROWS_MAX;
+                                       model.setRowCount(rows);
+                               }
+                               refreshAll();
+                       } catch (NumberFormatException x) {
+                       }
+               }
+       };
+
+       public TableElementWizardPage() {
+               super("TableElementWizardPage");
+               setTitle("Table");
+               setDescription("Edit table element and cells modifier.");
+       }
+
+       public String getPreviewText() {
+               if (model == null) {
+                       initModel();
+               }
+               return (model != null) ? model.expandCodes() : null;
+       }
+
+       void initModel() {
+               String content = ((EditElementWizard) getWizard()).getSelection()
+                               .getText().trim();
+               try {
+                       model = new TableElementModel(content, getEditType() == NEW);
+               } catch (ParserConfigurationException e) {
+                       PHPeclipsePlugin.log(e);
+               } catch (SAXException e) {
+                       PHPeclipsePlugin.log(e);
+               } catch (IOException e) {
+                       PHPeclipsePlugin.log(e);
+               }
+       }
+
+       protected void createChildControl(Composite parent) {
+               parent.setLayout(new GridLayout(2, false));
+
+               // table settings
+               viewer = new TableViewer(parent, SWT.SINGLE | SWT.FULL_SELECTION
+                               | SWT.BORDER);
+               refreshTableHeaderColumns();
+
+               viewer.setContentProvider(new TableElementContentProvider());
+               viewer.setLabelProvider(new TableElementLabelProvider());
+               viewer.setCellModifier(new TableElementCellModifier(
+                               new IPropertyChangeListener() {
+                                       public void propertyChange(PropertyChangeEvent event) {
+                                               refreshAll();
+                                       }
+                               }));
+
+               viewer.setInput(model);
+               viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+                       public void selectionChanged(SelectionChangedEvent event) {
+                               refreshButtonState();
+                               refreshPreview();
+                       }
+               });
+
+               Table table = viewer.getTable();
+               table.setLinesVisible(true);
+               table.setHeaderVisible(true);
+
+               GridData gd = new GridData(GridData.FILL_BOTH);
+               gd.verticalSpan = 2;
+               table.setLayoutData(gd);
+
+               // text input area setting
+               Composite textInputArea = new Composite(parent, SWT.NONE);
+               textInputArea.setLayout(new GridLayout(1, false));
+               textInputArea.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.VERTICAL_ALIGN_BEGINNING));
+               rowsText = createNumInputText(textInputArea, "&Rows:");
+               colsText = createNumInputText(textInputArea, "&Columns:");
+
+               // button area.
+               Composite buttonArea = new Composite(parent, SWT.NONE);
+               buttonArea.setLayout(new GridLayout(1, false));
+               buttonArea.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                               | GridData.VERTICAL_ALIGN_END));
+               addButton = createButton(buttonArea, "&Add");
+               removeButton = createButton(buttonArea, "&Remove");
+               upButton = createButton(buttonArea, "&Up");
+               downButton = createButton(buttonArea, "&Down");
+
+               // init state
+               TableColumn[] cols = table.getColumns();
+               for (int i = 0; i < cols.length; i++) {
+                       cols[i].pack();
+               }
+               refreshTableLengthText();
+               refreshButtonState();
+       }
+
+       Button createButton(Composite parent, String text) {
+               Button button = new Button(parent, SWT.NONE);
+               button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+               button.setText(text);
+               button.addSelectionListener(buttonListener);
+               return button;
+       }
+
+       Text createNumInputText(Composite parent, String label) {
+               Label labe = new Label(parent, SWT.NONE);
+               labe.setText(label);
+
+               Text text = new Text(parent, SWT.BORDER);
+               text.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+               text.setTextLimit(2);
+               text.addVerifyListener(new NumVerifyListener());
+               text.addModifyListener(cellCountChangeListener);
+               return text;
+       }
+
+       void refreshAll() {
+               refreshTableHeaderColumns();
+               refreshTableLengthText();
+               refreshButtonState();
+               refreshPreview();
+               viewer.refresh();
+       }
+
+       void refreshTableHeaderColumns() {
+               if (model == null) {
+                       initModel();
+               }
+
+               Table table = viewer.getTable();
+               TableColumn[] cols = table.getColumns();
+               CellEditor[] editors = viewer.getCellEditors();
+
+               String[] props = model.getColumnProperties();
+               viewer.setColumnProperties(props);
+               // modify cell length
+               if (props.length > cols.length) {
+                       CellEditor[] newEditors = new CellEditor[props.length];
+                       if (editors != null) {
+                               System.arraycopy(editors, 0, newEditors, 0, editors.length);
+                       }
+                       for (int i = cols.length; i < props.length; i++) {
+                               TableColumn col = new TableColumn(table, SWT.LEFT);
+                               col.setText(TableElementModel.toColumnName(i));
+                               newEditors[i] = new TextCellEditor(table);
+                       }
+                       viewer.setCellEditors(newEditors);
+               } else if (props.length < cols.length) {
+                       for (int i = props.length; i < cols.length; i++) {
+                               cols[i].dispose();
+                               editors[i].dispose();
+                       }
+                       CellEditor[] newEditors = new CellEditor[props.length];
+                       System.arraycopy(editors, 0, newEditors, 0, props.length);
+                       viewer.setCellEditors(newEditors);
+               }
+
+               // adjust table fields.
+               viewer.refresh();
+               cols = table.getColumns();
+               for (int i = 0; i < cols.length; i++) {
+                       cols[i].pack();
+               }
+       }
+
+       void refreshTableLengthText() {
+               String cols = String.valueOf(model.getColumnCount());
+               if (!cols.equals(colsText.getText())) {
+                       colsText.setText(cols);
+               }
+               String rows = String.valueOf(model.getRowCount());
+               if (!rows.equals(rowsText.getText())) {
+                       rowsText.setText(rows);
+               }
+       }
+
+       void refreshButtonState() {
+               Element e = getCurrentSelection();
+               boolean enable = (e != null);
+
+               removeButton.setEnabled(enable);
+               int currentIndex = -1;
+               Element[] rows = model.getRows();
+               for (int i = 0; i < rows.length; i++) {
+                       if (rows[i].equals(e)) {
+                               currentIndex = i;
+                       }
+               }
+               upButton.setEnabled(enable && currentIndex > 0);
+               downButton.setEnabled(enable && currentIndex < rows.length - 1);
+       }
+
+       Element getCurrentSelection() {
+               IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
+               return (sel != null) ? (Element) sel.getFirstElement() : null;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/UnknownElementWizardPage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/wizards/html/UnknownElementWizardPage.java
new file mode 100644 (file)
index 0000000..817451d
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * $Id: UnknownElementWizardPage.java,v 1.2 2006-10-21 23:18:43 pombredanne Exp $
+ * Copyright Narushima Hironori. All rights reserved.
+ */
+package net.sourceforge.phpeclipse.wizards.html;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+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.Item;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * 
+ * 
+ */
+public class UnknownElementWizardPage extends EditElementWizardPage {
+
+       // key of TableCell for attribute editor.
+       final static String NAME = "ColumnProperty-name",
+                       VALUE = "ColumnProperty-value";
+
+       Button emptyElementCheck, addButton, removeButton, upButton, downButton;
+
+       TableViewer unknownElementAttrs;
+
+       ArrayList attrs = new ArrayList(), listeners = new ArrayList();
+
+       SelectionListener elemTypeChangeListener = new SelectionListener() {
+               public void widgetSelected(SelectionEvent e) {
+                       refreshPreview();
+               }
+
+               public void widgetDefaultSelected(SelectionEvent e) {
+               }
+       };
+
+       public UnknownElementWizardPage() {
+               super("UnknownElementEditPage");
+               setTitle("Unknown");
+               setDescription("Editor for any HTML element.");
+       }
+
+       static IInputValidator attrValidator = new IInputValidator() {
+               public String isValid(String newText) {
+                       if (newText.length() == 0) {
+                               return "Need to specify name";
+                       }
+                       if (newText.indexOf(' ') != -1 || newText.indexOf('\n') != -1
+                                       || newText.indexOf('\t') != -1) {
+                               return "Not contain blank";
+                       }
+                       return null;
+               }
+       };
+
+       protected void createChildControl(Composite parent) {
+               // empty eleemnt
+               parent.setLayout(new GridLayout(2, false));
+
+               // // attribute editor
+               Label labe = new Label(parent, SWT.NONE);
+               labe.setText("Element &Attribute:");
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               labe.setLayoutData(gd);
+               new Label(parent, SWT.NONE);
+
+               // attribute display table setting
+               unknownElementAttrs = new TableViewer(parent, SWT.BORDER | SWT.SINGLE
+                               | SWT.FULL_SELECTION);
+               gd = new GridData(GridData.FILL_BOTH);
+               gd.horizontalSpan = 1;
+               gd.verticalSpan = 4;
+               unknownElementAttrs.getControl().setLayoutData(gd);
+
+               final Table table = unknownElementAttrs.getTable();
+               new TableColumn(table, SWT.LEFT).setText("Name");
+               new TableColumn(table, SWT.LEFT).setText("Value");
+
+               table.setLinesVisible(true);
+               table.setHeaderVisible(true);
+               // modifier setting
+               unknownElementAttrs.setColumnProperties(new String[] { NAME, VALUE });
+               unknownElementAttrs.setContentProvider(new ArrayContentProvider());
+
+               unknownElementAttrs.setCellEditors(new CellEditor[] {
+                               new TextCellEditor(table), new TextCellEditor(table) });
+               unknownElementAttrs.setCellModifier(new ICellModifier() {
+                       public boolean canModify(Object element, String property) {
+                               return true;
+                       }
+
+                       public Object getValue(Object element, String property) {
+                               return ((String[]) element)[property.equals(NAME) ? 0 : 1];
+                       }
+
+                       public void modify(Object element, String property, Object value) {
+                               if (element instanceof Item) {
+                                       ((String[]) ((Item) element).getData())[property
+                                                       .equals(NAME) ? 0 : 1] = HTMLUtilities
+                                                       .unescape((String) value);
+                                       refreshPreview();
+                               }
+                       }
+               });
+
+               unknownElementAttrs.setLabelProvider(new ITableLabelProvider() {
+                       public Image getColumnImage(Object element, int columnIndex) {
+                               return null;
+                       }
+
+                       public String getColumnText(Object element, int columnIndex) {
+                               return ((String[]) element)[columnIndex];
+                       }
+
+                       public void addListener(ILabelProviderListener listener) {
+                       }
+
+                       public void removeListener(ILabelProviderListener listener) {
+                       }
+
+                       public void dispose() {
+                       }
+
+                       public boolean isLabelProperty(Object element, String property) {
+                               return property.equals(NAME) || property.equals(VALUE);
+                       }
+               });
+
+               resetAttributes();
+               unknownElementAttrs.setInput(attrs);
+
+               TableColumn[] columns = table.getColumns();
+               for (int i = 0; i < columns.length; i++) {
+                       columns[i].pack();
+               }
+
+               // buttonss
+               upButton = createButton(parent, "&Up");
+               upButton.addSelectionListener(new SelectionListener() {
+
+                       public void widgetSelected(SelectionEvent e) {
+                               int index = getSelectionIndex();
+                               if (index > 0) {
+                                       attrs.add(index - 1, attrs.remove(index));
+                                       refreshPreview();
+                               }
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+
+               downButton = createButton(parent, "&Down");
+               downButton.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               int index = getSelectionIndex();
+                               if (index < attrs.size() - 1) {
+                                       attrs.add(index + 1, attrs.remove(index));
+                                       refreshPreview();
+                               }
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+
+               addButton = createButton(parent, "&Add");
+               addButton.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               int insertIndex = getSelectionIndex();
+                               String[] newData = inputValue();
+                               if (newData != null) {
+                                       attrs.add(newData);
+                                       refreshPreview();
+                               }
+                       }
+
+                       String[] inputValue() {
+                               SomeItemInputDialog dialog = new SomeItemInputDialog(
+                                               getShell(), "Input new attribute", new String[] {
+                                                               "Attribute name", "Attribute value" },
+                                               new IInputValidator[] { attrValidator, null });
+
+                               if (dialog.open() == Window.OK) {
+                                       return dialog.getValues();
+                               }
+                               return null;
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+
+               removeButton = createButton(parent, "&Remove");
+               removeButton.addSelectionListener(new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               int index = getSelectionIndex();
+                               if (index != -1) {
+                                       attrs.remove(index);
+                                       refreshPreview();
+                               }
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               });
+
+               emptyElementCheck = new Button(parent, SWT.CHECK);
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               emptyElementCheck.setLayoutData(gd);
+               emptyElementCheck.setText("&Empty Element");
+               emptyElementCheck.addSelectionListener(elemTypeChangeListener);
+               emptyElementCheck.setSelection(isEmptyAsText());
+
+               new Label(parent, SWT.NONE);
+       }
+
+       static Button createButton(Composite parent, String text) {
+               Button button = new Button(parent, SWT.PUSH);
+               GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+                               | GridData.HORIZONTAL_ALIGN_END);
+               gd.widthHint = 60;
+               button.setLayoutData(gd);
+               button.setText(text);
+               return button;
+       }
+
+       public String getPreviewText() {
+               String elemName = getElementName();
+               if (elemName == null) {
+                       return null;
+               }
+
+               // sets values
+
+               boolean empty = false;
+               if (emptyElementCheck == null) {
+                       // ui uninitialized
+                       empty = isEmptyAsText();
+               } else {
+                       // ui initialized
+                       empty = emptyElementCheck.getSelection();
+               }
+
+               String content = getSelectionText();
+               if (!empty && getEditType() == MODIFY) {
+                       content = chooseContent(content);
+               }
+
+               String previewText = "<" + elemName + attrsCode();
+               if (empty) {
+                       previewText += " />";
+               } else {
+                       previewText += ">" + content + "</" + elemName + ">";
+               }
+               return previewText;
+       }
+
+       boolean isEmptyAsText() {
+               String selText = getSelectionText();
+               if (getEditType() == MODIFY) {
+                       int len = selText.length();
+                       return selText.substring(len - 2, len).equals("/>");
+               }
+               return false;
+       }
+
+       void resetAttributes() {
+               attrs.clear();
+
+               Element elem = getParsedSelectionText();
+               if (elem != null) {
+                       NamedNodeMap as = elem.getAttributes();
+                       for (int i = 0; i < as.getLength(); i++) {
+                               Node n = as.item(i);
+                               attrs.add(new String[] { n.getNodeName(), n.getNodeValue() });
+                       }
+               }
+       }
+
+       String attrsCode() {
+               StringBuffer buff = new StringBuffer();
+               Object[] as = attrs.toArray();
+               for (int i = 0; i < as.length; i++) {
+                       String[] a = (String[]) as[i];
+                       buff.append(" " + a[0] + "=\"" + HTMLUtilities.escape(a[1]) + "\"");
+               }
+               return buff.toString();
+       }
+
+       int getSelectionIndex() {
+               Object sel = unknownElementAttrs.getSelection();
+               if (sel instanceof IStructuredSelection) {
+                       Object item = ((IStructuredSelection) sel).getFirstElement();
+                       return attrs.indexOf(item);
+               } else {
+                       return -1;
+               }
+       }
+
+       public void refreshPreview() {
+               unknownElementAttrs.refresh();
+               super.refreshPreview();
+       }
+
+       public void setElementName(String elemName) {
+               super.setElementName(elemName);
+               setTitle("\"" + elemName + "\" Element");
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPlugin.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPlugin.java
new file mode 100644 (file)
index 0000000..d886c5a
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLPlugin.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui;
+
+import java.net.URL;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpeclipse.xml.ui.text.DTDTextTools;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class XMLPlugin extends AbstractUIPlugin {
+       public static final String ICON_ELEMENT = "element_obj.gif"; //$NON-NLS-1$
+
+       // The shared instance.
+       private static XMLPlugin plugin;
+
+       // Resource bundle.
+       private ResourceBundle resources;
+
+       private XMLTextTools xmlTextTools;
+
+       private DTDTextTools dtdTextTools;
+
+       /**
+        * The constructor.
+        */
+       public XMLPlugin() {
+               plugin = this;
+
+               try {
+                       resources = ResourceBundle
+                                       .getBundle("net.sourceforge.phpeclipse.xml.ui.XMLPluginResources"); //$NON-NLS-1$
+               } catch (MissingResourceException x) {
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+        */
+       public void stop(BundleContext context) throws Exception {
+               try {
+                       if (xmlTextTools != null) {
+                               xmlTextTools.dispose();
+                               xmlTextTools = null;
+                       }
+
+                       if (dtdTextTools != null) {
+                               dtdTextTools.dispose();
+                               dtdTextTools = null;
+                       }
+               } finally {
+                       super.stop(context);
+               }
+       }
+
+       /**
+        * Returns the shared instance.
+        */
+       public static XMLPlugin getDefault() {
+               return plugin;
+       }
+
+       /**
+        * Returns the string from the plugin's resource bundle, or 'key' if not
+        * found.
+        */
+       public static String getResourceString(String key) {
+               ResourceBundle bundle = XMLPlugin.getDefault().getResourceBundle();
+               try {
+                       return bundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return key;
+               }
+       }
+
+       /**
+        * Returns the plugin's resource bundle.
+        */
+       public ResourceBundle getResourceBundle() {
+               return resources;
+       }
+
+       /**
+        * Returns instance of text tools for XML.
+        */
+       public XMLTextTools getXMLTextTools() {
+               if (xmlTextTools == null) {
+                       xmlTextTools = new XMLTextTools(getPreferenceStore());
+               }
+               return xmlTextTools;
+       }
+
+       /**
+        * Returns instance of text tools for DTD.
+        */
+       public DTDTextTools getDTDTextTools() {
+               if (dtdTextTools == null) {
+                       dtdTextTools = new DTDTextTools(getPreferenceStore());
+               }
+               return dtdTextTools;
+       }
+
+       /*
+        * @see AbstractUIPlugin#initializeImageRegistry(ImageRegistry)
+        */
+       protected void initializeImageRegistry(ImageRegistry reg) {
+               reg.put(ICON_ELEMENT, getImageDescriptor(ICON_ELEMENT));
+       }
+
+       /**
+        * Returns an image descriptor for the image corresponding to the specified
+        * key (which is the name of the image file).
+        * 
+        * @param key
+        *            The key of the image
+        * @return The descriptor for the requested image, or <code>null</code> if
+        *         the image could not be found
+        */
+       private ImageDescriptor getImageDescriptor(String key) {
+               try {
+                       URL url = getBundle().getEntry("/icons/" + key); //$NON-NLS-1$
+                       return ImageDescriptor.createFromURL(url);
+               } catch (IllegalStateException e) {
+                       return null;
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPluginResources.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPluginResources.properties
new file mode 100644 (file)
index 0000000..3b08588
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2003 Christopher Lenz and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     Igor Malinin - initial english resources
+# 
+# $Id: XMLPluginResources.properties,v 1.1 2004-09-02 18:28:04 jsurfer Exp $
+#
+
+####
+# XML Syntax Highlighting Preferences
+####
+
+XmlSyntaxPreferencePage.others=Others
+XmlSyntaxPreferencePage.PI=Precessing Instruction
+XmlSyntaxPreferencePage.Declaration=Declaration
+XmlSyntaxPreferencePage.Comment=Comment
+XmlSyntaxPreferencePage.Tag=Tag Name
+XmlSyntaxPreferencePage.AttName=Attribute Name
+XmlSyntaxPreferencePage.AttValue=Attribute Value
+XmlSyntaxPreferencePage.Entity=XML Entity
+XmlSyntaxPreferencePage.CDATA=CDATA Section
+XmlSyntaxPreferencePage.SmartyTag=Smarty Tag Name
+XmlSyntaxPreferencePage.Conditional=Conditional Section
+
+
+XmlSyntaxPreferencePage.description=XML Syntax Colors
+XmlSyntaxPreferencePage.backgroundColor=Background Color
+XmlSyntaxPreferencePage.systemDefault=System Default
+XmlSyntaxPreferencePage.custom=Custom
+XmlSyntaxPreferencePage.foreground=Foreground
+XmlSyntaxPreferencePage.color=Color
+XmlSyntaxPreferencePage.bold=Bold
+XmlSyntaxPreferencePage.italic=Italic
+XmlSyntaxPreferencePage.preview=Preview
+
+DTDMergeViewer.title=DTD Source Compare
+XMLMergeViewer.title=XML Source Compare
+
+## Actions ##
+
+ContentAssistProposal.label=Content Assist@Ctrl+SPACE
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist
+
+CompletionProcessor.ContextInfo.display.pattern=proposal {0} at position {1}
+CompletionProcessor.ContextInfo.value.pattern=proposal {0} valid from {1} to {2}
+CompletionProcessor.Proposal.ContextInfo.pattern={0} valid 5 characters around insertion point
+CompletionProcessor.Proposal.hoverinfo.pattern=Java keyword: {0}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewer.java
new file mode 100644 (file)
index 0000000..a833e92
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDMergeViewer.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.compare;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DTDConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.text.DTDTextTools;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+/**
+ * @author Igor Malinin
+ */
+public class DTDMergeViewer extends TextMergeViewer {
+
+       /**
+        * The preference store.
+        */
+       private IPreferenceStore preferenceStore;
+
+       /**
+        * The listener for changes to the preference store.
+        */
+       private IPropertyChangeListener propertyChangeListener;
+
+       /**
+        * The DTD text tools.
+        */
+       private DTDTextTools textTools;
+
+       /*
+        * @see TextMergeViewer#TextMergeViewer(Composite, int,
+        *      CompareConfiguration)
+        */
+       public DTDMergeViewer(Composite parent, int style,
+                       CompareConfiguration configuration) {
+               super(parent, style, configuration);
+       }
+
+       // TextMergeViewer Implementation ------------------------------------------
+
+       /*
+        * @see TextMergeViewer#configureTextViewer()
+        */
+       protected void configureTextViewer(TextViewer textViewer) {
+               XMLPlugin plugin = XMLPlugin.getDefault();
+
+               preferenceStore = plugin.getPreferenceStore();
+               if (preferenceStore != null) {
+                       propertyChangeListener = new IPropertyChangeListener() {
+                               public void propertyChange(PropertyChangeEvent event) {
+                                       handlePreferenceStoreChanged(event);
+                               }
+                       };
+                       preferenceStore.addPropertyChangeListener(propertyChangeListener);
+               }
+
+               textTools = plugin.getDTDTextTools();
+
+               if (textViewer instanceof SourceViewer) {
+                       SourceViewer sourceViewer = (SourceViewer) textViewer;
+                       sourceViewer.configure(new DTDConfiguration(textTools));
+               }
+
+               updateBackgroundColor();
+       }
+
+       /*
+        * @see TextMergeViewer#getDocumentPartitioner()
+        */
+       protected IDocumentPartitioner getDocumentPartitioner() {
+               return textTools.createDTDPartitioner();
+       }
+
+       /*
+        * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getTitle()
+        */
+       public String getTitle() {
+               return XMLPlugin.getResourceString("DTDMergeViewer.title"); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.ContentViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+        */
+       protected void handleDispose(DisposeEvent event) {
+               if (propertyChangeListener != null) {
+                       if (preferenceStore != null) {
+                               preferenceStore
+                                               .removePropertyChangeListener(propertyChangeListener);
+                       }
+
+                       propertyChangeListener = null;
+               }
+
+               super.handleDispose(event);
+       }
+
+       protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+               String p = event.getProperty();
+
+               if (p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND)
+                               || p
+                                               .equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+                       updateBackgroundColor();
+               } else if (textTools.affectsBehavior(event)) {
+                       invalidateTextPresentation();
+               }
+       }
+
+       private void updateBackgroundColor() {
+               boolean defaultBackgroundColor = preferenceStore
+                               .getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT);
+
+               if (defaultBackgroundColor) {
+                       setBackgroundColor(null);
+               } else {
+                       RGB backgroundColor = PreferenceConverter.getColor(preferenceStore,
+                                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
+                       setBackgroundColor(backgroundColor);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewerCreator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewerCreator.java
new file mode 100644 (file)
index 0000000..6eeb9fc
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDMergeViewerCreator.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.compare;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.IViewerCreator;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Igor Malinin
+ */
+public class DTDMergeViewerCreator implements IViewerCreator {
+
+       /*
+        * @see IViewerCreator#createViewer(Composite, CompareConfiguration)
+        */
+       public Viewer createViewer(Composite parent, CompareConfiguration config) {
+               return new DTDMergeViewer(parent, SWT.NULL, config);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewer.java
new file mode 100644 (file)
index 0000000..7947a8e
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLMergeViewer.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.compare;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLMergeViewer extends TextMergeViewer {
+
+       /**
+        * The preference store.
+        */
+       private IPreferenceStore preferenceStore;
+
+       /**
+        * The listener for changes to the preference store.
+        */
+       private IPropertyChangeListener propertyChangeListener;
+
+       /**
+        * The XML text tools.
+        */
+       private XMLTextTools textTools;
+
+       /*
+        * @see TextMergeViewer#TextMergeViewer(Composite, int,
+        *      CompareConfiguration)
+        */
+       public XMLMergeViewer(Composite parent, int style,
+                       CompareConfiguration configuration) {
+               super(parent, style, configuration);
+       }
+
+       // TextMergeViewer Implementation
+       // ------------------------------------------
+
+       /*
+        * @see TextMergeViewer#configureTextViewer()
+        */
+       protected void configureTextViewer(TextViewer textViewer) {
+               XMLPlugin plugin = XMLPlugin.getDefault();
+
+               preferenceStore = plugin.getPreferenceStore();
+               if (preferenceStore != null) {
+                       propertyChangeListener = new IPropertyChangeListener() {
+                               public void propertyChange(PropertyChangeEvent event) {
+                                       handlePreferenceStoreChanged(event);
+                               }
+                       };
+                       preferenceStore.addPropertyChangeListener(propertyChangeListener);
+               }
+
+               textTools = plugin.getXMLTextTools();
+
+               if (textViewer instanceof SourceViewer) {
+                       SourceViewer sourceViewer = (SourceViewer) textViewer;
+                       sourceViewer.configure(new XMLConfiguration(textTools));
+               }
+
+               updateBackgroundColor();
+       }
+
+       /*
+        * @see TextMergeViewer#getDocumentPartitioner()
+        */
+       protected IDocumentPartitioner getDocumentPartitioner() {
+               return textTools.createXMLPartitioner();
+       }
+
+       /*
+        * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getTitle()
+        */
+       public String getTitle() {
+               return XMLPlugin.getResourceString("XMLMergeViewer.title"); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.ContentViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+        */
+       protected void handleDispose(DisposeEvent event) {
+               if (propertyChangeListener != null) {
+                       if (preferenceStore != null) {
+                               preferenceStore
+                                               .removePropertyChangeListener(propertyChangeListener);
+                       }
+
+                       propertyChangeListener = null;
+               }
+
+               super.handleDispose(event);
+       }
+
+       protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+               String p = event.getProperty();
+
+               if (p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND)
+                               || p
+                                               .equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+                       updateBackgroundColor();
+               } else if (textTools.affectsBehavior(event)) {
+                       invalidateTextPresentation();
+               }
+       }
+
+       private void updateBackgroundColor() {
+               boolean defaultBackgroundColor = preferenceStore
+                               .getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT);
+
+               if (defaultBackgroundColor) {
+                       setBackgroundColor(null);
+               } else {
+                       RGB backgroundColor = PreferenceConverter.getColor(preferenceStore,
+                                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
+                       setBackgroundColor(backgroundColor);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewerCreator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewerCreator.java
new file mode 100644 (file)
index 0000000..60f84c0
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLMergeViewerCreator.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.compare;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.IViewerCreator;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLMergeViewerCreator implements IViewerCreator {
+
+       /*
+        * @see IViewerCreator#createViewer(Composite, CompareConfiguration)
+        */
+       public Viewer createViewer(Composite parent, CompareConfiguration config) {
+               return new XMLMergeViewer(parent, SWT.NULL, config);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/DTDEditor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/DTDEditor.java
new file mode 100644 (file)
index 0000000..43f76d7
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDEditor.java,v 1.3 2006-10-21 23:14:14 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DTDConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DTDDocumentProvider;
+import net.sourceforge.phpeclipse.xml.ui.text.DTDTextTools;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+
+/**
+ * DTD Editor.
+ * 
+ * @author Igor Malinin
+ */
+public class DTDEditor extends TextEditor {
+
+       public DTDEditor() {
+               setPreferenceStore(XMLPlugin.getDefault().getPreferenceStore());
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
+        */
+       protected void initializeEditor() {
+               super.initializeEditor();
+
+               DTDTextTools dtdTextTools = XMLPlugin.getDefault().getDTDTextTools();
+
+               setSourceViewerConfiguration(new DTDConfiguration(dtdTextTools));
+
+               setDocumentProvider(new DTDDocumentProvider());
+       }
+
+       protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+               return XMLPlugin.getDefault().getDTDTextTools().affectsBehavior(event);
+       }
+
+       protected void createActions() {
+               super.createActions();
+
+               IAction action = new ContentAssistAction(XMLEditorMessages
+                               .getResourceBundle(), "ContentAssistProposal.", this); //$NON-NLS-1$
+               action
+                               .setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+               setAction("ContentAssistProposal", action); //$NON-NLS-1$
+               markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
+
+               // IAction action= new TextOperationAction(
+               // TemplateMessages.getResourceBundle(),
+               // "Editor." + TEMPLATE_PROPOSALS + ".", //$NON-NLS-1$ //$NON-NLS-2$
+               // this,
+               // ISourceViewer.CONTENTASSIST_PROPOSALS);
+               // action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+               // setAction(TEMPLATE_PROPOSALS, action);
+               // markAsStateDependentAction(TEMPLATE_PROPOSALS, true);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentProvider.java
new file mode 100644 (file)
index 0000000..999fd08
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLDocumentProvider.java,v 1.3 2006-10-21 23:14:14 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import java.net.MalformedURLException;
+
+import net.sourceforge.phpeclipse.xml.core.internal.model.XMLDocument;
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.ui.editors.text.TextFileDocumentProvider;
+
+/**
+ * Document provider for XML files.
+ * 
+ * TODO Merge the encoding detection support from I18NDocumentProvider and
+ * AbstractDocumentProvider into this class
+ * 
+ * TODO This class currently doubles as a model manager which will need to be
+ * moved into core at some point, and would make this class pretty much useless
+ */
+public class XMLDocumentProvider extends TextFileDocumentProvider {
+
+       // Inner Classes -----------------------------------------------------------
+
+       private class XMLFileInfo extends FileInfo {
+               IXMLDocument xmlDocument;
+       }
+
+       // TestFileDocumentProvider Implementation ---------------------------------
+
+       /*
+        * @see TextFileDocumentProvider#createEmptyFileInfo()
+        */
+       protected FileInfo createEmptyFileInfo() {
+               return new XMLFileInfo();
+       }
+
+       /*
+        * @see TextFileDocumentProvider#createFileInfo(Object)
+        */
+       protected FileInfo createFileInfo(Object element) throws CoreException {
+               FileInfo fileInfo = super.createFileInfo(element);
+               if (!(fileInfo instanceof XMLFileInfo)) {
+                       return null;
+               }
+
+               IDocument document = fileInfo.fTextFileBuffer.getDocument();
+
+               String systemId = null;
+               try {
+                       systemId = getSystemFile(fileInfo).toURL().toString();
+               } catch (MalformedURLException e) {
+               }
+
+               IXMLDocument xmlDocument = createModel(document, systemId);
+               if (xmlDocument instanceof IDocumentListener) {
+                       document.addDocumentListener((IDocumentListener) xmlDocument);
+               }
+
+               XMLFileInfo xmlFileInfo = (XMLFileInfo) fileInfo;
+               xmlFileInfo.xmlDocument = xmlDocument;
+
+               return xmlFileInfo;
+       }
+
+       /*
+        * @see TextFileDocumentProvider#disposeFileInfo(Object,
+        *      TextFileDocumentProvider.FileInfo)
+        */
+       protected void disposeFileInfo(Object element, FileInfo info) {
+               if (info instanceof XMLFileInfo) {
+                       IDocument document = getDocument(element);
+                       if (document != null) {
+                               IXMLDocument xmlDocument = ((XMLFileInfo) info).xmlDocument;
+                               if (xmlDocument instanceof IDocumentListener) {
+                                       document
+                                                       .removeDocumentListener((IDocumentListener) xmlDocument);
+                               }
+                       }
+               }
+
+               super.disposeFileInfo(element, info);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Creates the XML document model object corresponding to the specified
+        * document.
+        * 
+        * @param document
+        *            the document to parse
+        * @param systemId
+        *            the system ID of the document
+        * @return the document model object
+        */
+       public IXMLDocument createModel(IDocument document, String systemId) {
+               return new XMLDocument(document, systemId);
+       }
+
+       /**
+        * Returns the XML document model associated with the specified element.
+        * 
+        * @param element
+        *            the element
+        * @return the document model associated with the element
+        */
+       public IXMLDocument getModel(Object element) {
+               FileInfo info = getFileInfo(element);
+               if (info instanceof XMLFileInfo) {
+                       XMLFileInfo xmlFileInfo = (XMLFileInfo) info;
+                       return xmlFileInfo.xmlDocument;
+               }
+
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentSetupParticipant.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentSetupParticipant.java
new file mode 100644 (file)
index 0000000..40fa9a4
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial implementation
+ * 
+ * $Id: XMLDocumentSetupParticipant.java,v 1.3 2006-10-21 23:14:14 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+
+/**
+ * Document setup participant that sets up the CSS specific partitioning.
+ */
+public class XMLDocumentSetupParticipant implements IDocumentSetupParticipant {
+
+       /*
+        * @see IDocumentSetupParticipant#setup(IDocument)
+        */
+       public void setup(IDocument document) {
+               if (document != null) {
+                       XMLTextTools tools = XMLPlugin.getDefault().getXMLTextTools();
+                       IDocumentPartitioner partitioner = tools.createXMLPartitioner();
+                       partitioner.connect(document);
+                       document.setDocumentPartitioner(partitioner);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditor.java
new file mode 100644 (file)
index 0000000..bd096c2
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *     Christopher Lenz - integrated outline page
+ *
+ * $Id: XMLEditor.java,v 1.4 2006-10-21 23:14:14 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.ui.editor.ShowExternalPreviewAction;
+import net.sourceforge.phpeclipse.ui.text.IReconcilingParticipant;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.outline.XMLOutlinePage;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+/**
+ * XML Editor.
+ * 
+ * @author Igor Malinin
+ */
+public class XMLEditor extends TextEditor implements IReconcilingParticipant {
+
+       /**
+        * Listens to changes to the selection in the outline page, and changes the
+        * selection and highlight range in the editor accordingly.
+        */
+       private class OutlineSelectionChangedListener implements
+                       ISelectionChangedListener {
+
+               /*
+                * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
+                */
+               public void selectionChanged(SelectionChangedEvent event) {
+                       IStructuredSelection selection = (IStructuredSelection) event
+                                       .getSelection();
+                       if (selection.isEmpty()) {
+                               resetHighlightRange();
+                       } else {
+                               ISourceReference element = (ISourceReference) selection
+                                               .getFirstElement();
+                               highlightElement(element, true);
+                       }
+               }
+
+       }
+
+       /**
+        * The associated outline page.
+        */
+       XMLOutlinePage outlinePage;
+
+       int fType;
+
+       /**
+        * Listens to changes in the outline page's selection to update the editor
+        * selection and highlight range.
+        */
+       private ISelectionChangedListener outlineSelectionChangedListener;
+
+       public XMLEditor() {
+               this(ShowExternalPreviewAction.XML_TYPE);
+       }
+
+       /**
+        * Constructor.
+        */
+       public XMLEditor(int type) {
+               fType = type;
+               List stores = new ArrayList(3);
+
+               stores.add(XMLPlugin.getDefault().getPreferenceStore());
+               stores.add(EditorsUI.getPreferenceStore());
+
+               setPreferenceStore(new ChainedPreferenceStore(
+                               (IPreferenceStore[]) stores.toArray(new IPreferenceStore[stores
+                                               .size()])));
+       }
+
+       /*
+        * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+        */
+       public Object getAdapter(Class adapter) {
+               if (adapter.equals(IContentOutlinePage.class)) {
+                       if (outlinePage == null) {
+                               outlinePage = new XMLOutlinePage(this);
+                               outlineSelectionChangedListener = new OutlineSelectionChangedListener();
+                               outlinePage
+                                               .addSelectionChangedListener(outlineSelectionChangedListener);
+                       }
+
+                       return outlinePage;
+               }
+
+               return super.getAdapter(adapter);
+       }
+
+       /*
+        * @see IReconcilingParticipant#reconciled()
+        */
+       public void reconciled() {
+               Shell shell = getSite().getShell();
+               if ((shell != null) && !shell.isDisposed()) {
+                       shell.getDisplay().asyncExec(new Runnable() {
+                               public void run() {
+                                       if (outlinePage != null) {
+                                               outlinePage.update();
+                                       }
+                               }
+                       });
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
+        */
+       protected void initializeEditor() {
+               super.initializeEditor();
+
+               XMLTextTools xmlTextTools = XMLPlugin.getDefault().getXMLTextTools();
+               setSourceViewerConfiguration(new XMLConfiguration(xmlTextTools, this));
+               setDocumentProvider(new XMLDocumentProvider());
+
+               ShowExternalPreviewAction fShowExternalPreviewAction = ShowExternalPreviewAction
+                               .getInstance();
+               fShowExternalPreviewAction.setEditor(this);
+               fShowExternalPreviewAction.update();
+               if (fShowExternalPreviewAction != null)
+                       fShowExternalPreviewAction.doRun(fType);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
+        */
+       protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+               return XMLPlugin.getDefault().getXMLTextTools().affectsBehavior(event);
+       }
+
+       void highlightElement(ISourceReference element, boolean moveCursor) {
+               if (element != null) {
+                       IRegion highlightRegion = element.getSourceRegion();
+                       setHighlightRange(highlightRegion.getOffset(), highlightRegion
+                                       .getLength(), moveCursor);
+               } else {
+                       resetHighlightRange();
+               }
+       }
+
+       protected void createActions() {
+               super.createActions();
+
+               IAction action = new ContentAssistAction(XMLEditorMessages
+                               .getResourceBundle(), "ContentAssistProposal.", this); //$NON-NLS-1$
+               action
+                               .setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+               setAction("ContentAssistProposal", action); //$NON-NLS-1$
+               markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
+
+               // IAction action= new TextOperationAction(
+               // TemplateMessages.getResourceBundle(),
+               // "Editor." + TEMPLATE_PROPOSALS + ".", //$NON-NLS-1$ //$NON-NLS-2$
+               // this,
+               // ISourceViewer.CONTENTASSIST_PROPOSALS);
+               // action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+               // setAction(TEMPLATE_PROPOSALS, action);
+               // markAsStateDependentAction(TEMPLATE_PROPOSALS, true);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorSaved()
+        */
+       protected void editorSaved() {
+               super.editorSaved();
+               ShowExternalPreviewAction a = ShowExternalPreviewAction.getInstance();
+               if (a != null) {
+                       a.refresh(fType);
+               }
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorActionContributor.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorActionContributor.java
new file mode 100644 (file)
index 0000000..8d65d7c
--- /dev/null
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import net.sourceforge.phpeclipse.ui.editor.ShowExternalPreviewAction;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.texteditor.BasicTextEditorActionContributor;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Common base class for action contributors for Java editors.
+ */
+public class XMLEditorActionContributor extends
+               BasicTextEditorActionContributor {
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.ui.IEditorActionBarContributor#setActiveEditor(org.eclipse.ui.IEditorPart)
+        */
+       public void setActiveEditor(IEditorPart part) {
+               super.setActiveEditor(part);
+               ITextEditor textEditor = null;
+               if (part instanceof ITextEditor)
+                       textEditor = (ITextEditor) part;
+
+               if (textEditor != null) {
+                       IFile file = null;
+                       IEditorInput editorInput = textEditor.getEditorInput();
+
+                       if (editorInput instanceof IFileEditorInput) {
+                               file = ((IFileEditorInput) editorInput).getFile();
+                       }
+
+                       ShowExternalPreviewAction fShowExternalPreviewAction = ShowExternalPreviewAction
+                                       .getInstance();
+                       fShowExternalPreviewAction.setEditor(textEditor);
+                       fShowExternalPreviewAction.update();
+                       if (fShowExternalPreviewAction != null)
+                               fShowExternalPreviewAction
+                                               .doRun(ShowExternalPreviewAction.PHP_TYPE);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.java
new file mode 100644 (file)
index 0000000..906e74b
--- /dev/null
@@ -0,0 +1,46 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class XMLEditorMessages {
+
+       private static final String RESOURCE_BUNDLE = "net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLEditorMessages";//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle = ResourceBundle
+                       .getBundle(RESOURCE_BUNDLE);
+
+       private XMLEditorMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+
+       public static ResourceBundle getResourceBundle() {
+               return fgResourceBundle;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.properties b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.properties
new file mode 100644 (file)
index 0000000..bea66ef
--- /dev/null
@@ -0,0 +1,10 @@
+#############################################################
+#
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+#
+#############################################################
+ContentAssistProposal.label=Content Assist@Ctrl+SPACE
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineContentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineContentProvider.java
new file mode 100644 (file)
index 0000000..4484e94
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLOutlineContentProvider.java,v 1.3 2006-10-21 23:14:14 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.outline;
+
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+import net.sourceforge.phpeclipse.xml.core.model.IXMLElement;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content provider for the XML outline page.
+ */
+public class XMLOutlineContentProvider implements ITreeContentProvider {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The parsed XML document.
+        */
+       private IXMLDocument document;
+
+       // ITreeContentProvider Implementation -------------------------------------
+
+       /*
+        * ITreeContentProvider#getChildren(Object)
+        */
+       public Object[] getChildren(Object parentElement) {
+               if (parentElement instanceof IXMLElement) {
+                       return ((IXMLElement) parentElement).getChildren();
+               }
+               return new Object[0];
+       }
+
+       /*
+        * @see ITreeContentProvider#getParent(Object)
+        */
+       public Object getParent(Object element) {
+               if (element instanceof IXMLElement) {
+                       return ((IXMLElement) element).getParent();
+               }
+               return null;
+       }
+
+       /*
+        * @see ITreeContentProvider#hasChildren(Object)
+        */
+       public boolean hasChildren(Object element) {
+               return getChildren(element).length > 0;
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
+        */
+       public Object[] getElements(Object inputElement) {
+               if ((document != null) && (document.getRoot() != null)) {
+                       return new Object[] { document.getRoot() };
+               }
+               return new Object[0];
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+        */
+       public void dispose() {
+               document = null;
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer,
+        *      Object, Object)
+        */
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               if (oldInput != newInput) {
+                       if (oldInput instanceof IXMLDocument) {
+                               document = null;
+                       }
+                       if (newInput instanceof IXMLDocument) {
+                               document = (IXMLDocument) newInput;
+                       }
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineLabelProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineLabelProvider.java
new file mode 100644 (file)
index 0000000..38fd25c
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLOutlineLabelProvider.java,v 1.3 2006-10-21 23:14:14 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.outline;
+
+import net.sourceforge.phpeclipse.xml.core.model.IXMLElement;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Label provider for the XML outline page.
+ */
+public class XMLOutlineLabelProvider extends LabelProvider {
+
+       // LabelProvider Implementation --------------------------------------------
+
+       /**
+        * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+        */
+       public Image getImage(Object element) {
+               if (element instanceof IXMLElement) {
+                       return XMLPlugin.getDefault().getImageRegistry().get(
+                                       XMLPlugin.ICON_ELEMENT);
+               }
+               return null;
+       }
+
+       /**
+        * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+        */
+       public String getText(Object element) {
+               if (element instanceof IXMLElement) {
+                       IXMLElement xmlElement = (IXMLElement) element;
+                       StringBuffer buf = new StringBuffer();
+                       if (xmlElement.getPrefix() != null) {
+                               buf.append(xmlElement.getPrefix());
+                               buf.append(':');
+                       }
+                       buf.append(xmlElement.getLocalName());
+                       return buf.toString();
+               }
+               return null;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlinePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlinePage.java
new file mode 100644 (file)
index 0000000..0daae7d
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLOutlinePage.java,v 1.3 2006-10-21 23:14:14 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.outline;
+
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.ui.views.outline.ProblemsLabelDecorator;
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider;
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLEditor;
+
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+
+/**
+ * Implements the outline page associated with the XML editor.
+ */
+public class XMLOutlinePage extends ContentOutlinePage {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated editor.
+        */
+       private XMLEditor editor;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param editor
+        *            The associated text editor
+        */
+       public XMLOutlinePage(XMLEditor editor) {
+               this.editor = editor;
+       }
+
+       // ContentOutlinePage Implementation ---------------------------------------
+
+       /*
+        * @see org.eclipse.ui.part.IPage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               TreeViewer viewer = getTreeViewer();
+               viewer.setContentProvider(new XMLOutlineContentProvider());
+               viewer.setLabelProvider(new DecoratingLabelProvider(
+                               new XMLOutlineLabelProvider(), new ProblemsLabelDecorator(
+                                               editor)));
+               viewer.setInput(getDocument());
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Selects a specific element in the outline page.
+        * 
+        * @param element
+        *            the element to select
+        */
+       public void select(ISourceReference element) {
+               TreeViewer viewer = getTreeViewer();
+               if (viewer != null) {
+                       ISelection selection = viewer.getSelection();
+                       if (selection instanceof IStructuredSelection) {
+                               IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+                               List elements = structuredSelection.toList();
+                               if (!elements.contains(element)) {
+                                       if (element == null) {
+                                               selection = StructuredSelection.EMPTY;
+                                       } else {
+                                               selection = new StructuredSelection(element);
+                                       }
+                                       viewer.setSelection(selection, true);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Updates the outline page.
+        */
+       public void update() {
+               IXMLDocument document = getDocument();
+               if (document != null) {
+                       TreeViewer viewer = getTreeViewer();
+                       if (viewer != null) {
+                               Control control = viewer.getControl();
+                               if ((control != null) && !control.isDisposed()) {
+                                       control.setRedraw(false);
+                                       viewer.setInput(document);
+                                       viewer.expandAll();
+                                       control.setRedraw(true);
+                               }
+                       }
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the parsed model of the XML document that is loaded into the
+        * associated editor.
+        * 
+        * @return the parsed XML document
+        */
+       private IXMLDocument getDocument() {
+               IDocumentProvider provider = editor.getDocumentProvider();
+               if (provider instanceof XMLDocumentProvider) {
+                       XMLDocumentProvider xmlProvider = (XMLDocumentProvider) provider;
+                       return xmlProvider.getModel(editor.getEditorInput());
+               }
+               return null;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/ContentAssistPreference.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/ContentAssistPreference.java
new file mode 100644 (file)
index 0000000..25b27d1
--- /dev/null
@@ -0,0 +1,65 @@
+package net.sourceforge.phpeclipse.xml.ui.internal.preferences;
+
+import net.sourceforge.phpeclipse.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.ui.templates.template.BasicCompletionProcessor;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+
+public class ContentAssistPreference {
+       /** Preference key for html content assist auto activation triggers */
+       private final static String AUTOACTIVATION_TRIGGERS_HTML = PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_HTML;
+
+       /** Preference key for alphabetic ordering of proposals */
+       private final static String ORDER_PROPOSALS = PreferenceConstants.CODEASSIST_ORDER_PROPOSALS;
+
+       private static BasicCompletionProcessor getHTMLProcessor(
+                       ContentAssistant assistant) {
+               IContentAssistProcessor p = assistant
+                               .getContentAssistProcessor(XMLPartitionScanner.XML_TAG);
+               if (p instanceof BasicCompletionProcessor)
+                       return (BasicCompletionProcessor) p;
+               return null;
+       }
+
+       private static void configureHTMLProcessor(ContentAssistant assistant,
+                       IPreferenceStore store) {
+               BasicCompletionProcessor hcp = getHTMLProcessor(assistant);
+               if (hcp == null)
+                       return;
+
+               String triggers = store.getString(AUTOACTIVATION_TRIGGERS_HTML);
+               if (triggers != null)
+                       hcp.setCompletionProposalAutoActivationCharacters(triggers
+                                       .toCharArray());
+
+               boolean enabled;
+               // boolean enabled = store.getBoolean(CASE_SENSITIVITY);
+               // jdcp.restrictProposalsToMatchingCases(enabled);
+
+               enabled = store.getBoolean(ORDER_PROPOSALS);
+               // hcp.orderProposalsAlphabetically(enabled);
+       }
+
+       private static void changeHTMLProcessor(ContentAssistant assistant,
+                       IPreferenceStore store, String key) {
+               BasicCompletionProcessor jdcp = getHTMLProcessor(assistant);
+               if (jdcp == null)
+                       return;
+
+               if (AUTOACTIVATION_TRIGGERS_HTML.equals(key)) {
+                       String triggers = store.getString(AUTOACTIVATION_TRIGGERS_HTML);
+                       if (triggers != null)
+                               jdcp.setCompletionProposalAutoActivationCharacters(triggers
+                                               .toCharArray());
+                       // } else if (CASE_SENSITIVITY.equals(key)) {
+                       // boolean enabled = store.getBoolean(CASE_SENSITIVITY);
+                       // jdcp.restrictProposalsToMatchingCases(enabled);
+               } else if (ORDER_PROPOSALS.equals(key)) {
+                       boolean enable = store.getBoolean(ORDER_PROPOSALS);
+                       // jdcp.orderProposalsAlphabetically(enable);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLPreferenceInitializer.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLPreferenceInitializer.java
new file mode 100644 (file)
index 0000000..4b6aefb
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2002-2004 Roberto Gonzalez Rocha and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Roberto Gonzalez Rocha - Initial version
+ *     Igor Malinin - refactoring, minor changes
+ *
+ * $Id: XMLPreferenceInitializer.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.preferences;
+
+/*import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.PropertyResourceBundle;
+*/
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.ui.IPreferenceConstants;
+
+import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.preferences.ITextStylePreferences;
+//import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+//import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLPreferenceInitializer extends AbstractPreferenceInitializer implements IPreferenceConstants {
+       /*
+        * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+        */
+       public void initializeDefaultPreferences() {
+               final IPreferenceStore store = /*XMLPlugin*/WebUI.getDefault()
+                               .getPreferenceStore();
+               final Display display = Display.getDefault();
+
+               // TODO: ChainedPreferenceStore does not work for preferences preview
+
+               display.syncExec(new Runnable() {
+                       public void run() {
+                               PreferenceConverter.setDefault(store,
+                                               AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND, display
+                                                               .getSystemColor(SWT.COLOR_LIST_FOREGROUND)
+                                                               .getRGB());
+                       }
+               });
+
+               store.setDefault(
+                               AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT,
+                               true);
+
+               display.syncExec(new Runnable() {
+                       public void run() {
+                               PreferenceConverter.setDefault(store,
+                                               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, display
+                                                               .getSystemColor(SWT.COLOR_LIST_BACKGROUND)
+                                                               .getRGB());
+                       }
+               });
+
+               store.setDefault(
+                               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT,
+                               true);
+
+               // end of common preferences
+
+               setDefault(store, IXMLSyntaxConstants.XML_DEFAULT, "0,0,0",
+                               ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_TAG, "127,0,127",
+                               ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_ATT_NAME, "0,127,0",
+                               ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_ATT_VALUE, "0,0,255",
+                               ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_ENTITY, "127,127,0",
+                               ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_CDATA, "127,127,0",
+                               ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_PI, "127,127,127",
+                               ITextStylePreferences.STYLE_BOLD);
+
+               setDefault(store, IXMLSyntaxConstants.XML_COMMENT, "127,0,0",
+                               ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_DECL, "127,0,127",
+                               ITextStylePreferences.STYLE_BOLD);
+
+               setDefault(store, IXMLSyntaxConstants.XML_SMARTY, "255,0,127",
+                               ITextStylePreferences.STYLE_BOLD);
+
+               setDefault(store, IXMLSyntaxConstants.DTD_CONDITIONAL, "127,127,0",
+                               ITextStylePreferences.STYLE_BOLD);
+
+               String operatingSystem = Platform.getOS();
+               // maxosx, linux, solaris, win32,...
+               try {
+                       /*InputStream is = getDefault()
+                                       .openStream(
+                                                       new Path("prefs/default_" + operatingSystem
+                                                                       + ".properties"));
+                       PropertyResourceBundle resourceBundle = new PropertyResourceBundle(
+                                       is);
+                       Enumeration e = resourceBundle.getKeys();
+                       String key;
+                       while (e.hasMoreElements()) {
+                               key = (String) e.nextElement();
+                               store.setDefault(key, resourceBundle.getString(key));
+                       }*/
+               } catch (Exception e) {
+                       // no default properties found
+                       if (operatingSystem.equals(Platform.OS_WIN32)) {
+                               // store.setDefault(PHP_RUN_PREF, "c:\\apache\\php\\php.exe");
+                               // store.setDefault(EXTERNAL_PARSER_PREF, "c:\\apache\\php\\php
+                               // -l -f {0}");
+                               // store.setDefault(MYSQL_RUN_PREF,
+                               // "c:\\apache\\mysql\\bin\\mysqld-nt.exe");
+                               // store.setDefault(APACHE_RUN_PREF, "c:\\apache\\apache.exe");
+                               // store.setDefault(XAMPP_START_PREF,
+                               // "c:\\xampp\\xampp_start.exe");
+                               // store.setDefault(XAMPP_STOP_PREF,
+                               // "c:\\xampp\\xampp_stop.exe");
+                               // store.setDefault(
+                               // ETC_HOSTS_PATH_PREF,
+                               // "c:\\windows\\system32\\drivers\\etc\\hosts");
+                       } else {
+                               // store.setDefault(PHP_RUN_PREF, "/apache/php/php");
+                               // store.setDefault(EXTERNAL_PARSER_PREF, "/apache/php/php -l -f
+                               // {0}");
+                               // store.setDefault(MYSQL_RUN_PREF, "/apache/mysql/bin/mysqld");
+                               // store.setDefault(APACHE_RUN_PREF, "/apache/apache");
+                               // store.setDefault(XAMPP_START_PREF, "xamp/xampp_start");
+                               // store.setDefault(XAMPP_STOP_PREF, "xampp/xampp_stop");
+                       }
+                       // store.setDefault(MYSQL_PREF, "--standalone");
+                       // store.setDefault(APACHE_START_PREF, "-c \"DocumentRoot
+                       // \"{0}\"\"");
+                       // store.setDefault(APACHE_STOP_PREF, "-k shutdown");
+                       // store.setDefault(APACHE_RESTART_PREF, "-k restart");
+                       // store.setDefault(MYSQL_START_BACKGROUND, "true");
+                       // store.setDefault(APACHE_START_BACKGROUND, "true");
+                       // store.setDefault(APACHE_STOP_BACKGROUND, "true");
+                       // store.setDefault(APACHE_RESTART_BACKGROUND, "true");
+               }
+               store.setDefault(PHP_USERDEF_XMLFILE, "");
+               PreferenceConverter.setDefault(store, PHP_TAG, PHPColorProvider.TAG);
+               PreferenceConverter.setDefault(store, PHP_KEYWORD,
+                               PHPColorProvider.KEYWORD);
+               PreferenceConverter.setDefault(store, PHP_VARIABLE,
+                               PHPColorProvider.VARIABLE);
+               PreferenceConverter.setDefault(store, PHP_VARIABLE_DOLLAR,
+                               PHPColorProvider.VARIABLE);
+               /*PreferenceConverter.setDefault(store, PHP_FUNCTIONNAME,
+                               PHPColorProvider.FUNCTION_NAME);*/
+
+               setDefault(store, PHP_FUNCTIONNAME, PHPColorProvider.FUNCTION_NAME,
+                               ITextStylePreferences.STYLE_BOLD);
+               
+               PreferenceConverter.setDefault(store, PHP_CONSTANT,
+                               PHPColorProvider.CONSTANT);
+               PreferenceConverter.setDefault(store, PHP_TYPE, PHPColorProvider.TYPE);
+               PreferenceConverter.setDefault(store, PHP_DEFAULT,
+                               PHPColorProvider.DEFAULT);
+               PreferenceConverter.setDefault(store, PHPDOC_KEYWORD,
+                               PHPColorProvider.PHPDOC_KEYWORD);
+               
+               PreferenceConverter.setDefault(store, PHPDOC_TAG,
+                               PHPColorProvider.PHPDOC_TAG);
+               PreferenceConverter.setDefault(store, PHPDOC_LINK,
+                               PHPColorProvider.PHPDOC_LINK);
+               PreferenceConverter.setDefault(store, PHPDOC_DEFAULT,
+                               PHPColorProvider.PHPDOC_DEFAULT);
+
+               PreferenceConverter.setDefault(store, EDITOR_PHP_KEYWORD_RETURN_COLOR,
+                               new RGB(127, 0, 85));
+               store.setDefault(EDITOR_PHP_KEYWORD_RETURN_BOLD, true);
+               store.setDefault(EDITOR_PHP_KEYWORD_RETURN_ITALIC, false);
+
+               PreferenceConverter.setDefault(store, EDITOR_PHP_OPERATOR_COLOR,
+                               new RGB(0, 0, 0));
+               store.setDefault(EDITOR_PHP_OPERATOR_BOLD, false);
+               store.setDefault(EDITOR_PHP_OPERATOR_ITALIC, false);
+
+               PreferenceConverter.setDefault(store, EDITOR_PHP_BRACE_OPERATOR_COLOR,
+                               new RGB(0, 0, 0));
+               store.setDefault(EDITOR_PHP_BRACE_OPERATOR_BOLD, false);
+               store.setDefault(EDITOR_PHP_BRACE_OPERATOR_ITALIC, false);
+
+               
+               PreferenceConverter.setDefault(store, EDITOR_PHP_KEYWORD_RETURN_COLOR,
+                               new RGB(127, 0, 85));
+               store.setDefault(EDITOR_PHP_KEYWORD_RETURN_BOLD, true);
+               store.setDefault(EDITOR_PHP_KEYWORD_RETURN_ITALIC, false);
+
+               PreferenceConverter.setDefault(store, EDITOR_PHP_OPERATOR_COLOR,
+                               new RGB(0, 0, 0));
+               store.setDefault(EDITOR_PHP_OPERATOR_BOLD, false);
+               store.setDefault(EDITOR_PHP_OPERATOR_ITALIC, false);
+
+               PreferenceConverter.setDefault(store, EDITOR_PHP_BRACE_OPERATOR_COLOR,
+                               new RGB(0, 0, 0));
+               store.setDefault(EDITOR_PHP_BRACE_OPERATOR_BOLD, false);
+               store.setDefault(EDITOR_PHP_BRACE_OPERATOR_ITALIC, false);
+
+               // this will initialize the static fields in the syntaxrdr class
+               new PHPSyntaxRdr();
+               JavaCore.initializeDefaultPluginPreferences();
+               PreferenceConstants.initializeDefaultValues(store);
+       }
+
+       private static void setDefault(IPreferenceStore store, String constant,
+                       String color, String style) {
+               store.setDefault(constant + ITextStylePreferences.SUFFIX_FOREGROUND,
+                               color);
+               store.setDefault(constant + ITextStylePreferences.SUFFIX_STYLE, style);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLSyntaxPreferencePage.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLSyntaxPreferencePage.java
new file mode 100644 (file)
index 0000000..e855df2
--- /dev/null
@@ -0,0 +1,587 @@
+/*
+ * Copyright (c) 2002-2004 Roberto Gonzalez Rocha and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Roberto Gonzalez Rocha - Initial version
+ *     Igor Malinin - refactoring, minor changes
+ *
+ * $Id: XMLSyntaxPreferencePage.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.preferences;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import net.sourceforge.phpeclipse.ui.ColorEditor;
+import net.sourceforge.phpeclipse.ui.preferences.ITextStylePreferences;
+import net.sourceforge.phpeclipse.ui.preferences.OverlayPreferenceStore;
+import net.sourceforge.phpeclipse.ui.preferences.PreferenceDescriptor;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+/**
+ * The XMLSyntaxPreferencePage is a preference page that handles setting the
+ * colors used by the XML editors.
+ */
+public class XMLSyntaxPreferencePage extends PreferencePage implements
+               IWorkbenchPreferencePage {
+
+       public final PreferenceDescriptor[] fKeys = new PreferenceDescriptor[] {
+                       new PreferenceDescriptor(
+                                       PreferenceDescriptor.BOOLEAN,
+                                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_DEFAULT
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_DEFAULT
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_TAG
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_TAG
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_ATT_NAME
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_ATT_NAME
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_ATT_VALUE
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_ATT_VALUE
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_ENTITY
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_ENTITY
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_CDATA
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_CDATA
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_PI
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_PI
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_COMMENT
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_COMMENT
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_DECL
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_DECL
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_SMARTY
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.XML_SMARTY
+                                                       + ITextStylePreferences.SUFFIX_STYLE),
+
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.DTD_CONDITIONAL
+                                                       + ITextStylePreferences.SUFFIX_FOREGROUND),
+                       new PreferenceDescriptor(PreferenceDescriptor.STRING,
+                                       IXMLSyntaxConstants.DTD_CONDITIONAL
+                                                       + ITextStylePreferences.SUFFIX_STYLE), };
+
+       OverlayPreferenceStore overlay;
+
+       final String[][] fSyntaxColorListModel = new String[][] {
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.others"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_DEFAULT },
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.Tag"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_TAG },
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.AttName"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_ATT_NAME },
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.AttValue"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_ATT_VALUE },
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.Entity"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_ENTITY },
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.CDATA"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_CDATA },
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.PI"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_PI },
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.Comment"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_COMMENT },
+                       {
+                                       XMLPlugin
+                                                       .getResourceString("XmlSyntaxPreferencePage.Declaration"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_DECL },
+                       {
+                                       XMLPlugin
+                                                       .getResourceString("XmlSyntaxPreferencePage.Conditional"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.XML_SMARTY },
+                       { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.SmartyTag"), //$NON-NLS-1$
+                                       IXMLSyntaxConstants.DTD_CONDITIONAL }, };
+
+       private XMLTextTools xmlTextTools;
+
+       private Color bgColor;
+
+       Button bgDefault;
+
+       Button bgCustom;
+
+       ColorEditor bgColorEditor;
+
+       List colors;
+
+       ColorEditor fgColorEditor;
+
+       Button fgBold;
+
+       SourceViewer preview;
+
+       /**
+        * Constructor for XMLSyntaxPreferencePage.
+        */
+       public XMLSyntaxPreferencePage() {
+               setDescription(XMLPlugin
+                               .getResourceString("XmlSyntaxPreferencePage.description")); //$NON-NLS-1$
+
+               setPreferenceStore(XMLPlugin.getDefault().getPreferenceStore());
+
+               overlay = new OverlayPreferenceStore(getPreferenceStore(), fKeys);
+       }
+
+       protected Control createContents(Composite parent) {
+               overlay.load();
+               overlay.start();
+
+               Composite colorComposite = new Composite(parent, SWT.NULL);
+               colorComposite.setLayout(new GridLayout());
+
+               Group backgroundComposite = new Group(colorComposite,
+                               SWT.SHADOW_ETCHED_IN);
+
+               backgroundComposite.setLayout(new RowLayout());
+               backgroundComposite.setText(XMLPlugin
+                               .getResourceString("XmlSyntaxPreferencePage.backgroundColor")); //$NON-NLS-1$
+
+               SelectionListener backgroundSelectionListener = new SelectionListener() {
+                       public void widgetSelected(SelectionEvent e) {
+                               boolean custom = bgCustom.getSelection();
+                               bgColorEditor.getButton().setEnabled(custom);
+                               overlay
+                                               .setValue(
+                                                               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT,
+                                                               !custom);
+                       }
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+               };
+
+               bgDefault = new Button(backgroundComposite, SWT.RADIO | SWT.LEFT);
+               bgDefault.setText(XMLPlugin
+                               .getResourceString("XmlSyntaxPreferencePage.systemDefault")); //$NON-NLS-1$
+               bgDefault.addSelectionListener(backgroundSelectionListener);
+
+               bgCustom = new Button(backgroundComposite, SWT.RADIO | SWT.LEFT);
+               bgCustom.setText(XMLPlugin
+                               .getResourceString("XmlSyntaxPreferencePage.custom")); //$NON-NLS-1$
+               bgCustom.addSelectionListener(backgroundSelectionListener);
+
+               bgColorEditor = new ColorEditor(backgroundComposite);
+
+               Label label = new Label(colorComposite, SWT.LEFT);
+               label.setText(XMLPlugin
+                               .getResourceString("XmlSyntaxPreferencePage.foreground")); //$NON-NLS-1$
+               label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               Composite editorComposite = new Composite(colorComposite, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               editorComposite.setLayout(layout);
+               GridData gd = new GridData(GridData.FILL_BOTH);
+               editorComposite.setLayoutData(gd);
+
+               colors = new List(editorComposite, SWT.SINGLE | SWT.V_SCROLL
+                               | SWT.BORDER);
+               gd = new GridData(GridData.FILL_BOTH);
+               gd.heightHint = convertHeightInCharsToPixels(5);
+               colors.setLayoutData(gd);
+
+               Composite stylesComposite = new Composite(editorComposite, SWT.NONE);
+               layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               stylesComposite.setLayout(layout);
+               stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+               label = new Label(stylesComposite, SWT.LEFT);
+               label.setText(XMLPlugin
+                               .getResourceString("XmlSyntaxPreferencePage.color")); //$NON-NLS-1$
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gd);
+
+               fgColorEditor = new ColorEditor(stylesComposite);
+
+               Button fgColorButton = fgColorEditor.getButton();
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalAlignment = GridData.BEGINNING;
+               fgColorButton.setLayoutData(gd);
+
+               label = new Label(stylesComposite, SWT.LEFT);
+               label.setText(XMLPlugin
+                               .getResourceString("XmlSyntaxPreferencePage.bold")); //$NON-NLS-1$
+               gd = new GridData();
+               gd.horizontalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gd);
+
+               fgBold = new Button(stylesComposite, SWT.CHECK);
+               gd = new GridData(GridData.FILL_HORIZONTAL);
+               gd.horizontalAlignment = GridData.BEGINNING;
+               fgBold.setLayoutData(gd);
+
+               label = new Label(colorComposite, SWT.LEFT);
+               label.setText(XMLPlugin
+                               .getResourceString("XmlSyntaxPreferencePage.preview")); //$NON-NLS-1$
+               label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               Control previewer = createPreviewer(colorComposite);
+               gd = new GridData(GridData.FILL_BOTH);
+               gd.widthHint = convertWidthInCharsToPixels(20);
+               gd.heightHint = convertHeightInCharsToPixels(5);
+               previewer.setLayoutData(gd);
+
+               colors.addSelectionListener(new SelectionListener() {
+
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               handleSyntaxColorListSelection();
+                       }
+               });
+
+               bgColorEditor.getButton().addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               PreferenceConverter.setValue(overlay,
+                                               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND,
+                                               bgColorEditor.getColorValue());
+                       }
+               });
+
+               fgColorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = colors.getSelectionIndex();
+
+                               String key = fSyntaxColorListModel[i][1];
+
+                               PreferenceConverter.setValue(overlay, key
+                                               + ITextStylePreferences.SUFFIX_FOREGROUND,
+                                               fgColorEditor.getColorValue());
+                       }
+               });
+
+               fgBold.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = colors.getSelectionIndex();
+
+                               String key = fSyntaxColorListModel[i][1];
+
+                               String value = (fgBold.getSelection()) ? ITextStylePreferences.STYLE_BOLD
+                                               : ITextStylePreferences.STYLE_NORMAL;
+
+                               overlay.setValue(key + ITextStylePreferences.SUFFIX_STYLE,
+                                               value);
+                       }
+               });
+
+               initialize();
+
+               return colorComposite;
+       }
+
+       private Control createPreviewer(Composite parent) {
+               xmlTextTools = new XMLTextTools(overlay); // REVISIT: DTD
+
+               preview = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL
+                               | SWT.BORDER);
+
+               preview.configure(new XMLConfiguration(xmlTextTools));
+               preview.getTextWidget().setFont(
+                               JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
+               preview.setEditable(false);
+
+               initializeViewerColors(preview);
+
+               String content = loadPreviewContentFromFile("preview.xml"); //$NON-NLS-1$
+               IDocument document = new Document(content);
+
+               // REVISIT: DTD
+               IDocumentPartitioner partitioner = xmlTextTools.createXMLPartitioner();
+
+               partitioner.connect(document);
+               document.setDocumentPartitioner(partitioner);
+
+               preview.setDocument(document);
+
+               overlay.addPropertyChangeListener(new IPropertyChangeListener() {
+                       public void propertyChange(PropertyChangeEvent event) {
+                               String p = event.getProperty();
+                               if (p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND)
+                                               || p
+                                                               .equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+                                       initializeViewerColors(preview);
+                               }
+
+                               preview.invalidateTextPresentation();
+                       }
+               });
+
+               return preview.getControl();
+       }
+
+       /**
+        * Initializes the given viewer's colors.
+        * 
+        * @param viewer
+        *            the viewer to be initialized
+        */
+       void initializeViewerColors(ISourceViewer viewer) {
+               if (overlay != null) {
+                       StyledText styledText = viewer.getTextWidget();
+
+                       // ---------- background color ----------------------
+                       Color color = null;
+                       if (!overlay
+                                       .getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+                               color = createColor(overlay,
+                                               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND,
+                                               styledText.getDisplay());
+                       }
+
+                       styledText.setBackground(color);
+
+                       if (bgColor != null) {
+                               bgColor.dispose();
+                       }
+
+                       bgColor = color;
+               }
+       }
+
+       /**
+        * Creates a color from the information stored in the given preference
+        * store. Returns <code>null</code> if there is no such information
+        * available.
+        */
+       private Color createColor(IPreferenceStore store, String key,
+                       Display display) {
+               RGB rgb = null;
+
+               if (store.contains(key)) {
+                       if (store.isDefault(key)) {
+                               rgb = PreferenceConverter.getDefaultColor(store, key);
+                       } else {
+                               rgb = PreferenceConverter.getColor(store, key);
+                       }
+
+                       if (rgb != null) {
+                               return new Color(display, rgb);
+                       }
+               }
+
+               return null;
+       }
+
+       void handleSyntaxColorListSelection() {
+               int i = colors.getSelectionIndex();
+
+               String key = fSyntaxColorListModel[i][1];
+
+               RGB rgb = PreferenceConverter.getColor(overlay, key
+                               + ITextStylePreferences.SUFFIX_FOREGROUND);
+
+               fgColorEditor.setColorValue(rgb);
+
+               // REVISIT
+               fgBold.setSelection(overlay.getString(
+                               key + ITextStylePreferences.SUFFIX_STYLE).indexOf(
+                               ITextStylePreferences.STYLE_BOLD) >= 0);
+       }
+
+       private String loadPreviewContentFromFile(String filename) {
+               StringBuffer string = new StringBuffer(512);
+
+               try {
+                       char[] buf = new char[512];
+                       BufferedReader reader = new BufferedReader(
+                                       new InputStreamReader(XMLSyntaxPreferencePage.class
+                                                       .getResourceAsStream(filename)));
+
+                       try {
+                               while (true) {
+                                       int n = reader.read(buf);
+                                       if (n < 0) {
+                                               break;
+                                       }
+
+                                       string.append(buf, 0, n);
+                               }
+                       } finally {
+                               reader.close();
+                       }
+               } catch (IOException e) {
+               }
+
+               return string.toString();
+       }
+
+       /**
+        * 
+        */
+       private void initialize() {
+               initializeFields();
+
+               for (int i = 0; i < fSyntaxColorListModel.length; i++) {
+                       colors.add(fSyntaxColorListModel[i][0]);
+               }
+
+               colors.getDisplay().asyncExec(new Runnable() {
+
+                       public void run() {
+                               colors.select(0);
+                               handleSyntaxColorListSelection();
+                       }
+               });
+       }
+
+       private void initializeFields() {
+               RGB rgb = PreferenceConverter.getColor(overlay,
+                               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
+               bgColorEditor.setColorValue(rgb);
+
+               boolean def = overlay
+                               .getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT);
+               bgDefault.setSelection(def);
+               bgCustom.setSelection(!def);
+               bgColorEditor.getButton().setEnabled(!def);
+       }
+
+       /*
+        * @see IWorkbenchPreferencePage#init(IWorkbench)
+        */
+       public void init(IWorkbench workbench) {
+       }
+
+       /*
+        * @see PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               overlay.loadDefaults();
+               // initializeFields();
+               handleSyntaxColorListSelection();
+
+               super.performDefaults();
+
+               preview.invalidateTextPresentation();
+       }
+
+       /*
+        * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               overlay.propagate();
+               XMLPlugin.getDefault().savePluginPreferences();
+
+               return true;
+       }
+
+       /*
+        * @see org.eclipse.jface.dialogs.IDialogPage#dispose()
+        */
+       public void dispose() {
+               if (xmlTextTools != null) {
+                       xmlTextTools.dispose();
+                       xmlTextTools = null;
+               }
+
+               if (overlay != null) {
+                       overlay.stop();
+                       overlay = null;
+               }
+
+               super.dispose();
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/preview.xml b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/preview.xml
new file mode 100644 (file)
index 0000000..2fc0edc
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE doc SYSTEM "doc.dtd" [
+       <!ELEMENT text (#PCDATA)>
+       <!ATTLIST text
+               xml:space (preserve) #FIXED 'preserve'
+               id        ID         #IMPLIED
+       >
+]>
+
+<!-- comment -->
+
+<doc>
+       <text id="name">
+               &lt;text&gt;
+               <![CDATA[<text>]]>
+       </text>
+</doc>
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AbstractDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AbstractDocumentProvider.java
new file mode 100644 (file)
index 0000000..10d4fee
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: AbstractDocumentProvider.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.sourceforge.phpeclipse.ui.editor.I18NDocumentProvider;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public abstract class AbstractDocumentProvider extends I18NDocumentProvider {
+       protected IWhitespaceDetector detector = new WhitespaceDetector();
+
+       /*
+        * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getDefaultEncoding()
+        */
+       public String getDefaultEncoding() {
+               return "UTF-8";
+       }
+
+       public String getDeclaredEncoding(InputStream in) throws IOException {
+               if (!in.markSupported()) {
+                       in = new BufferedInputStream(in, 512);
+               }
+
+               in.mark(512);
+               String encoding = super.getDeclaredEncoding(in);
+               if (encoding != null) {
+                       return encoding;
+               }
+
+               in.reset();
+
+               // check Prolog-Start <?xml
+               if (!skipXMLDecl(in)) {
+                       return null;
+               }
+
+               // detect 'encoding'
+               skipEncoding(in);
+
+               // read encoding
+               int delimiter;
+
+               while (true) {
+                       int ch = in.read();
+                       if (ch < 0) {
+                               return null;
+                       }
+
+                       if (detector.isWhitespace((char) ch)) {
+                               continue;
+                       }
+
+                       if (ch == '"' || ch == '\'') {
+                               delimiter = ch;
+                               break;
+                       }
+
+                       return null;
+               }
+
+               StringBuffer buf = new StringBuffer();
+
+               while (true) {
+                       int ch = in.read();
+                       if (ch < 0) {
+                               return null;
+                       }
+
+                       if (ch == delimiter) {
+                               break;
+                       }
+
+                       buf.append((char) ch);
+               }
+
+               return buf.toString();
+       }
+
+       private boolean skipXMLDecl(InputStream in) throws IOException {
+               int ch = in.read();
+               if (ch != '<') {
+                       return false;
+               }
+
+               ch = in.read();
+               if (ch != '?') {
+                       return false;
+               }
+
+               ch = in.read();
+               if (ch != 'x') {
+                       return false;
+               }
+
+               ch = in.read();
+               if (ch != 'm') {
+                       return false;
+               }
+
+               ch = in.read();
+               if (ch != 'l') {
+                       return false;
+               }
+
+               return true;
+       }
+
+       private boolean skipEncoding(InputStream in) throws IOException {
+               int ch = in.read();
+
+               boolean whitespace = false;
+
+               while (true) {
+                       if (ch < 0) {
+                               return false;
+                       }
+
+                       if (detector.isWhitespace((char) ch)) {
+                               ch = in.read();
+                               whitespace = true;
+                               continue;
+                       }
+
+                       if (ch == '?' || ch == '<') {
+                               return false;
+                       }
+
+                       if (ch != 'e') {
+                               ch = in.read();
+                               whitespace = false;
+                               continue;
+                       }
+
+                       if (!whitespace) {
+                               ch = in.read();
+                               continue;
+                       }
+
+                       if ((ch = in.read()) == 'n' && (ch = in.read()) == 'c'
+                                       && (ch = in.read()) == 'o' && (ch = in.read()) == 'd'
+                                       && (ch = in.read()) == 'i' && (ch = in.read()) == 'n'
+                                       && (ch = in.read()) == 'g') {
+                               break;
+                       }
+
+                       whitespace = false;
+               }
+
+               // '='
+               while (true) {
+                       ch = in.read();
+                       if (ch < 0) {
+                               return false;
+                       }
+
+                       if (detector.isWhitespace((char) ch)) {
+                               continue;
+                       }
+
+                       if (ch == '=') {
+                               break;
+                       }
+
+                       return false;
+               }
+
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AnnotationAdapter.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AnnotationAdapter.java
new file mode 100644 (file)
index 0000000..8f7139f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: AnnotationAdapter.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.IReconcileResult;
+import org.eclipse.jface.text.source.Annotation;
+
+/**
+ * Adapts a temporary or persistent annotation to a reconcile result.
+ */
+public abstract class AnnotationAdapter implements IReconcileResult {
+
+       /**
+        * Creates and returns the annotation adapted by this adapter.
+        * 
+        * @return an annotation (can be temporary or persistent)
+        */
+       public abstract Annotation createAnnotation();
+
+       /**
+        * The position of the annotation adapted by this adapter.
+        * 
+        * @return the position
+        */
+       public abstract Position getPosition();
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AttValueDoubleClickStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AttValueDoubleClickStrategy.java
new file mode 100644 (file)
index 0000000..2ce9fb1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: AttValueDoubleClickStrategy.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITypedRegion;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class AttValueDoubleClickStrategy extends TextDoubleClickStrategy {
+       /*
+        * @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(ITextViewer)
+        */
+       public void doubleClicked(ITextViewer viewer) {
+               int offset = viewer.getSelectedRange().x;
+               if (offset < 0) {
+                       return;
+               }
+
+               try {
+                       IDocument document = viewer.getDocument();
+
+                       ITypedRegion region = document.getPartition(offset);
+
+                       int start = region.getOffset();
+                       int length = region.getLength();
+                       int end = start + length - 1;
+
+                       if (offset == start) {
+                               if (document.getChar(start) == document.getChar(end)) {
+                                       viewer.setSelectedRange(start + 1, length - 2);
+                               } else {
+                                       viewer.setSelectedRange(start + 1, length - 1);
+                               }
+
+                               return;
+                       }
+
+                       if (offset == end) {
+                               if (document.getChar(start) == document.getChar(end)) {
+                                       viewer.setSelectedRange(start + 1, length - 2);
+                                       return;
+                               }
+                       }
+
+                       super.doubleClicked(viewer);
+               } catch (BadLocationException e) {
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDConfiguration.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDConfiguration.java
new file mode 100644 (file)
index 0000000..282771f
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDConfiguration.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+import net.sourceforge.phpeclipse.xml.ui.text.DTDTextTools;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+/**
+ * DTD editor configuration.
+ * 
+ * @author Igor Malinin
+ */
+public class DTDConfiguration extends SourceViewerConfiguration {
+       private DTDTextTools dtdTextTools;
+
+       private ITextDoubleClickStrategy dcsDefault;
+
+       private ITextDoubleClickStrategy dcsSimple;
+
+       public DTDConfiguration(DTDTextTools tools) {
+               dtdTextTools = tools;
+
+               dcsDefault = new TextDoubleClickStrategy();
+               dcsSimple = new SimpleDoubleClickStrategy();
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getDoubleClickStrategy(ISourceViewer,
+        *      String)
+        */
+       public ITextDoubleClickStrategy getDoubleClickStrategy(
+                       ISourceViewer sourceViewer, String contentType) {
+               if (XMLPartitionScanner.XML_PI.equals(contentType)) {
+                       return dcsSimple;
+               }
+
+               if (XMLPartitionScanner.XML_COMMENT.equals(contentType)) {
+                       return dcsSimple;
+               }
+
+               if (XMLPartitionScanner.XML_DECL.equals(contentType)) {
+                       return dcsSimple;
+               }
+
+               if (XMLPartitionScanner.DTD_CONDITIONAL.equals(contentType)) {
+                       return dcsSimple;
+               }
+
+               return dcsDefault;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredContentTypes(ISourceViewer)
+        */
+       public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+               return new String[] { IDocument.DEFAULT_CONTENT_TYPE,
+                               XMLPartitionScanner.XML_PI, XMLPartitionScanner.XML_COMMENT,
+                               XMLPartitionScanner.XML_DECL,
+                               XMLPartitionScanner.DTD_CONDITIONAL, };
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(ISourceViewer)
+        */
+       public IPresentationReconciler getPresentationReconciler(
+                       ISourceViewer sourceViewer) {
+               PresentationReconciler reconciler = new PresentationReconciler();
+
+               DefaultDamagerRepairer dr;
+
+               dr = new DefaultDamagerRepairer(dtdTextTools.getDTDTextScanner());
+               reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+               reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_PI);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_PI);
+
+               dr = new DefaultDamagerRepairer(dtdTextTools.getXMLPIScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_PI);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_PI);
+
+               dr = new DefaultDamagerRepairer(dtdTextTools.getXMLCommentScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_COMMENT);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_COMMENT);
+
+               dr = new DefaultDamagerRepairer(dtdTextTools.getXMLDeclScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_DECL);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_DECL);
+
+               dr = new DefaultDamagerRepairer(dtdTextTools.getDTDConditionalScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.DTD_CONDITIONAL);
+               reconciler.setRepairer(dr, XMLPartitionScanner.DTD_CONDITIONAL);
+
+               return reconciler;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDDocumentProvider.java
new file mode 100644 (file)
index 0000000..fbb3769
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDDocumentProvider.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+
+/**
+ * DTD document provider.
+ * 
+ * @author Igor Malinin
+ */
+public class DTDDocumentProvider extends AbstractDocumentProvider {
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(Object)
+        */
+       protected IDocument createDocument(Object element) throws CoreException {
+               IDocument document = super.createDocument(element);
+               if (document != null) {
+                       IDocumentPartitioner partitioner = XMLPlugin.getDefault()
+                                       .getDTDTextTools().createDTDPartitioner();
+
+                       if (partitioner != null) {
+                               partitioner.connect(document);
+                               document.setDocumentPartitioner(partitioner);
+                       }
+               }
+
+               return document;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DeclScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DeclScanner.java
new file mode 100644 (file)
index 0000000..9269b7c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DeclScanner.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * @author Igor Malinin
+ */
+public class DeclScanner extends BufferedRuleBasedScanner {
+
+       /**
+        * Creates a color scanner for XML text or attribute value.
+        */
+       public DeclScanner(Map tokens) {
+               IToken decl = (Token) tokens.get(IXMLSyntaxConstants.XML_DECL);
+
+               setDefaultReturnToken(decl);
+
+               IToken markup = (Token) tokens.get(IXMLSyntaxConstants.XML_ATT_NAME);
+
+               WordRule rule = new WordRule(new NmtokenDetector(), markup);
+               rule.addWord("ATTLIST", decl);
+               rule.addWord("CDATA", decl);
+               rule.addWord("DOCTYPE", decl);
+               rule.addWord("ELEMENT", decl);
+               rule.addWord("EMPTY", decl);
+               rule.addWord("ENTITY", decl);
+               rule.addWord("FIXED", decl);
+               rule.addWord("ID", decl);
+               rule.addWord("IDREF", decl);
+               rule.addWord("IDREFS", decl);
+               rule.addWord("IMPLIED", decl);
+               rule.addWord("PCDATA", decl);
+               rule.addWord("PUBLIC", decl);
+               rule.addWord("REQUIRED", decl);
+               rule.addWord("SYSTEM", decl);
+
+               IToken string = (Token) tokens.get(IXMLSyntaxConstants.XML_ATT_VALUE);
+               IToken entity = (Token) tokens.get(IXMLSyntaxConstants.XML_ENTITY);
+
+               IRule[] rules = { rule, new MultiLineRule("\"", "\"", string),
+                               new MultiLineRule("'", "'", string),
+                               new EntityRule('%', entity), };
+
+               setRules(rules);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/EntityRule.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/EntityRule.java
new file mode 100644 (file)
index 0000000..efedb0f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: EntityRule.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * Rule detecting XML or DTD entities.
+ * 
+ * @author Igor Malinin
+ */
+public class EntityRule implements IRule {
+
+       private static NameDetector detector = new NameDetector();
+
+       private char start;
+
+       private IToken token;
+
+       public EntityRule(char start, IToken token) {
+               this.start = start;
+               this.token = token;
+       }
+
+       public IToken evaluate(ICharacterScanner scanner) {
+               int ch = scanner.read();
+
+               if (ch == start) {
+                       ch = scanner.read();
+                       if (ch == ICharacterScanner.EOF) {
+                               scanner.unread();
+                               return token;
+                       }
+                       if (ch == ';') {
+                               return token;
+                       }
+                       if (!detector.isWordStart((char) ch)) {
+                               scanner.unread();
+                               return token;
+                       }
+
+                       while (true) {
+                               ch = scanner.read();
+                               if (ch == ICharacterScanner.EOF) {
+                                       scanner.unread();
+                                       return token;
+                               }
+                               if (ch == ';') {
+                                       return token;
+                               }
+                               if (!detector.isWordPart((char) ch)) {
+                                       scanner.unread();
+                                       return token;
+                               }
+                       }
+               }
+               scanner.unread();
+
+               return Token.UNDEFINED;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NameDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NameDetector.java
new file mode 100644 (file)
index 0000000..e86f491
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: NameDetector.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * XML Name detector.
+ * 
+ * @author Igor Malinin
+ */
+public class NameDetector implements IWordDetector {
+
+       /**
+        * @see IWordDetector#isWordPart(char)
+        */
+       public boolean isWordPart(char ch) {
+               if (Character.isUnicodeIdentifierPart(ch)) {
+                       return true;
+               }
+               switch (ch) {
+               case '.':
+               case '-':
+               case '_':
+               case ':':
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * @see IWordDetector#isWordStart(char)
+        */
+       public boolean isWordStart(char ch) {
+               if (Character.isUnicodeIdentifierStart(ch)) {
+                       return true;
+               }
+               switch (ch) {
+               case '_':
+               case ':':
+                       return true;
+               }
+               return false;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NmtokenDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NmtokenDetector.java
new file mode 100644 (file)
index 0000000..4a3278a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: NmtokenDetector.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * XML Nmtoken detector.
+ * 
+ * @author Igor Malinin
+ */
+public class NmtokenDetector implements IWordDetector {
+
+       /**
+        * @see IWordDetector#isWordPart(char)
+        */
+       public boolean isWordPart(char ch) {
+               if (Character.isUnicodeIdentifierPart(ch)) {
+                       return true;
+               }
+               switch (ch) {
+               case '.':
+               case '-':
+               case '_':
+               case ':':
+                       return false;
+               }
+               return false;
+       }
+
+       /**
+        * @see IWordDetector#isWordStart(char)
+        */
+       public boolean isWordStart(char ch) {
+               return isWordPart(ch);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/PHPXMLPartitionScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/PHPXMLPartitionScanner.java
new file mode 100644 (file)
index 0000000..0339ba5
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: PHPXMLPartitionScanner.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class PHPXMLPartitionScanner implements IPartitionTokenScanner {
+       // public static final String XML_PI = "__xml_processing_instruction";
+       public static final String XML_COMMENT = "__xml_comment";
+
+       public static final String XML_DECL = "__xml_declaration";
+
+       public static final String XML_TAG = "__xml_tag";
+
+       public static final String XML_ATTRIBUTE = "__xml_attribute";
+
+       public static final String XML_CDATA = "__xml_cdata";
+
+       public static final String DTD_INTERNAL = "__dtd_internal";
+
+       // public static final String DTD_INTERNAL_PI = "__dtd_internal_pi";
+       public static final String DTD_INTERNAL_COMMENT = "__dtd_internal_comment";
+
+       public static final String DTD_INTERNAL_DECL = "__dtd_internal_declaration";
+
+       public static final String DTD_CONDITIONAL = "__dtd_conditional";
+
+       public static final int STATE_DEFAULT = 0;
+
+       public static final int STATE_TAG = 1;
+
+       public static final int STATE_DECL = 2;
+
+       public static final int STATE_CDATA = 4;
+
+       public static final int STATE_INTERNAL = 8;
+
+       protected IDocument document;
+
+       protected int end;
+
+       protected int offset;
+
+       protected int length;
+
+       protected int position;
+
+       protected int state;
+
+       protected boolean parsedtd;
+
+       protected Map tokens = new HashMap();
+
+       public PHPXMLPartitionScanner(boolean parsedtd) {
+               this.parsedtd = parsedtd;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+        */
+       public IToken nextToken() {
+               offset += length;
+
+               switch (state) {
+               case STATE_TAG:
+                       return nextTagToken();
+
+               case STATE_DECL:
+                       return nextDeclToken();
+
+               case STATE_CDATA:
+                       return nextCDATAToken();
+               }
+
+               switch (read()) {
+               case ICharacterScanner.EOF:
+                       state = STATE_DEFAULT;
+                       return getToken(null);
+
+               case '<':
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               if (parsedtd || isInternal()) {
+                                       break;
+                               }
+
+                               state = STATE_DEFAULT;
+                               return getToken(XML_TAG);
+
+                       case '?': // <? <?PI
+                               unread();
+                               break;
+                       // return nextPIToken();
+
+                       case '!': // <! <!DEFINITION or <![CDATA[ or <!--COMMENT
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       state = STATE_DEFAULT;
+                                       return getToken(XML_TAG);
+
+                               case '-': // <!- <!--COMMENT
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               return nextDeclToken();
+
+                                       case '-': // <!--
+                                               return nextCommentToken();
+                                       }
+
+                               case '[': // <![ <![CDATA[ or <![%cond;[
+                                       if (parsedtd) {
+                                               return nextConditionalToken();
+                                       }
+
+                                       if (!isInternal()) {
+                                               return nextCDATAToken();
+                                       }
+                               }
+
+                               return nextDeclToken();
+                       }
+
+                       if (parsedtd || isInternal()) {
+                               break;
+                       }
+
+                       unread();
+
+                       return nextTagToken();
+
+               case ']':
+                       if (isInternal()) {
+                               unread();
+
+                               state = STATE_DECL;
+                               length = 0;
+                               return nextToken();
+                       }
+                       break;
+               default:
+                       unread();
+               }
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               state = STATE_DEFAULT;
+                               return getToken(null);
+
+                       case '<':
+                               if (parsedtd || isInternal()) {
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               state = STATE_DEFAULT;
+                                               return getToken(null);
+
+                                       case '!':
+                                       case '?':
+                                               unread();
+                                               break;
+
+                                       default:
+                                               continue loop;
+                                       }
+                               }
+
+                               unread();
+
+                               state &= STATE_INTERNAL;
+                               return getToken(isInternal() ? DTD_INTERNAL : null);
+
+                       case ']':
+                               if (isInternal()) {
+                                       unread();
+
+                                       state = STATE_DECL;
+                                       if (position == offset) {
+                                               // nothing between
+                                               length = 0;
+                                               return nextToken();
+                                       }
+
+                                       return getToken(DTD_INTERNAL);
+                               }
+                       }
+               }
+       }
+
+       private IToken nextTagToken() {
+               int quot = read();
+
+               switch (quot) {
+               case ICharacterScanner.EOF:
+               case '>':
+                       state = STATE_DEFAULT;
+                       return getToken(XML_TAG);
+
+               case '"':
+               case '\'':
+                       while (true) {
+                               int ch = read();
+
+                               if (ch == quot) {
+                                       state = STATE_TAG;
+                                       return getToken(XML_ATTRIBUTE);
+                               }
+
+                               switch (ch) {
+                               case '<':
+                                       unread();
+
+                               case ICharacterScanner.EOF:
+                                       state = STATE_DEFAULT;
+                                       return getToken(XML_ATTRIBUTE);
+                               }
+                       }
+               default:
+                       unread();
+               }
+
+               while (true) {
+                       switch (read()) {
+                       case '<':
+                               unread();
+
+                       case ICharacterScanner.EOF:
+                       case '>':
+                               state = STATE_DEFAULT;
+                               return getToken(XML_TAG);
+
+                       case '"':
+                       case '\'':
+                               unread();
+
+                               state = STATE_TAG;
+                               return getToken(XML_TAG);
+                       }
+               }
+       }
+
+       private IToken nextDeclToken() {
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               state = STATE_DEFAULT;
+                               return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL);
+
+                       case '<':
+                               if (parsedtd || isInternal()) {
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               state = STATE_DEFAULT;
+                                               return getToken(isInternal() ? DTD_INTERNAL : null);
+
+                                       case '!':
+                                       case '?':
+                                               unread();
+                                               break;
+
+                                       default:
+                                               continue loop;
+                                       }
+                               }
+
+                               unread();
+
+                       case '>':
+                               state &= STATE_INTERNAL;
+                               return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL);
+
+                       case '[': // <!DOCTYPE xxx [dtd]>
+                               if (!isInternal()) {
+                                       state = STATE_INTERNAL;
+                                       return getToken(XML_DECL);
+                               }
+                       }
+               }
+       }
+
+       private IToken nextCommentToken() {
+               state &= STATE_INTERNAL;
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               break loop;
+
+                       case '-': // - -->
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case '-': // -- -->
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                       case '>':
+                                               break loop;
+                                       }
+
+                                       unread();
+                                       continue loop;
+                               }
+                       }
+               }
+
+               return getToken(isInternal() ? DTD_INTERNAL_COMMENT : XML_COMMENT);
+       }
+
+       private IToken nextCDATAToken() {
+               state = STATE_DEFAULT;
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               break loop;
+
+                       case ']': // ] ]]>
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case ']': // ]] ]]>
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                       case '>': // ]]>
+                                               break loop;
+                                       }
+
+                                       unread();
+                                       unread();
+                                       continue loop;
+                               }
+                       }
+               }
+
+               return getToken(XML_CDATA);
+       }
+
+       private IToken nextConditionalToken() {
+               state = STATE_DEFAULT;
+
+               int level = 1;
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               break loop;
+
+                       case '<': // - -->
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case '!': // -- -->
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               break loop;
+
+                                       case '[':
+                                               ++level;
+                                               continue loop;
+                                       }
+
+                                       unread();
+                                       continue loop;
+                               }
+
+                               unread();
+                               continue loop;
+
+                       case ']': // - -->
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case ']': // -- -->
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                       case '>':
+                                               if (--level == 0) {
+                                                       break loop;
+                                               }
+
+                                               continue loop;
+                                       }
+
+                                       unread();
+                                       unread();
+                                       continue loop;
+                               }
+                       }
+               }
+
+               return getToken(DTD_CONDITIONAL);
+       }
+
+       private IToken getToken(String type) {
+               length = position - offset;
+
+               if (length == 0) {
+                       return Token.EOF;
+               }
+
+               if (type == null) {
+                       return Token.UNDEFINED;
+               }
+
+               IToken token = (IToken) tokens.get(type);
+               if (token == null) {
+                       token = new Token(type);
+                       tokens.put(type, token);
+               }
+
+               return token;
+       }
+
+       private boolean isInternal() {
+               return (state & STATE_INTERNAL) != 0;
+       }
+
+       private int read() {
+               if (position >= end) {
+                       return ICharacterScanner.EOF;
+               }
+
+               try {
+                       return document.getChar(position++);
+               } catch (BadLocationException e) {
+                       --position;
+                       return ICharacterScanner.EOF;
+               }
+       }
+
+       private void unread() {
+               --position;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
+        */
+       public int getTokenOffset() {
+               Assert.isTrue(offset >= 0, Integer.toString(offset));
+               return offset;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
+        */
+       public int getTokenLength() {
+               return length;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int,
+        *      int)
+        */
+       public void setRange(IDocument document, int offset, int length) {
+               this.document = document;
+               this.end = offset + length;
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+
+               this.state = STATE_DEFAULT;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
+        */
+       // public void setPartialRange(IDocument document, int offset, int length,
+       // String contentType, int partitionOffset) {
+       // state = STATE_DEFAULT;
+       // if (partitionOffset > -1) {
+       // int delta = offset - partitionOffset;
+       // if (delta > 0) {
+       // setRange(document, partitionOffset, length + delta);
+       // return;
+       // }
+       // }
+       // setRange(document, partitionOffset, length);
+       // }
+       /*
+        * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
+        */
+       public void setPartialRange(IDocument document, int offset, int length,
+                       String contentType, int partitionOffset) {
+               // boolean flag = false;
+               this.document = document;
+               this.end = offset + length;
+
+               // NB! Undocumented value: -1
+               if (partitionOffset >= 0) {
+                       offset = partitionOffset;
+                       // flag = true;
+               }
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+
+               // if (flag) {
+               // state = STATE_DEFAULT;
+               // return;
+               // }
+               if (contentType == XML_ATTRIBUTE) {
+                       state = STATE_TAG;
+                       return;
+               }
+
+               if (contentType == XML_TAG) {
+                       state = isContinuationPartition() ? STATE_TAG : STATE_DEFAULT;
+                       return;
+               }
+
+               if (contentType == XML_DECL) {
+                       state = isContinuationPartition() ? STATE_DECL : STATE_DEFAULT;
+                       return;
+               }
+
+               if (contentType == DTD_INTERNAL || contentType == DTD_INTERNAL_DECL
+                               || contentType == DTD_INTERNAL_COMMENT) {
+                       state = STATE_INTERNAL;
+                       return;
+               }
+
+               state = STATE_DEFAULT;
+       }
+
+       private boolean isContinuationPartition() {
+               try {
+                       String type = document.getContentType(offset - 1);
+
+                       if (type != IDocument.DEFAULT_CONTENT_TYPE) {
+                               return true;
+                       }
+               } catch (BadLocationException e) {
+               }
+
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SimpleDoubleClickStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SimpleDoubleClickStrategy.java
new file mode 100644 (file)
index 0000000..3eb545a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: SimpleDoubleClickStrategy.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITypedRegion;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class SimpleDoubleClickStrategy extends TextDoubleClickStrategy {
+       /*
+        * @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(ITextViewer)
+        */
+       public void doubleClicked(ITextViewer viewer) {
+               int offset = viewer.getSelectedRange().x;
+               if (offset < 0) {
+                       return;
+               }
+
+               try {
+                       IDocument document = viewer.getDocument();
+
+                       ITypedRegion region = document.getPartition(offset);
+
+                       int start = region.getOffset();
+                       int length = region.getLength();
+
+                       if (offset == start) {
+                               viewer.setSelectedRange(start, length);
+                               return;
+                       }
+
+                       int end = start + length - 1;
+
+                       if (offset == end && document.getChar(end) == '>') {
+                               viewer.setSelectedRange(start, length);
+                               return;
+                       }
+
+                       super.doubleClicked(viewer);
+               } catch (BadLocationException e) {
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SingleTokenScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SingleTokenScanner.java
new file mode 100644 (file)
index 0000000..b78c796
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: SingleTokenScanner.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * @author Igor Malinin
+ */
+public class SingleTokenScanner extends RuleBasedScanner {
+
+       /**
+        * Creates a single token scanner.
+        */
+       public SingleTokenScanner(Map tokens, String property) {
+               setDefaultReturnToken((Token) tokens.get(property));
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TagDoubleClickStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TagDoubleClickStrategy.java
new file mode 100644 (file)
index 0000000..3e70d8f
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: TagDoubleClickStrategy.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITypedRegion;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class TagDoubleClickStrategy extends TextDoubleClickStrategy {
+       /*
+        * @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(ITextViewer)
+        */
+       public void doubleClicked(ITextViewer viewer) {
+               int offset = viewer.getSelectedRange().x;
+               if (offset < 0) {
+                       return;
+               }
+
+               try {
+                       IDocument document = viewer.getDocument();
+
+                       ITypedRegion region = document.getPartition(offset);
+
+                       int start = region.getOffset();
+
+                       if (offset == start && document.getChar(offset) == '<') {
+                               region = document.getPartition(offset);
+                               offset = region.getOffset() + region.getLength();
+
+                               if (document.getChar(offset - 1) != '>') {
+                                       while (true) {
+                                               if (offset >= document.getLength()) {
+                                                       break;
+                                               }
+
+                                               region = document.getPartition(offset);
+                                               offset = region.getOffset() + region.getLength();
+
+                                               if (XMLPartitionScanner.XML_ATTRIBUTE.equals(region
+                                                               .getType())) {
+                                                       continue;
+                                               }
+
+                                               if (XMLPartitionScanner.XML_TAG
+                                                               .equals(region.getType())) {
+                                                       if (document.getChar(region.getOffset()) == '<') {
+                                                               break;
+                                                       }
+
+                                                       if (document.getChar(offset - 1) == '>') {
+                                                               break;
+                                                       }
+
+                                                       continue;
+                                               }
+
+                                               offset = region.getOffset();
+                                               break;
+                                       }
+                               }
+
+                               viewer.setSelectedRange(start, offset - start);
+                               return;
+                       }
+
+                       int end = start + region.getLength();
+
+                       if (offset == end - 1 && document.getChar(offset) == '>') {
+                               region = document.getPartition(offset);
+                               offset = region.getOffset();
+
+                               if (document.getChar(offset) != '<') {
+                                       while (true) {
+                                               if (offset <= 0) {
+                                                       break;
+                                               }
+
+                                               region = document.getPartition(offset - 1);
+                                               offset = region.getOffset();
+
+                                               if (XMLPartitionScanner.XML_ATTRIBUTE.equals(region
+                                                               .getType())) {
+                                                       continue;
+                                               }
+
+                                               if (XMLPartitionScanner.XML_TAG
+                                                               .equals(region.getType())) {
+                                                       if (document.getChar(offset) == '<') {
+                                                               break;
+                                                       }
+
+                                                       continue;
+                                               }
+
+                                               offset += region.getLength();
+                                               break;
+                                       }
+                               }
+
+                               viewer.setSelectedRange(offset, end - offset);
+                               return;
+                       }
+
+                       super.doubleClicked(viewer);
+               } catch (BadLocationException e) {
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TextScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TextScanner.java
new file mode 100644 (file)
index 0000000..3ef9542
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: TextScanner.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * @author Igor Malinin
+ */
+public class TextScanner extends BufferedRuleBasedScanner {
+
+       /**
+        * Creates a color scanner for XML text or attribute value.
+        */
+       public TextScanner(Map tokens, char startEntity, String defaultProperty) {
+               setDefaultReturnToken((Token) tokens.get(defaultProperty));
+
+               IToken entity = (Token) tokens.get(IXMLSyntaxConstants.XML_ENTITY);
+
+               IRule[] rules = { new EntityRule(startEntity, entity) };
+
+               setRules(rules);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/WhitespaceDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/WhitespaceDetector.java
new file mode 100644 (file)
index 0000000..3efcc3e
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: WhitespaceDetector.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+/**
+ * XML white-space detector.
+ * 
+ * @author Igor Malinin
+ */
+public class WhitespaceDetector implements IWhitespaceDetector {
+
+       /**
+        * @see IWhitespaceDetector#isWhitespace(char)
+        */
+       public boolean isWhitespace(char ch) {
+               switch (ch) {
+               case 0x09:
+               case 0x0A:
+               case 0x0D:
+               case 0x20:
+                       return true;
+
+               default:
+                       return false;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotation.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotation.java
new file mode 100644 (file)
index 0000000..fb371b8
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLAnnotation.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.source.Annotation;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLAnnotation extends Annotation {
+       public static final String TYPE_ERROR = "org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
+
+       public static final String TYPE_WARNING = "org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
+
+       public static final String TYPE_INFO = "org.eclipse.ui.workbench.texteditor.info"; //$NON-NLS-1$
+
+       public XMLAnnotation(String type, boolean persistent, String text) {
+               super(type, persistent, text);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationHover.java
new file mode 100644 (file)
index 0000000..3e38663
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLAnnotationHover.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+/**
+ * Implements simple annotation hover to show the associated messages.
+ */
+public class XMLAnnotationHover implements IAnnotationHover {
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer,
+        *      int)
+        */
+       public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+               List annotations = getAnnotationsForLine(sourceViewer, lineNumber);
+               if (annotations != null) {
+                       List messages = new ArrayList();
+
+                       Iterator e = annotations.iterator();
+                       while (e.hasNext()) {
+                               Annotation annotation = (Annotation) e.next();
+
+                               String message = annotation.getText();
+                               if (message != null) {
+                                       message = message.trim();
+                                       if (message.length() > 0) {
+                                               messages.add(message);
+                                       }
+                               }
+                       }
+
+                       if (messages.size() == 1) {
+                               return (String) messages.get(0);
+                       }
+
+                       if (messages.size() > 1) {
+                               return formatMessages(messages);
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Formats multiple annotation messages for display.
+        */
+       private String formatMessages(List messages) {
+               StringBuffer buffer = new StringBuffer();
+
+               Iterator e = messages.iterator();
+               while (e.hasNext()) {
+                       buffer.append("- "); //$NON-NLS-1$
+                       buffer.append(e.next());
+                       buffer.append('\n');
+               }
+
+               return buffer.toString();
+       }
+
+       /**
+        * Returns annotations for the ruler's line of activity.
+        */
+       private List getAnnotationsForLine(ISourceViewer viewer, int line) {
+               IDocument document = viewer.getDocument();
+
+               IAnnotationModel model = viewer.getAnnotationModel();
+               if (model == null) {
+                       return null;
+               }
+
+               List retVal = new ArrayList();
+
+               Iterator e = new XMLAnnotationIterator(model, true);
+               while (e.hasNext()) {
+                       Annotation a = (Annotation) e.next();
+
+                       Position position = model.getPosition(a);
+                       if (position != null) {
+                               try {
+                                       int annotationLine = document.getLineOfOffset(position
+                                                       .getOffset());
+                                       if (annotationLine == line) {
+                                               retVal.add(a);
+                                       }
+                               } catch (BadLocationException e1) {
+                                       // ignore
+                               }
+                       }
+               }
+
+               return retVal;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationIterator.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationIterator.java
new file mode 100644 (file)
index 0000000..b86dea6
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLAnnotationIterator.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Iterator;
+
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLAnnotationIterator implements Iterator {
+       private boolean skipIrrelevants;
+
+       private Iterator iterator;
+
+       private Annotation next;
+
+       public XMLAnnotationIterator(IAnnotationModel model, boolean skipIrrelevants) {
+               this.skipIrrelevants = skipIrrelevants;
+
+               iterator = model.getAnnotationIterator();
+               skip();
+       }
+
+       private void skip() {
+               while (iterator.hasNext()) {
+                       Annotation next = (Annotation) iterator.next();
+                       if (next instanceof XMLAnnotation) {
+                               if (skipIrrelevants) {
+                                       if (!next.isMarkedDeleted()) {
+                                               this.next = next;
+                                               return;
+                                       }
+                               } else {
+                                       this.next = next;
+                                       return;
+                               }
+                       }
+               }
+
+               this.next = null;
+       }
+
+       /*
+        * @see java.util.Iterator#hasNext()
+        */
+       public boolean hasNext() {
+               return (next != null);
+       }
+
+       /*
+        * @see java.util.Iterator#next()
+        */
+       public Object next() {
+               try {
+                       return next;
+               } finally {
+                       skip();
+               }
+       }
+
+       /*
+        * @see java.util.Iterator#remove()
+        */
+       public void remove() {
+               throw new UnsupportedOperationException();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLCDATAScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLCDATAScanner.java
new file mode 100644 (file)
index 0000000..848f207
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLCDATAScanner.java,v 1.4 2007-06-03 11:39:00 toshihiro Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLCDATAScanner implements ITokenScanner {
+
+       private Map tokens;
+
+       private IDocument document;
+
+       private int begin;
+
+       private int end;
+
+       private int offset;
+
+       private int length;
+
+       private int position;
+
+       public XMLCDATAScanner(Map tokens) {
+               this.tokens = tokens;
+       }
+
+       /*
+        * @see ITokenScanner#setRange(IDocument, int, int)
+        */
+       public void setRange(IDocument document, int offset, int length) {
+               this.document = document;
+
+               this.begin = offset;
+               this.end = offset + length;
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+       }
+
+       /*
+        * @see ITokenScanner#nextToken()
+        */
+       public IToken nextToken() {
+               offset += length;
+
+               if (position == begin) {
+
+                       try {
+                               if (document.get(position, 9).equals("<![CDATA[")) {
+                                       position += 9;
+                                       return getToken(IXMLSyntaxConstants.XML_CDATA);
+                               }
+                       } catch (BadLocationException e) {
+                       }
+
+               }
+
+               if (position == end) {
+                       return getToken(null);
+               }
+
+               try {
+                       int p = end - 3;
+                       if (document.get(p, 3).equals("]]>")) {
+                               if (position == p) {
+                                       position = end;
+                                       return getToken(IXMLSyntaxConstants.XML_CDATA);
+                               }
+                               position = p;
+                       } else {
+                               position = end;
+                       }
+               } catch (BadLocationException e) {
+               }
+
+               return getToken(IXMLSyntaxConstants.XML_DEFAULT);
+       }
+
+       private IToken getToken(String type) {
+               length = position - offset;
+
+               if (length == 0) {
+                       return Token.EOF;
+               }
+
+               if (type == null) {
+                       return Token.UNDEFINED;
+               }
+
+               IToken token = (IToken) tokens.get(type);
+               if (token == null) {
+                       return Token.UNDEFINED;
+               }
+
+               return token;
+       }
+
+       /*
+        * @see ITokenScanner#getTokenOffset()
+        */
+       public int getTokenOffset() {
+               return offset;
+       }
+
+       /*
+        * @see ITokenScanner#getTokenLength()
+        */
+       public int getTokenLength() {
+               return length;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLConfiguration.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLConfiguration.java
new file mode 100644 (file)
index 0000000..14a17c9
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLConfiguration.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import net.sourceforge.phpeclipse.ui.templates.template.BasicCompletionProcessor;
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.reconciler.MonoReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * XML editor configuration.
+ * 
+ * @author Igor Malinin
+ */
+public class XMLConfiguration extends TextSourceViewerConfiguration {
+       protected XMLTextTools xmlTextTools;
+
+       private ITextDoubleClickStrategy dcsDefault;
+
+       private ITextDoubleClickStrategy dcsSimple;
+
+       private ITextDoubleClickStrategy dcsTag;
+
+       private ITextDoubleClickStrategy dcsAttValue;
+
+       /** The associated editor. */
+       private ITextEditor editor;
+
+       public XMLConfiguration(XMLTextTools tools) {
+               this(tools, null);
+       }
+
+       public XMLConfiguration(XMLTextTools tools, ITextEditor editor) {
+               xmlTextTools = tools;
+               this.editor = editor;
+               dcsDefault = new TextDoubleClickStrategy();
+               dcsSimple = new SimpleDoubleClickStrategy();
+               dcsTag = new TagDoubleClickStrategy();
+               dcsAttValue = new AttValueDoubleClickStrategy();
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
+        */
+       public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+               return new XMLAnnotationHover();
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
+        */
+       public ITextHover getTextHover(ISourceViewer sourceViewer,
+                       String contentType) {
+               if (editor != null) {
+                       IDocumentProvider provider = editor.getDocumentProvider();
+                       IEditorInput input = editor.getEditorInput();
+                       IAnnotationModel model = provider.getAnnotationModel(input);
+                       return new XMLTextHover(model);
+               }
+
+               return super.getTextHover(sourceViewer, contentType);
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getDoubleClickStrategy(ISourceViewer,
+        *      String)
+        */
+       public ITextDoubleClickStrategy getDoubleClickStrategy(
+                       ISourceViewer sourceViewer, String contentType) {
+               if (XMLPartitionScanner.XML_COMMENT.equals(contentType)) {
+                       return dcsSimple;
+               }
+
+               if (XMLPartitionScanner.XML_PI.equals(contentType)) {
+                       return dcsSimple;
+               }
+
+               if (XMLPartitionScanner.XML_TAG.equals(contentType)) {
+                       return dcsTag;
+               }
+
+               if (XMLPartitionScanner.XML_ATTRIBUTE.equals(contentType)) {
+                       return dcsAttValue;
+               }
+
+               if (XMLPartitionScanner.XML_CDATA.equals(contentType)) {
+                       return dcsSimple;
+               }
+
+               if (contentType.startsWith(XMLPartitionScanner.DTD_INTERNAL)) {
+                       return dcsSimple;
+               }
+
+               return dcsDefault;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredContentTypes(ISourceViewer)
+        */
+       public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+               return new String[] { IDocument.DEFAULT_CONTENT_TYPE,
+                               XMLPartitionScanner.XML_PI, XMLPartitionScanner.XML_COMMENT,
+                               XMLPartitionScanner.XML_DECL, XMLPartitionScanner.XML_TAG,
+                               XMLPartitionScanner.XML_ATTRIBUTE,
+                               XMLPartitionScanner.XML_CDATA,
+                               XMLPartitionScanner.DTD_INTERNAL,
+                               XMLPartitionScanner.DTD_INTERNAL_PI,
+                               XMLPartitionScanner.DTD_INTERNAL_COMMENT,
+                               XMLPartitionScanner.DTD_INTERNAL_DECL, };
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(ISourceViewer)
+        */
+       public IPresentationReconciler getPresentationReconciler(
+                       ISourceViewer sourceViewer) {
+               PresentationReconciler reconciler = new PresentationReconciler();
+
+               DefaultDamagerRepairer dr;
+
+               dr = new DefaultDamagerRepairer(xmlTextTools.getXMLTextScanner());
+               reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+               reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+               dr = new DefaultDamagerRepairer(xmlTextTools.getDTDTextScanner());
+               reconciler.setDamager(dr, XMLPartitionScanner.DTD_INTERNAL);
+               reconciler.setRepairer(dr, XMLPartitionScanner.DTD_INTERNAL);
+
+               dr = new DefaultDamagerRepairer(xmlTextTools.getXMLPIScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_PI);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_PI);
+               reconciler.setDamager(dr, XMLPartitionScanner.DTD_INTERNAL_PI);
+               reconciler.setRepairer(dr, XMLPartitionScanner.DTD_INTERNAL_PI);
+
+               dr = new DefaultDamagerRepairer(xmlTextTools.getXMLCommentScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_COMMENT);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_COMMENT);
+               reconciler.setDamager(dr, XMLPartitionScanner.DTD_INTERNAL_COMMENT);
+               reconciler.setRepairer(dr, XMLPartitionScanner.DTD_INTERNAL_COMMENT);
+
+               dr = new DefaultDamagerRepairer(xmlTextTools.getXMLDeclScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_DECL);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_DECL);
+               reconciler.setDamager(dr, XMLPartitionScanner.DTD_INTERNAL_DECL);
+               reconciler.setRepairer(dr, XMLPartitionScanner.DTD_INTERNAL_DECL);
+
+               dr = new DefaultDamagerRepairer(xmlTextTools.getXMLTagScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG);
+
+               dr = new DefaultDamagerRepairer(xmlTextTools.getXMLAttributeScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_ATTRIBUTE);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_ATTRIBUTE);
+
+               dr = new DefaultDamagerRepairer(xmlTextTools.getXMLCDATAScanner());
+
+               reconciler.setDamager(dr, XMLPartitionScanner.XML_CDATA);
+               reconciler.setRepairer(dr, XMLPartitionScanner.XML_CDATA);
+
+               return reconciler;
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
+        */
+       public IReconciler getReconciler(ISourceViewer sourceViewer) {
+               if ((editor != null) && editor.isEditable()) {
+                       MonoReconciler reconciler = new MonoReconciler(
+                                       new XMLReconcilingStrategy(editor), false);
+                       reconciler.setProgressMonitor(new NullProgressMonitor());
+                       reconciler.setDelay(500);
+                       return reconciler;
+               }
+
+               return null;
+       }
+
+       public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+               ContentAssistant assistant = new ContentAssistant();
+               assistant
+                               .setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+               IContentAssistProcessor processor = new BasicCompletionProcessor();
+               assistant.setContentAssistProcessor(processor,
+                               IDocument.DEFAULT_CONTENT_TYPE);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.XML_TAG);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.XML_PI);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.XML_COMMENT);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.XML_DECL);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.XML_TAG);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.XML_ATTRIBUTE);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.XML_CDATA);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.DTD_INTERNAL);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.DTD_INTERNAL_PI);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.DTD_INTERNAL_COMMENT);
+               assistant.setContentAssistProcessor(processor,
+                               XMLPartitionScanner.DTD_INTERNAL_DECL);
+               assistant
+                               .setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
+               assistant
+                               .setInformationControlCreator(getInformationControlCreator(sourceViewer));
+
+               return assistant;
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java
new file mode 100644 (file)
index 0000000..eca1657
--- /dev/null
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLPartitionScanner.java,v 1.5 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class XMLPartitionScanner implements IPartitionTokenScanner {
+       public static final String XML_PI = "__xml_processing_instruction";
+
+       public static final String XML_COMMENT = "__xml_comment";
+
+       public static final String XML_DECL = "__xml_declaration";
+
+       public static final String XML_TAG = "__xml_tag";
+
+       public static final String XML_ATTRIBUTE = "__xml_attribute";
+
+       public static final String XML_CDATA = "__xml_cdata";
+
+       public static final String DTD_INTERNAL = "__dtd_internal";
+
+       public static final String DTD_INTERNAL_PI = "__dtd_internal_pi";
+
+       public static final String DTD_INTERNAL_COMMENT = "__dtd_internal_comment";
+
+       public static final String DTD_INTERNAL_DECL = "__dtd_internal_declaration";
+
+       public static final String DTD_CONDITIONAL = "__dtd_conditional";
+
+       public static final int STATE_DEFAULT = 0;
+
+       public static final int STATE_TAG = 1;
+
+       public static final int STATE_DECL = 2;
+
+       public static final int STATE_CDATA = 4;
+
+       public static final int STATE_INTERNAL = 8;
+
+       protected IDocument document;
+
+       protected int end;
+
+       protected int offset;
+
+       protected int length;
+
+       protected int position;
+
+       protected int state;
+
+       protected boolean parsedtd;
+
+       protected Map tokens = new HashMap();
+
+       public XMLPartitionScanner(boolean parsedtd) {
+               this.parsedtd = parsedtd;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+        */
+       public IToken nextToken() {
+               offset += length;
+
+               switch (state) {
+               case STATE_TAG:
+                       return nextTagToken();
+
+               case STATE_DECL:
+                       return nextDeclToken();
+
+               case STATE_CDATA:
+                       return nextCDATAToken();
+               }
+
+               switch (read()) {
+               case ICharacterScanner.EOF:
+                       state = STATE_DEFAULT;
+                       return getToken(null);
+
+               case '<':
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               if (parsedtd || isInternal()) {
+                                       break;
+                               }
+
+                               state = STATE_DEFAULT;
+                               return getToken(XML_TAG);
+
+                       case '?': // <? <?PI
+                               return nextPIToken();
+
+                       case '!': // <! <!DEFINITION or <![CDATA[ or <!--COMMENT
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       state = STATE_DEFAULT;
+                                       return getToken(XML_TAG);
+
+                               case '-': // <!- <!--COMMENT
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               return nextDeclToken();
+
+                                       case '-': // <!--
+                                               return nextCommentToken();
+                                       }
+
+                               case '[': // <![ <![CDATA[ or <![%cond;[
+                                       if (parsedtd) {
+                                               return nextConditionalToken();
+                                       }
+
+                                       if (!isInternal()) {
+                                               return nextCDATAToken();
+                                       }
+                               }
+
+                               return nextDeclToken();
+                       }
+
+                       if (parsedtd || isInternal()) {
+                               break;
+                       }
+
+                       unread();
+
+                       return nextTagToken();
+
+               case ']':
+                       if (isInternal()) {
+                               unread();
+
+                               state = STATE_DECL;
+                               length = 0;
+                               return nextToken();
+                       }
+                       break;
+               default:
+                       unread();
+               }
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               state = STATE_DEFAULT;
+                               return getToken(null);
+
+                       case '<':
+                               if (parsedtd || isInternal()) {
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               state = STATE_DEFAULT;
+                                               return getToken(null);
+
+                                       case '!':
+                                       case '?':
+                                               unread();
+                                               break;
+
+                                       default:
+                                               continue loop;
+                                       }
+                               }
+
+                               unread();
+
+                               state &= STATE_INTERNAL;
+                               return getToken(isInternal() ? DTD_INTERNAL : null);
+
+                       case ']':
+                               if (isInternal()) {
+                                       unread();
+
+                                       state = STATE_DECL;
+                                       if (position == offset) {
+                                               // nothing between
+                                               length = 0;
+                                               return nextToken();
+                                       }
+
+                                       return getToken(DTD_INTERNAL);
+                               }
+                       }
+               }
+       }
+
+       private IToken nextTagToken() {
+               int quot = read();
+
+               switch (quot) {
+               case ICharacterScanner.EOF:
+               case '>':
+                       state = STATE_DEFAULT;
+                       return getToken(XML_TAG);
+
+               case '"':
+               case '\'':
+                       while (true) {
+                               int ch = read();
+
+                               if (ch == quot) {
+                                       state = STATE_TAG;
+                                       return getToken(XML_ATTRIBUTE);
+                               }
+
+                               switch (ch) {
+                               case '<':
+                                       unread();
+
+                               case ICharacterScanner.EOF:
+                                       state = STATE_DEFAULT;
+                                       return getToken(XML_ATTRIBUTE);
+                               }
+                       }
+               default:
+                       unread();
+               }
+
+               while (true) {
+                       switch (read()) {
+                       case '<':
+                               unread();
+
+                       case ICharacterScanner.EOF:
+                       case '>':
+                               state = STATE_DEFAULT;
+                               return getToken(XML_TAG);
+
+                       case '"':
+                       case '\'':
+                               unread();
+
+                               state = STATE_TAG;
+                               return getToken(XML_TAG);
+                       }
+               }
+       }
+
+       private IToken nextDeclToken() {
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               state = STATE_DEFAULT;
+                               return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL);
+
+                       case '<':
+                               if (parsedtd || isInternal()) {
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               state = STATE_DEFAULT;
+                                               return getToken(isInternal() ? DTD_INTERNAL : null);
+
+                                       case '!':
+                                       case '?':
+                                               unread();
+                                               break;
+
+                                       default:
+                                               continue loop;
+                                       }
+                               }
+
+                               unread();
+
+                       case '>':
+                               state &= STATE_INTERNAL;
+                               return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL);
+
+                       case '[': // <!DOCTYPE xxx [dtd]>
+                               if (!isInternal()) {
+                                       state = STATE_INTERNAL;
+                                       return getToken(XML_DECL);
+                               }
+                       }
+               }
+       }
+
+       private IToken nextCommentToken() {
+               state &= STATE_INTERNAL;
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               break loop;
+
+                       case '-': // - -->
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case '-': // -- -->
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                       case '>':
+                                               break loop;
+                                       }
+
+                                       unread();
+                                       continue loop;
+                               }
+                       }
+               }
+
+               return getToken(isInternal() ? DTD_INTERNAL_COMMENT : XML_COMMENT);
+       }
+
+       private IToken nextPIToken() {
+               state &= STATE_INTERNAL;
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               break loop;
+
+                       case '?': // ? ?>
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                               case '>':
+                                       break loop;
+                               }
+
+                               unread();
+                       }
+               }
+
+               return getToken(isInternal() ? DTD_INTERNAL_PI : XML_PI);
+       }
+
+       private IToken nextCDATAToken() {
+               state = STATE_DEFAULT;
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               break loop;
+
+                       case ']': // ] ]]>
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case ']': // ]] ]]>
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                       case '>': // ]]>
+                                               break loop;
+                                       }
+
+                                       unread();
+                                       unread();
+                                       continue loop;
+                               }
+                       }
+               }
+
+               return getToken(XML_CDATA);
+       }
+
+       private IToken nextConditionalToken() {
+               state = STATE_DEFAULT;
+
+               int level = 1;
+
+               loop: while (true) {
+                       switch (read()) {
+                       case ICharacterScanner.EOF:
+                               break loop;
+
+                       case '<': // - -->
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case '!': // -- -->
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               break loop;
+
+                                       case '[':
+                                               ++level;
+                                               continue loop;
+                                       }
+
+                                       unread();
+                                       continue loop;
+                               }
+
+                               unread();
+                               continue loop;
+
+                       case ']': // - -->
+                               switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case ']': // -- -->
+                                       switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                       case '>':
+                                               if (--level == 0) {
+                                                       break loop;
+                                               }
+
+                                               continue loop;
+                                       }
+
+                                       unread();
+                                       unread();
+                                       continue loop;
+                               }
+                       }
+               }
+
+               return getToken(DTD_CONDITIONAL);
+       }
+
+       private IToken getToken(String type) {
+               length = position - offset;
+
+               if (length == 0) {
+                       return Token.EOF;
+               }
+
+               if (type == null) {
+                       return Token.UNDEFINED;
+               }
+
+               IToken token = (IToken) tokens.get(type);
+               if (token == null) {
+                       token = new Token(type);
+                       tokens.put(type, token);
+               }
+
+               return token;
+       }
+
+       private boolean isInternal() {
+               return (state & STATE_INTERNAL) != 0;
+       }
+
+       private int read() {
+               if (position >= end) {
+                       return ICharacterScanner.EOF;
+               }
+
+               try {
+                       return document.getChar(position++);
+               } catch (BadLocationException e) {
+                       --position;
+                       return ICharacterScanner.EOF;
+               }
+       }
+
+       private void unread() {
+               --position;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
+        */
+       public int getTokenOffset() {
+               Assert.isTrue(offset >= 0, Integer.toString(offset));
+               return offset;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
+        */
+       public int getTokenLength() {
+               return length;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int,
+        *      int)
+        */
+       public void setRange(IDocument document, int offset, int length) {
+               this.document = document;
+               this.end = offset + length;
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+
+               this.state = STATE_DEFAULT;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
+        */
+       // public void setPartialRange(IDocument document, int offset, int length,
+       // String contentType, int partitionOffset) {
+       // state = STATE_DEFAULT;
+       // if (partitionOffset > -1) {
+       // int delta = offset - partitionOffset;
+       // if (delta > 0) {
+       // setRange(document, partitionOffset, length + delta);
+       // return;
+       // }
+       // }
+       // setRange(document, partitionOffset, length);
+       // }
+       /*
+        * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
+        */
+       public void setPartialRange(IDocument document, int offset, int length,
+                       String contentType, int partitionOffset) {
+               // boolean flag = false;
+               this.document = document;
+               this.end = offset + length;
+
+               // NB! Undocumented value: -1
+               if (partitionOffset >= 0) {
+                       offset = partitionOffset;
+                       // flag = true;
+               }
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+
+               // if (flag) {
+               // state = STATE_DEFAULT;
+               // return;
+               // }
+               if (contentType == XML_ATTRIBUTE) {
+                       state = STATE_TAG;
+                       return;
+               }
+
+               if (contentType == XML_TAG) {
+                       state = isContinuationPartition() ? STATE_TAG : STATE_DEFAULT;
+                       return;
+               }
+
+               if (contentType == XML_DECL) {
+                       state = isContinuationPartition() ? STATE_DECL : STATE_DEFAULT;
+                       return;
+               }
+
+               if (contentType == DTD_INTERNAL || contentType == DTD_INTERNAL_PI
+                               || contentType == DTD_INTERNAL_DECL
+                               || contentType == DTD_INTERNAL_COMMENT) {
+                       state = STATE_INTERNAL;
+                       return;
+               }
+
+               state = STATE_DEFAULT;
+       }
+
+       private boolean isContinuationPartition() {
+               try {
+                       String type = document.getContentType(offset - 1);
+
+                       if (type != IDocument.DEFAULT_CONTENT_TYPE) {
+                               return true;
+                       }
+               } catch (BadLocationException e) {
+               }
+
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcileStep.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcileStep.java
new file mode 100644 (file)
index 0000000..4bfbac7
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLReconcileStep.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+import net.sourceforge.phpeclipse.xml.core.parser.IProblem;
+import net.sourceforge.phpeclipse.xml.core.parser.IProblemCollector;
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.AbstractReconcileStep;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilableModel;
+import org.eclipse.jface.text.reconciler.IReconcileResult;
+import org.eclipse.jface.text.reconciler.IReconcileStep;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Implementation of a reconcile step for building the XML parse tree on changes
+ * to the editor content.
+ */
+public class XMLReconcileStep extends AbstractReconcileStep {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * Adapts an <code>IXMLDocument</code> to the
+        * <code>IReconcilableModel</code> interface.
+        */
+       private class XMLDocumentAdapter implements IReconcilableModel {
+               private IXMLDocument document;
+
+               public XMLDocumentAdapter(IXMLDocument document) {
+                       this.document = document;
+               }
+
+               public IXMLDocument getDocument() {
+                       return document;
+               }
+
+       }
+
+       /**
+        * Implementation of the problem collector interface for creating problem
+        * annotations when there are problems parsing the style sheet.
+        */
+       private class ProblemCollector implements IProblemCollector {
+               /**
+                * The list of problems added to this collector.
+                */
+               private List collectedProblems = new ArrayList();
+
+               /**
+                * @see IProblemCollector#addProblem(IProblem)
+                */
+               public void addProblem(IProblem problem) {
+                       collectedProblems.add(problem);
+               }
+
+               /**
+                * Returns the list of problems collected while the CSS source has been
+                * parsed, in the order they were reported. The list returned is
+                * immutable.
+                * 
+                * @return the list of collected problems (of type {@link IProblem})
+                */
+               public List getProblems() {
+                       return Collections.unmodifiableList(collectedProblems);
+               }
+       }
+
+       /**
+        * Adapter that adapts an {@link IProblem} to an {@link Annotation}.
+        */
+       private class ProblemAdapter extends AnnotationAdapter {
+               private IProblem problem;
+
+               private Position position;
+
+               public ProblemAdapter(IProblem problem) {
+                       this.problem = problem;
+               }
+
+               public Position getPosition() {
+                       if (position == null) {
+                               position = createPositionFromProblem();
+                       }
+
+                       return position;
+               }
+
+               public Annotation createAnnotation() {
+                       int start = problem.getSourceStart();
+                       if (start < 0) {
+                               return null;
+                       }
+
+                       int length = problem.getSourceEnd() - start + 1;
+                       if (length < 0) {
+                               return null;
+                       }
+
+                       String type;
+                       if (problem.isWarning()) {
+                               type = XMLAnnotation.TYPE_ERROR;
+                       } else if (problem.isError()) {
+                               type = XMLAnnotation.TYPE_WARNING;
+                       } else {
+                               type = XMLAnnotation.TYPE_INFO;
+                       }
+
+                       return new XMLAnnotation(type, false, problem.getMessage());
+               }
+
+               private Position createPositionFromProblem() {
+                       int start = problem.getSourceStart();
+                       if (start < 0) {
+                               return null;
+                       }
+
+                       int length = problem.getSourceEnd() - problem.getSourceStart() + 1;
+                       if (length < 0) {
+                               return null;
+                       }
+
+                       return new Position(start, length);
+               }
+
+       }
+
+       // Instance Variables ------------------------------------------------------
+
+       private ITextEditor editor;
+
+       private XMLDocumentAdapter xmlDocumentAdapter;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Default constructor.
+        */
+       public XMLReconcileStep(ITextEditor editor) {
+               this.editor = editor;
+
+               xmlDocumentAdapter = new XMLDocumentAdapter(getXMLDocument());
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param step
+        *            the step to add to the pipe
+        * @param editor
+        *            the associated text editor
+        */
+       public XMLReconcileStep(IReconcileStep step, ITextEditor editor) {
+               super(step);
+
+               this.editor = editor;
+
+               xmlDocumentAdapter = new XMLDocumentAdapter(getXMLDocument());
+       }
+
+       // AbstractReconcileStep Implementation ------------------------------------
+
+       /*
+        * @see AbstractReconcileStep#reconcileModel(DirtyRegion, IRegion)
+        */
+       protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion,
+                       IRegion subRegion) {
+               IXMLDocument model = xmlDocumentAdapter.getDocument();
+
+               IEditorInput editorInput = null;
+               IFile file = null;
+               if (editor != null) {
+                       editorInput = editor.getEditorInput();
+               }
+
+               if (editorInput instanceof IFileEditorInput)
+                       file = ((IFileEditorInput) editorInput).getFile();
+               ProblemCollector problemCollector = new ProblemCollector();
+               model.reconcile(problemCollector, file);
+
+               List problems = problemCollector.getProblems();
+               IReconcileResult[] retVal = new IReconcileResult[problems.size()];
+               for (int i = 0; i < problems.size(); i++) {
+                       IProblem problem = (IProblem) problems.get(i);
+                       retVal[i] = new ProblemAdapter(problem);
+               }
+
+               return retVal;
+       }
+
+       /*
+        * @see AbstractReconcileStep#getModel()
+        */
+       public IReconcilableModel getModel() {
+               return xmlDocumentAdapter;
+       }
+
+       // Private Methods Implementation ------------------------------------------
+
+       /**
+        * Retrieve the style sheet associated with the editor input.
+        */
+       private IXMLDocument getXMLDocument() {
+               IDocumentProvider documentProvider = editor.getDocumentProvider();
+               if (documentProvider instanceof XMLDocumentProvider) {
+                       XMLDocumentProvider xmlDocumentProvider = (XMLDocumentProvider) documentProvider;
+                       return xmlDocumentProvider.getModel(editor.getEditorInput());
+               }
+
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcilingStrategy.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcilingStrategy.java
new file mode 100644 (file)
index 0000000..47a7798
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLReconcilingStrategy.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.ui.text.IReconcilingParticipant;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcileResult;
+import org.eclipse.jface.text.reconciler.IReconcileStep;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Reconciling strategy for XML document. This class is responsible for keeping
+ * the parsed model in sync with the text.
+ */
+public class XMLReconcilingStrategy implements IReconcilingStrategy,
+               IReconcilingStrategyExtension {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated text editor.
+        */
+       private ITextEditor editor;
+
+       /**
+        * A progress monitor that should be used for long-running operations.
+        */
+       IProgressMonitor progressMonitor;
+
+       /**
+        * The first (and only) reconcile step is the parsing of the style sheet.
+        */
+       private IReconcileStep firstStep;
+
+       // Constructors ------------------------------------------------------------
+
+       public XMLReconcilingStrategy(ITextEditor editor) {
+               this.editor = editor;
+               firstStep = new XMLReconcileStep(editor);
+       }
+
+       // IReconcilingStrategy Implementation -------------------------------------
+
+       /**
+        * @see IReconcilingStrategy#reconcile(DirtyRegion, IRegion)
+        */
+       public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+               removeTemporaryAnnotations();
+               process(firstStep.reconcile(dirtyRegion, subRegion));
+       }
+
+       /**
+        * @see IReconcilingStrategy#reconcile(IRegion)
+        */
+       public void reconcile(IRegion partition) {
+               removeTemporaryAnnotations();
+               process(firstStep.reconcile(partition));
+       }
+
+       /**
+        * @see IReconcilingStrategy#setDocument(IDocument)
+        */
+       public void setDocument(IDocument document) {
+               // FIXME
+               firstStep.setInputModel(null); // new DocumentAdapter(document);
+       }
+
+       // IReconcilingStrategyExtension Implementation ----------------------------
+
+       /**
+        * @see IReconcilingStrategyExtension#initialReconcile()
+        */
+       public void initialReconcile() {
+               process(firstStep.reconcile(null));
+       }
+
+       /**
+        * @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
+        */
+       public void setProgressMonitor(IProgressMonitor monitor) {
+               firstStep.setProgressMonitor(monitor);
+               progressMonitor = monitor;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the annotation model for the editor input.
+        * 
+        * @return the annotation model
+        */
+       IAnnotationModel getAnnotationModel() {
+               IEditorInput input = editor.getEditorInput();
+               return editor.getDocumentProvider().getAnnotationModel(input);
+       }
+
+       /**
+        * Adds results of the reconcilation to the annotation model.
+        */
+       private void process(final IReconcileResult[] results) {
+               if (results == null) {
+                       return;
+               }
+
+               IRunnableWithProgress runnable = new WorkspaceModifyOperation() {
+                       protected void execute(IProgressMonitor monitor) {
+                               for (int i = 0; i < results.length; i++) {
+                                       if ((progressMonitor != null)
+                                                       && (progressMonitor.isCanceled())) {
+                                               return;
+                                       }
+
+                                       if (results[i] instanceof AnnotationAdapter) {
+                                               AnnotationAdapter result = (AnnotationAdapter) results[i];
+                                               Position pos = result.getPosition();
+                                               Annotation annotation = result.createAnnotation();
+                                               getAnnotationModel().addAnnotation(annotation, pos);
+                                       }
+                               }
+                       }
+               };
+
+               try {
+                       runnable.run(null);
+               } catch (InvocationTargetException e) {
+                       e.printStackTrace();
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+
+               if (editor instanceof IReconcilingParticipant) {
+                       ((IReconcilingParticipant) editor).reconciled();
+               }
+       }
+
+       /*
+        * TODO A "real" implementation must be smarter, i.e. don't remove and add
+        * the annotations which are the same.
+        */
+       private void removeTemporaryAnnotations() {
+               Iterator i = getAnnotationModel().getAnnotationIterator();
+               while (i.hasNext()) {
+                       Annotation annotation = (Annotation) i.next();
+                       if (!annotation.isPersistent()) {
+                               getAnnotationModel().removeAnnotation(annotation);
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagRule.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagRule.java
new file mode 100644 (file)
index 0000000..da8fa87
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLTagRule.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * Rule detecting XML tag brackets and name.
+ * 
+ * @author Igor Malinin
+ */
+public class XMLTagRule implements IRule {
+
+       private IToken token;
+
+       public XMLTagRule(IToken token) {
+               this.token = token;
+       }
+
+       public IToken evaluate(ICharacterScanner scanner) {
+               int ch = scanner.read();
+               if (ch == '>') {
+                       return token;
+               }
+               if (ch == '/') {
+                       ch = scanner.read();
+                       if (ch == '>') {
+                               return token;
+                       }
+
+                       scanner.unread();
+                       scanner.unread();
+                       return Token.UNDEFINED;
+               }
+               if (ch == '<') {
+                       ch = scanner.read();
+                       if (ch == '/') {
+                               ch = scanner.read();
+                       }
+                       loop: while (true) {
+                               switch (ch) {
+                               case ICharacterScanner.EOF:
+                               case 0x09:
+                               case 0x0A:
+                               case 0x0D:
+                               case 0x20:
+                                       break loop;
+                               }
+
+                               ch = scanner.read();
+                       }
+
+                       scanner.unread();
+                       return token;
+               }
+               scanner.unread();
+               return Token.UNDEFINED;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagScanner.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagScanner.java
new file mode 100644 (file)
index 0000000..f0ef3d1
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLTagScanner.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLTagScanner extends BufferedRuleBasedScanner {
+
+       /**
+        * Creates a color token scanner.
+        */
+       public XMLTagScanner(Map tokens) {
+               setDefaultReturnToken((Token) tokens
+                               .get(IXMLSyntaxConstants.XML_DEFAULT));
+
+               IToken tag = (Token) tokens.get(IXMLSyntaxConstants.XML_TAG);
+               IToken attribute = (Token) tokens.get(IXMLSyntaxConstants.XML_ATT_NAME);
+
+               IRule[] rules = { new XMLTagRule(tag),
+                               new WordRule(new NameDetector(), attribute), };
+
+               setRules(rules);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTextHover.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTextHover.java
new file mode 100644 (file)
index 0000000..998f415
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLTextHover.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Iterator;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+/**
+ * Implements simple annotation hover to show the associated messages.
+ */
+public class XMLTextHover implements ITextHover {
+       /**
+        * This hovers annotation model.
+        */
+       private IAnnotationModel model;
+
+       /**
+        * Creates a new annotation hover.
+        * 
+        * @param model
+        *            this hover's annotation model
+        */
+       public XMLTextHover(IAnnotationModel model) {
+               this.model = model;
+       }
+
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion region) {
+               Iterator e = new XMLAnnotationIterator(model, true);
+               while (e.hasNext()) {
+                       Annotation a = (Annotation) e.next();
+
+                       Position p = model.getPosition(a);
+                       if (p.overlapsWith(region.getOffset(), region.getLength())) {
+                               String text = a.getText();
+                               if ((text != null) && (text.trim().length() > 0)) {
+                                       return text;
+                               }
+                       }
+               }
+
+               return null;
+       }
+
+       /*
+        * @see ITextHover#getHoverRegion(ITextViewer, int)
+        */
+       public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+               return XMLWordFinder.findWord(textViewer.getDocument(), offset);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLWordFinder.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLWordFinder.java
new file mode 100644 (file)
index 0000000..4e2fbd8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial implementation
+ * 
+ * $Id: XMLWordFinder.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class XMLWordFinder {
+       public static IRegion findWord(IDocument document, int offset) {
+               int length = document.getLength();
+
+               try {
+                       int pos = offset;
+
+                       while (pos >= 0) {
+                               if (!Character.isUnicodeIdentifierPart(document.getChar(pos))) {
+                                       break;
+                               }
+                               --pos;
+                       }
+
+                       int start = pos;
+
+                       pos = offset;
+
+                       while (pos < length) {
+                               if (!Character.isUnicodeIdentifierPart(document.getChar(pos))) {
+                                       break;
+                               }
+                               ++pos;
+                       }
+
+                       int end = pos;
+
+                       if (start == offset) {
+                               return new Region(start, end - start);
+                       }
+
+                       return new Region(start + 1, end - start - 1);
+               } catch (BadLocationException x) {
+                       return null;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/DTDTextTools.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/DTDTextTools.java
new file mode 100644 (file)
index 0000000..bb2fbbc
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDTextTools.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.text;
+
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.ui.text.AbstractTextTools;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DeclScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.SingleTokenScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.TextScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class DTDTextTools extends AbstractTextTools {
+       private static final String[] TOKENS = { IXMLSyntaxConstants.XML_DEFAULT,
+                       IXMLSyntaxConstants.XML_ATT_NAME,
+                       IXMLSyntaxConstants.XML_ATT_VALUE, IXMLSyntaxConstants.XML_ENTITY,
+                       IXMLSyntaxConstants.XML_PI, IXMLSyntaxConstants.XML_COMMENT,
+                       IXMLSyntaxConstants.XML_DECL, IXMLSyntaxConstants.DTD_CONDITIONAL, };
+
+       private static final String[] TYPES = { XMLPartitionScanner.XML_PI,
+                       XMLPartitionScanner.XML_COMMENT, XMLPartitionScanner.XML_DECL,
+                       XMLPartitionScanner.DTD_CONDITIONAL, };
+
+       /** The DTD partitions scanner */
+       private XMLPartitionScanner dtdPartitionScanner;
+
+       /** The DTD text scanner */
+       private TextScanner dtdTextScanner;
+
+       /** The DTD conditional sections scanner */
+       private SingleTokenScanner dtdConditionalScanner;
+
+       /** The XML processing instructions scanner */
+       private SingleTokenScanner xmlPIScanner;
+
+       /** The XML comments scanner */
+       private SingleTokenScanner xmlCommentScanner;
+
+       /** The XML declarations scanner */
+       private DeclScanner xmlDeclScanner;
+
+       /**
+        * Creates a new DTD text tools collection.
+        */
+       public DTDTextTools(IPreferenceStore store) {
+               super(store, TOKENS);
+
+               dtdPartitionScanner = new XMLPartitionScanner(true);
+
+               Map tokens = getTokens();
+
+               dtdTextScanner = new TextScanner(tokens, '%',
+                               IXMLSyntaxConstants.XML_DEFAULT);
+
+               dtdConditionalScanner = new SingleTokenScanner(tokens,
+                               IXMLSyntaxConstants.DTD_CONDITIONAL); // cond
+
+               xmlPIScanner = new SingleTokenScanner(tokens,
+                               IXMLSyntaxConstants.XML_PI);
+
+               xmlCommentScanner = new SingleTokenScanner(tokens,
+                               IXMLSyntaxConstants.XML_COMMENT);
+
+               xmlDeclScanner = new DeclScanner(tokens);
+       }
+
+       /**
+        * 
+        */
+       public IDocumentPartitioner createDTDPartitioner() {
+               return new DefaultPartitioner(dtdPartitionScanner, TYPES);
+       }
+
+       /**
+        * 
+        */
+       public IPartitionTokenScanner getDTDPartitionScanner() {
+               return dtdPartitionScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan DTD text.
+        * 
+        * @return an DTD text scanner
+        */
+       public RuleBasedScanner getDTDTextScanner() {
+               return dtdTextScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan DTD conditional sections.
+        * 
+        * @return an DTD conditional section scanner
+        */
+       public RuleBasedScanner getDTDConditionalScanner() {
+               return dtdConditionalScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML processing
+        * instructions.
+        * 
+        * @return an XML processing instruction scanner
+        */
+       public RuleBasedScanner getXMLPIScanner() {
+               return xmlPIScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML comments.
+        * 
+        * @return an XML comment scanner
+        */
+       public RuleBasedScanner getXMLCommentScanner() {
+               return xmlCommentScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML declarations.
+        * 
+        * @return an XML declaration scanner
+        */
+       public RuleBasedScanner getXMLDeclScanner() {
+               return xmlDeclScanner;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/IXMLSyntaxConstants.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/IXMLSyntaxConstants.java
new file mode 100644 (file)
index 0000000..7f3e194
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: IXMLSyntaxConstants.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.text;
+
+/**
+ * @author Igor Malinin
+ */
+public interface IXMLSyntaxConstants {
+
+       /**
+        * Note: This constant is for internal use only. Clients should not use this
+        * constant. The prefix all color constants start with.
+        */
+       String PREFIX = "xml_"; //$NON-NLS-1$
+
+       /** The style key for XML text. */
+       String XML_DEFAULT = PREFIX + "text"; //$NON-NLS-1$
+
+       /** The style key for XML tag names. */
+       String XML_TAG = PREFIX + "tag"; //$NON-NLS-1$
+
+       /** The style key for XML attribute names. */
+       String XML_ATT_NAME = PREFIX + "attribute"; //$NON-NLS-1$
+
+       /** The style key for XML attribute values. */
+       String XML_ATT_VALUE = PREFIX + "string"; //$NON-NLS-1$
+
+       /** The style key for XML entities. */
+       String XML_ENTITY = PREFIX + "entity"; //$NON-NLS-1$
+
+       /** The style key for XML processing instructions. */
+       String XML_PI = PREFIX + "processing_instruction"; //$NON-NLS-1$
+
+       /** The style key for XML CDATA sections. */
+       String XML_CDATA = PREFIX + "cdata"; //$NON-NLS-1$
+
+       /** The style key for XML comments. */
+       String XML_COMMENT = PREFIX + "comment"; //$NON-NLS-1$
+
+       /** The style key for XML declaration. */
+       String XML_DECL = PREFIX + "declaration"; //$NON-NLS-1$
+
+       /** The style key for external DTD conditional sections. */
+       String DTD_CONDITIONAL = PREFIX + "conditional"; //$NON-NLS-1$
+
+       /** The style key for SMARTY tag names. */
+       String XML_SMARTY = PREFIX + "smarty"; //$NON-NLS-1$
+}
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/XMLTextTools.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/xml/ui/text/XMLTextTools.java
new file mode 100644 (file)
index 0000000..5c6d32b
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLTextTools.java,v 1.4 2006-10-21 23:14:13 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.text;
+
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.ui.text.AbstractTextTools;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DeclScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.PHPXMLPartitionScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.SingleTokenScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.TextScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLCDATAScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLTagScanner;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class XMLTextTools extends AbstractTextTools {
+       /** Text Attributes for XML editors */
+       public static final String[] TOKENS = { IXMLSyntaxConstants.XML_DEFAULT,
+                       IXMLSyntaxConstants.XML_TAG, IXMLSyntaxConstants.XML_ATT_NAME,
+                       IXMLSyntaxConstants.XML_ATT_VALUE, IXMLSyntaxConstants.XML_ENTITY,
+                       IXMLSyntaxConstants.XML_PI, IXMLSyntaxConstants.XML_CDATA,
+                       IXMLSyntaxConstants.XML_COMMENT, IXMLSyntaxConstants.XML_SMARTY,
+                       IXMLSyntaxConstants.XML_DECL, };
+
+       /** Content types for XML editors */
+       public static final String[] TYPES = { XMLPartitionScanner.XML_PI,
+                       XMLPartitionScanner.XML_COMMENT, XMLPartitionScanner.XML_DECL,
+                       XMLPartitionScanner.XML_TAG, XMLPartitionScanner.XML_ATTRIBUTE,
+                       XMLPartitionScanner.XML_CDATA, XMLPartitionScanner.DTD_INTERNAL,
+                       XMLPartitionScanner.DTD_INTERNAL_PI,
+                       XMLPartitionScanner.DTD_INTERNAL_COMMENT,
+                       XMLPartitionScanner.DTD_INTERNAL_DECL, };
+
+       /** The XML partitions scanner */
+       private XMLPartitionScanner xmlPartitionScanner;
+
+       private PHPXMLPartitionScanner phpXMLPartitionScanner;
+
+       /** The XML text scanner */
+       private TextScanner xmlTextScanner;
+
+       /** The DTD text scanner */
+       private TextScanner dtdTextScanner;
+
+       /** The XML tags scanner */
+       private XMLTagScanner xmlTagScanner;
+
+       /** The XML attributes scanner */
+       private TextScanner xmlAttributeScanner;
+
+       /** The XML CDATA sections scanner */
+       private XMLCDATAScanner xmlCDATAScanner;
+
+       /** The XML processing instructions scanner */
+       private SingleTokenScanner xmlPIScanner;
+
+       /** The XML comments scanner */
+       private SingleTokenScanner xmlCommentScanner;
+
+       /** The XML declarations scanner */
+       private DeclScanner xmlDeclScanner;
+
+       public XMLTextTools(IPreferenceStore store) {
+               this(store, TOKENS);
+       }
+
+       /**
+        * Creates a new XML text tools collection.
+        */
+       public XMLTextTools(IPreferenceStore store, String[] strTokens) {
+               super(store, strTokens);
+
+               xmlPartitionScanner = new XMLPartitionScanner(false);
+               phpXMLPartitionScanner = new PHPXMLPartitionScanner(false);
+               Map tokens = getTokens();
+
+               xmlTextScanner = new TextScanner(tokens, '&',
+                               IXMLSyntaxConstants.XML_DEFAULT);
+
+               dtdTextScanner = new TextScanner(tokens, '%',
+                               IXMLSyntaxConstants.XML_DEFAULT);
+
+               xmlPIScanner = new SingleTokenScanner(tokens,
+                               IXMLSyntaxConstants.XML_PI);
+
+               xmlCommentScanner = new SingleTokenScanner(tokens,
+                               IXMLSyntaxConstants.XML_COMMENT);
+
+               xmlDeclScanner = new DeclScanner(tokens);
+
+               xmlTagScanner = new XMLTagScanner(tokens);
+
+               xmlAttributeScanner = new TextScanner(tokens, '&',
+                               IXMLSyntaxConstants.XML_ATT_VALUE);
+
+               xmlCDATAScanner = new XMLCDATAScanner(tokens);
+       }
+
+       /**
+        * 
+        */
+       public IDocumentPartitioner createXMLPartitioner() {
+               return new DefaultPartitioner(xmlPartitionScanner, TYPES);
+       }
+
+       public IDocumentPartitioner createPHPXMLPartitioner() {
+               return new DefaultPartitioner(phpXMLPartitionScanner, TYPES);
+       }
+
+       /**
+        * 
+        */
+       // public IPartitionTokenScanner getXMLPartitionScanner() {
+       // return xmlPartitionScanner;
+       // }
+       /**
+        * Returns a scanner which is configured to scan XML text.
+        * 
+        * @return an XML text scanner
+        */
+       public RuleBasedScanner getXMLTextScanner() {
+               return xmlTextScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan DTD text.
+        * 
+        * @return an DTD text scanner
+        */
+       public RuleBasedScanner getDTDTextScanner() {
+               return dtdTextScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML tags.
+        * 
+        * @return an XML tag scanner
+        */
+       public RuleBasedScanner getXMLTagScanner() {
+               return xmlTagScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML tag attributes.
+        * 
+        * @return an XML tag attribute scanner
+        */
+       public RuleBasedScanner getXMLAttributeScanner() {
+               return xmlAttributeScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML CDATA sections.
+        * 
+        * @return an XML CDATA section scanner
+        */
+       public ITokenScanner getXMLCDATAScanner() {
+               return xmlCDATAScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML processing
+        * instructions.
+        * 
+        * @return an XML processing instruction scanner
+        */
+       public RuleBasedScanner getXMLPIScanner() {
+               return xmlPIScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML comments.
+        * 
+        * @return an XML comment scanner
+        */
+       public RuleBasedScanner getXMLCommentScanner() {
+               return xmlCommentScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML declarations.
+        * 
+        * @return an XML declaration scanner
+        */
+       public RuleBasedScanner getXMLDeclScanner() {
+               return xmlDeclScanner;
+       }
+}