From 00585b19116c9c17d49c5dcf01c620ecd910bd26 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Mon, 1 Oct 2012 15:29:16 +0400 Subject: [PATCH] Refactoring: only SyntaxHighlighterFactory should be used to create highlighters. - SyntaxHighlighter.PROVIDER moved to SyntaxHighlighterFactory. - POVIDER.create() encapsulated into SyntaxHighlighterFactory.getSyntaxHighligher(FileType, Project, VirtualFile() --- .../lang/regexp/RegExpColorsPage.java | 3 +- .../template/FileTypeBasedContextType.java | 3 +- .../impl/FileTemplateConfigurable.java | 886 +++++++++--------- .../psi/impl/search/IndexPatternSearcher.java | 2 +- .../FileTypeEditorHighlighterProviders.java | 3 +- .../openapi/fileTypes/SyntaxHighlighter.java | 2 - .../fileTypes/SyntaxHighlighterFactory.java | 8 +- .../EditorHighlighterFactoryImpl.java | 4 +- .../com/intellij/usages/ChunkExtractor.java | 3 +- .../changes/PreparedFragmentedContent.java | 3 +- .../intellij/lexer/HtmlHighlightingLexer.java | 6 +- 11 files changed, 466 insertions(+), 457 deletions(-) diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpColorsPage.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpColorsPage.java index 1c175c978094..3767143a2335 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpColorsPage.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpColorsPage.java @@ -17,6 +17,7 @@ package org.intellij.lang.regexp; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; import com.intellij.openapi.options.colors.AttributesDescriptor; import com.intellij.openapi.options.colors.ColorDescriptor; import com.intellij.openapi.options.colors.ColorSettingsPage; @@ -69,7 +70,7 @@ public class RegExpColorsPage implements ColorSettingsPage { @NotNull public SyntaxHighlighter getHighlighter() { - final SyntaxHighlighter highlighter = SyntaxHighlighter.PROVIDER.create(RegExpFileType.INSTANCE, null, null); + final SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(RegExpFileType.INSTANCE, null, null); assert highlighter != null; return highlighter; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/FileTypeBasedContextType.java b/platform/lang-impl/src/com/intellij/codeInsight/template/FileTypeBasedContextType.java index 0cc2651b35e3..9939d2c316e6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/FileTypeBasedContextType.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/FileTypeBasedContextType.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.template; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -40,6 +41,6 @@ public abstract class FileTypeBasedContextType extends TemplateContextType { @Override public SyntaxHighlighter createHighlighter() { - return SyntaxHighlighter.PROVIDER.create(myFileType, null, null); + return SyntaxHighlighterFactory.getSyntaxHighlighter(myFileType, null, null); } } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java index 6515a2717fa7..6ffb1c271bcc 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java @@ -1,443 +1,443 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.ide.fileTemplates.impl; - -import com.intellij.codeInsight.template.impl.TemplateColors; -import com.intellij.ide.DataManager; -import com.intellij.ide.IdeBundle; -import com.intellij.ide.fileTemplates.FileTemplate; -import com.intellij.ide.fileTemplates.FileTemplateManager; -import com.intellij.lexer.CompositeLexer; -import com.intellij.lexer.FlexAdapter; -import com.intellij.lexer.Lexer; -import com.intellij.lexer.MergingLexerAdapter; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.EditorFactory; -import com.intellij.openapi.editor.EditorSettings; -import com.intellij.openapi.editor.colors.EditorColors; -import com.intellij.openapi.editor.colors.EditorColorsManager; -import com.intellij.openapi.editor.colors.EditorColorsScheme; -import com.intellij.openapi.editor.colors.TextAttributesKey; -import com.intellij.openapi.editor.event.DocumentAdapter; -import com.intellij.openapi.editor.event.DocumentEvent; -import com.intellij.openapi.editor.ex.EditorEx; -import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter; -import com.intellij.openapi.editor.highlighter.EditorHighlighter; -import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; -import com.intellij.openapi.fileTypes.*; -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Splitter; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiFileFactory; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.TokenSet; -import com.intellij.testFramework.LightVirtualFile; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.ui.SeparatorFactory; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import java.awt.*; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; - -/* - * @author: MYakovlev - * Date: Jul 26, 2002 - * Time: 12:46:00 PM - */ - -public class FileTemplateConfigurable implements Configurable, Configurable.NoScroll { - private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable"); - @NonNls private static final String EMPTY_HTML = ""; - @NonNls private static final String CONTENT_TYPE_PLAIN = "text/plain"; - - private JPanel myMainPanel; - private FileTemplate myTemplate; - private PsiFile myFile; - private Editor myTemplateEditor; - private JTextField myNameField; - private JTextField myExtensionField; - private JCheckBox myAdjustBox; - private JPanel myTopPanel; - private JEditorPane myDescriptionComponent; - private boolean myModified = false; - private URL myDefaultDescriptionUrl; - private final Project myProject = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext()); - - private final ArrayList myChangeListeners = new ArrayList(); - private Splitter mySplitter; - - public FileTemplate getTemplate() { - return myTemplate; - } - - public void setTemplate(FileTemplate template, URL defaultDescription) { - myDefaultDescriptionUrl = defaultDescription; - myTemplate = template; - if (myMainPanel != null) { - reset(); - myNameField.selectAll(); - myExtensionField.selectAll(); - } - } - - public void setShowInternalMessage(String message) { - if (message == null) { - myTopPanel.removeAll(); - myTopPanel.add(new JLabel(IdeBundle.message("label.name")), - new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, - new Insets(0, 0, 0, 2), 0, 0)); - myTopPanel.add(myNameField, - new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, - GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 2), 0, 0)); - myTopPanel.add(new JLabel(IdeBundle.message("label.extension")), - new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, - new Insets(0, 2, 0, 2), 0, 0)); - myTopPanel.add(myExtensionField, - new GridBagConstraints(3, 0, 1, 1, .3, 0.0, GridBagConstraints.CENTER, - GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0)); - myExtensionField.setColumns(7); - } - else { - myTopPanel.removeAll(); - myTopPanel.add(new JLabel(message), - new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.WEST, - GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - myTopPanel.add(Box.createVerticalStrut(myNameField.getPreferredSize().height), - new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, - GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - } - myMainPanel.revalidate(); - myTopPanel.repaint(); - } - - public void setShowAdjustCheckBox(boolean show) { - myAdjustBox.setEnabled(show); - } - - public String getDisplayName() { - return IdeBundle.message("title.file.templates"); - } - - public String getHelpTopic() { - return null; - } - - public JComponent createComponent() { - myMainPanel = new JPanel(new GridBagLayout()); - myNameField = new JTextField(); - myExtensionField = new JTextField(); - mySplitter = new Splitter(true, 0.66f); - - myTemplateEditor = createEditor(); - - myDescriptionComponent = new JEditorPane(UIUtil.HTML_MIME, EMPTY_HTML); - myDescriptionComponent.setEditable(false); - - myAdjustBox = new JCheckBox(IdeBundle.message("checkbox.reformat.according.to.style")); - myTopPanel = new JPanel(new GridBagLayout()); - - JPanel secondPanel = new JPanel(new GridBagLayout()); - secondPanel.add(SeparatorFactory.createSeparator(IdeBundle.message("label.description"), null), - new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, - new Insets(0, 0, 2, 0), 0, 0)); - secondPanel.add(ScrollPaneFactory.createScrollPane(myDescriptionComponent), - new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, - new Insets(2, 0, 0, 0), 0, 0)); - - myMainPanel.add(myTopPanel, - new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.CENTER, - GridBagConstraints.HORIZONTAL, new Insets(0, 0, 2, 0), 0, 0)); - myMainPanel.add(myAdjustBox, - new GridBagConstraints(0, 1, 4, 1, 0.0, 0.0, GridBagConstraints.WEST, - GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0)); - myMainPanel.add(mySplitter, - new GridBagConstraints(0, 2, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, - new Insets(2, 0, 0, 0), 0, 0)); - - mySplitter.setSecondComponent(secondPanel); - setShowInternalMessage(null); - - myNameField.addFocusListener(new FocusAdapter() { - public void focusLost(FocusEvent e) { - onNameChanged(); - } - }); - myExtensionField.addFocusListener(new FocusAdapter() { - public void focusLost(FocusEvent e) { - onNameChanged(); - } - }); - myMainPanel.setPreferredSize(new Dimension(400, 300)); - return myMainPanel; - } - - private Editor createEditor() { - EditorFactory editorFactory = EditorFactory.getInstance(); - Document doc = myFile == null ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText()) : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile); - Editor editor = myProject == null ? editorFactory.createEditor(doc) : editorFactory.createEditor(doc, myProject); - - EditorSettings editorSettings = editor.getSettings(); - editorSettings.setVirtualSpace(false); - editorSettings.setLineMarkerAreaShown(false); - editorSettings.setIndentGuidesShown(false); - editorSettings.setLineNumbersShown(false); - editorSettings.setFoldingOutlineShown(false); - editorSettings.setAdditionalColumnsCount(3); - editorSettings.setAdditionalLinesCount(3); - - EditorColorsScheme scheme = editor.getColorsScheme(); - scheme.setColor(EditorColors.CARET_ROW_COLOR, null); - - editor.getDocument().addDocumentListener(new DocumentAdapter() { - public void documentChanged(DocumentEvent e) { - onTextChanged(); - } - }); - - ((EditorEx)editor).setHighlighter(createHighlighter()); - mySplitter.setFirstComponent(editor.getComponent()); - return editor; - } - - private void onTextChanged() { - myModified = true; - } - - public String getNameValue() { - return myNameField.getText(); - } - - public String getExtensionValue() { - return myExtensionField.getText(); - } - - private void onNameChanged() { - ChangeEvent event = new ChangeEvent(this); - for (ChangeListener changeListener : myChangeListeners) { - changeListener.stateChanged(event); - } - } - - public void addChangeListener(ChangeListener listener) { - if (!myChangeListeners.contains(listener)) { - myChangeListeners.add(listener); - } - } - - public void removeChangeListener(ChangeListener listener) { - myChangeListeners.remove(listener); - } - - public boolean isModified() { - if (myModified) { - return true; - } - String name = (myTemplate == null) ? "" : myTemplate.getName(); - String extension = (myTemplate == null) ? "" : myTemplate.getExtension(); - if (!Comparing.equal(name, myNameField.getText())) { - return true; - } - if (!Comparing.equal(extension, myExtensionField.getText())) { - return true; - } - if (myTemplate != null) { - if (myTemplate.isReformatCode() != myAdjustBox.isSelected()) { - return true; - } - } - return false; - } - - public void apply() throws ConfigurationException { - if (myTemplate != null) { - myTemplate.setText(myTemplateEditor.getDocument().getText()); - String name = myNameField.getText(); - String extension = myExtensionField.getText(); - int lastDotIndex = extension.lastIndexOf("."); - if (lastDotIndex >= 0) { - name += extension.substring(0, lastDotIndex + 1); - extension = extension.substring(lastDotIndex + 1); - } - if (name.length() == 0 || !isValidFilename(name + "." + extension)) { - throw new ConfigurationException(IdeBundle.message("error.invalid.template.file.name.or.extension")); - } - myTemplate.setName(name); - myTemplate.setExtension(extension); - myTemplate.setReformatCode(myAdjustBox.isSelected()); - } - myModified = false; - } - - // TODO: needs to be generalized someday for other profiles - private static boolean isValidFilename(final String filename) { - if ( filename.contains("/") || filename.contains("\\") || filename.contains(":") ) { - return false; - } - final File tempFile = new File (FileUtil.getTempDirectory() + File.separator + filename); - return FileUtil.ensureCanCreateFile(tempFile); - } - - public void reset() { - final String text = (myTemplate == null) ? "" : myTemplate.getText(); - String name = (myTemplate == null) ? "" : myTemplate.getName(); - String extension = (myTemplate == null) ? "" : myTemplate.getExtension(); - String description = (myTemplate == null) ? "" : myTemplate.getDescription(); - - if ((description.length() == 0) && (myDefaultDescriptionUrl != null)) { - try { - description = UrlUtil.loadText(myDefaultDescriptionUrl); - } - catch (IOException e) { - LOG.error(e); - } - } - - EditorFactory.getInstance().releaseEditor(myTemplateEditor); - myFile = createFile(text, name); - myTemplateEditor = createEditor(); - - boolean adjust = (myTemplate != null) && myTemplate.isReformatCode(); - myNameField.setText(name); - myExtensionField.setText(extension); - myAdjustBox.setSelected(adjust); - String desc = description.length() > 0 ? description : EMPTY_HTML; - - // [myakovlev] do not delete these stupid lines! Or you get Exception! - myDescriptionComponent.setContentType(CONTENT_TYPE_PLAIN); - myDescriptionComponent.setEditable(true); - myDescriptionComponent.setText(desc); - myDescriptionComponent.setContentType(UIUtil.HTML_MIME); - myDescriptionComponent.setText(desc); - myDescriptionComponent.setCaretPosition(0); - myDescriptionComponent.setEditable(false); - - myNameField.setEditable((myTemplate != null) && (!myTemplate.isDefault())); - myExtensionField.setEditable((myTemplate != null) && (!myTemplate.isDefault())); - myModified = false; - } - - @Nullable - private PsiFile createFile(final String text, final String name) { - if (myTemplate == null || myProject == null) return null; - - final FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension("ft"); - if (fileType == FileTypes.UNKNOWN) return null; - - final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(name + ".txt.ft", fileType, text, 0, true); - file.getViewProvider().putUserData(FileTemplateManager.DEFAULT_TEMPLATE_PROPERTIES, FileTemplateManager.getInstance().getDefaultProperties(myProject)); - return file; - } - - public void disposeUIResources() { - myMainPanel = null; - if (myTemplateEditor != null) { - EditorFactory.getInstance().releaseEditor(myTemplateEditor); - myTemplateEditor = null; - } - myFile = null; - } - - private EditorHighlighter createHighlighter() { - if (myTemplate != null && myProject != null) { - return EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, new LightVirtualFile("aaa." + myTemplate.getExtension() + ".ft")); - } - else { - FileType fileType = null; - if (myTemplate != null) { - fileType = FileTypeManager.getInstance().getFileTypeByExtension(myTemplate.getExtension()); - } - if (fileType == null) { - fileType = FileTypes.PLAIN_TEXT; - } - SyntaxHighlighter originalHighlighter = SyntaxHighlighter.PROVIDER.create(fileType, null, null); - if (originalHighlighter == null) originalHighlighter = new PlainSyntaxHighlighter(); - return new LexerEditorHighlighter(new TemplateHighlighter(originalHighlighter), EditorColorsManager.getInstance().getGlobalScheme()); - } - } - - private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(FileTemplateTokenType.TEXT); - - private static class TemplateHighlighter extends SyntaxHighlighterBase { - private final Lexer myLexer; - private final SyntaxHighlighter myOriginalHighlighter; - - public TemplateHighlighter(SyntaxHighlighter original) { - myOriginalHighlighter = original; - Lexer originalLexer = original.getHighlightingLexer(); - Lexer templateLexer = new FlexAdapter(new FileTemplateTextLexer()); - templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE); - - myLexer = new CompositeLexer(originalLexer, templateLexer) { - protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) { - if (type2 == FileTemplateTokenType.MACRO || type2 == FileTemplateTokenType.DIRECTIVE) { - return type2; - } - else { - return type1; - } - } - }; - } - - @NotNull - public Lexer getHighlightingLexer() { - return myLexer; - } - - @NotNull - public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { - if (tokenType == FileTemplateTokenType.MACRO) { - return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES); - } - else if (tokenType == FileTemplateTokenType.DIRECTIVE) { - return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES); - } - - return myOriginalHighlighter.getTokenHighlights(tokenType); - } - } - - - public void focusToNameField() { - myNameField.selectAll(); - myNameField.requestFocus(); - } - - public void focusToExtensionField() { - myExtensionField.selectAll(); - myExtensionField.requestFocus(); - } -} +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.codeInsight.template.impl.TemplateColors; +import com.intellij.ide.DataManager; +import com.intellij.ide.IdeBundle; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.lexer.CompositeLexer; +import com.intellij.lexer.FlexAdapter; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.MergingLexerAdapter; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.EditorSettings; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter; +import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; +import com.intellij.openapi.fileTypes.*; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileFactory; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.testFramework.LightVirtualFile; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.SeparatorFactory; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; + +/* + * @author: MYakovlev + * Date: Jul 26, 2002 + * Time: 12:46:00 PM + */ + +public class FileTemplateConfigurable implements Configurable, Configurable.NoScroll { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable"); + @NonNls private static final String EMPTY_HTML = ""; + @NonNls private static final String CONTENT_TYPE_PLAIN = "text/plain"; + + private JPanel myMainPanel; + private FileTemplate myTemplate; + private PsiFile myFile; + private Editor myTemplateEditor; + private JTextField myNameField; + private JTextField myExtensionField; + private JCheckBox myAdjustBox; + private JPanel myTopPanel; + private JEditorPane myDescriptionComponent; + private boolean myModified = false; + private URL myDefaultDescriptionUrl; + private final Project myProject = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext()); + + private final ArrayList myChangeListeners = new ArrayList(); + private Splitter mySplitter; + + public FileTemplate getTemplate() { + return myTemplate; + } + + public void setTemplate(FileTemplate template, URL defaultDescription) { + myDefaultDescriptionUrl = defaultDescription; + myTemplate = template; + if (myMainPanel != null) { + reset(); + myNameField.selectAll(); + myExtensionField.selectAll(); + } + } + + public void setShowInternalMessage(String message) { + if (message == null) { + myTopPanel.removeAll(); + myTopPanel.add(new JLabel(IdeBundle.message("label.name")), + new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 0, 0, 2), 0, 0)); + myTopPanel.add(myNameField, + new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 2), 0, 0)); + myTopPanel.add(new JLabel(IdeBundle.message("label.extension")), + new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(0, 2, 0, 2), 0, 0)); + myTopPanel.add(myExtensionField, + new GridBagConstraints(3, 0, 1, 1, .3, 0.0, GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0)); + myExtensionField.setColumns(7); + } + else { + myTopPanel.removeAll(); + myTopPanel.add(new JLabel(message), + new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + myTopPanel.add(Box.createVerticalStrut(myNameField.getPreferredSize().height), + new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + } + myMainPanel.revalidate(); + myTopPanel.repaint(); + } + + public void setShowAdjustCheckBox(boolean show) { + myAdjustBox.setEnabled(show); + } + + public String getDisplayName() { + return IdeBundle.message("title.file.templates"); + } + + public String getHelpTopic() { + return null; + } + + public JComponent createComponent() { + myMainPanel = new JPanel(new GridBagLayout()); + myNameField = new JTextField(); + myExtensionField = new JTextField(); + mySplitter = new Splitter(true, 0.66f); + + myTemplateEditor = createEditor(); + + myDescriptionComponent = new JEditorPane(UIUtil.HTML_MIME, EMPTY_HTML); + myDescriptionComponent.setEditable(false); + + myAdjustBox = new JCheckBox(IdeBundle.message("checkbox.reformat.according.to.style")); + myTopPanel = new JPanel(new GridBagLayout()); + + JPanel secondPanel = new JPanel(new GridBagLayout()); + secondPanel.add(SeparatorFactory.createSeparator(IdeBundle.message("label.description"), null), + new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 2, 0), 0, 0)); + secondPanel.add(ScrollPaneFactory.createScrollPane(myDescriptionComponent), + new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(2, 0, 0, 0), 0, 0)); + + myMainPanel.add(myTopPanel, + new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, new Insets(0, 0, 2, 0), 0, 0)); + myMainPanel.add(myAdjustBox, + new GridBagConstraints(0, 1, 4, 1, 0.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0)); + myMainPanel.add(mySplitter, + new GridBagConstraints(0, 2, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(2, 0, 0, 0), 0, 0)); + + mySplitter.setSecondComponent(secondPanel); + setShowInternalMessage(null); + + myNameField.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + onNameChanged(); + } + }); + myExtensionField.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + onNameChanged(); + } + }); + myMainPanel.setPreferredSize(new Dimension(400, 300)); + return myMainPanel; + } + + private Editor createEditor() { + EditorFactory editorFactory = EditorFactory.getInstance(); + Document doc = myFile == null ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText()) : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile); + Editor editor = myProject == null ? editorFactory.createEditor(doc) : editorFactory.createEditor(doc, myProject); + + EditorSettings editorSettings = editor.getSettings(); + editorSettings.setVirtualSpace(false); + editorSettings.setLineMarkerAreaShown(false); + editorSettings.setIndentGuidesShown(false); + editorSettings.setLineNumbersShown(false); + editorSettings.setFoldingOutlineShown(false); + editorSettings.setAdditionalColumnsCount(3); + editorSettings.setAdditionalLinesCount(3); + + EditorColorsScheme scheme = editor.getColorsScheme(); + scheme.setColor(EditorColors.CARET_ROW_COLOR, null); + + editor.getDocument().addDocumentListener(new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + onTextChanged(); + } + }); + + ((EditorEx)editor).setHighlighter(createHighlighter()); + mySplitter.setFirstComponent(editor.getComponent()); + return editor; + } + + private void onTextChanged() { + myModified = true; + } + + public String getNameValue() { + return myNameField.getText(); + } + + public String getExtensionValue() { + return myExtensionField.getText(); + } + + private void onNameChanged() { + ChangeEvent event = new ChangeEvent(this); + for (ChangeListener changeListener : myChangeListeners) { + changeListener.stateChanged(event); + } + } + + public void addChangeListener(ChangeListener listener) { + if (!myChangeListeners.contains(listener)) { + myChangeListeners.add(listener); + } + } + + public void removeChangeListener(ChangeListener listener) { + myChangeListeners.remove(listener); + } + + public boolean isModified() { + if (myModified) { + return true; + } + String name = (myTemplate == null) ? "" : myTemplate.getName(); + String extension = (myTemplate == null) ? "" : myTemplate.getExtension(); + if (!Comparing.equal(name, myNameField.getText())) { + return true; + } + if (!Comparing.equal(extension, myExtensionField.getText())) { + return true; + } + if (myTemplate != null) { + if (myTemplate.isReformatCode() != myAdjustBox.isSelected()) { + return true; + } + } + return false; + } + + public void apply() throws ConfigurationException { + if (myTemplate != null) { + myTemplate.setText(myTemplateEditor.getDocument().getText()); + String name = myNameField.getText(); + String extension = myExtensionField.getText(); + int lastDotIndex = extension.lastIndexOf("."); + if (lastDotIndex >= 0) { + name += extension.substring(0, lastDotIndex + 1); + extension = extension.substring(lastDotIndex + 1); + } + if (name.length() == 0 || !isValidFilename(name + "." + extension)) { + throw new ConfigurationException(IdeBundle.message("error.invalid.template.file.name.or.extension")); + } + myTemplate.setName(name); + myTemplate.setExtension(extension); + myTemplate.setReformatCode(myAdjustBox.isSelected()); + } + myModified = false; + } + + // TODO: needs to be generalized someday for other profiles + private static boolean isValidFilename(final String filename) { + if ( filename.contains("/") || filename.contains("\\") || filename.contains(":") ) { + return false; + } + final File tempFile = new File (FileUtil.getTempDirectory() + File.separator + filename); + return FileUtil.ensureCanCreateFile(tempFile); + } + + public void reset() { + final String text = (myTemplate == null) ? "" : myTemplate.getText(); + String name = (myTemplate == null) ? "" : myTemplate.getName(); + String extension = (myTemplate == null) ? "" : myTemplate.getExtension(); + String description = (myTemplate == null) ? "" : myTemplate.getDescription(); + + if ((description.length() == 0) && (myDefaultDescriptionUrl != null)) { + try { + description = UrlUtil.loadText(myDefaultDescriptionUrl); + } + catch (IOException e) { + LOG.error(e); + } + } + + EditorFactory.getInstance().releaseEditor(myTemplateEditor); + myFile = createFile(text, name); + myTemplateEditor = createEditor(); + + boolean adjust = (myTemplate != null) && myTemplate.isReformatCode(); + myNameField.setText(name); + myExtensionField.setText(extension); + myAdjustBox.setSelected(adjust); + String desc = description.length() > 0 ? description : EMPTY_HTML; + + // [myakovlev] do not delete these stupid lines! Or you get Exception! + myDescriptionComponent.setContentType(CONTENT_TYPE_PLAIN); + myDescriptionComponent.setEditable(true); + myDescriptionComponent.setText(desc); + myDescriptionComponent.setContentType(UIUtil.HTML_MIME); + myDescriptionComponent.setText(desc); + myDescriptionComponent.setCaretPosition(0); + myDescriptionComponent.setEditable(false); + + myNameField.setEditable((myTemplate != null) && (!myTemplate.isDefault())); + myExtensionField.setEditable((myTemplate != null) && (!myTemplate.isDefault())); + myModified = false; + } + + @Nullable + private PsiFile createFile(final String text, final String name) { + if (myTemplate == null || myProject == null) return null; + + final FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension("ft"); + if (fileType == FileTypes.UNKNOWN) return null; + + final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(name + ".txt.ft", fileType, text, 0, true); + file.getViewProvider().putUserData(FileTemplateManager.DEFAULT_TEMPLATE_PROPERTIES, FileTemplateManager.getInstance().getDefaultProperties(myProject)); + return file; + } + + public void disposeUIResources() { + myMainPanel = null; + if (myTemplateEditor != null) { + EditorFactory.getInstance().releaseEditor(myTemplateEditor); + myTemplateEditor = null; + } + myFile = null; + } + + private EditorHighlighter createHighlighter() { + if (myTemplate != null && myProject != null) { + return EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, new LightVirtualFile("aaa." + myTemplate.getExtension() + ".ft")); + } + else { + FileType fileType = null; + if (myTemplate != null) { + fileType = FileTypeManager.getInstance().getFileTypeByExtension(myTemplate.getExtension()); + } + if (fileType == null) { + fileType = FileTypes.PLAIN_TEXT; + } + SyntaxHighlighter originalHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, null, null); + if (originalHighlighter == null) originalHighlighter = new PlainSyntaxHighlighter(); + return new LexerEditorHighlighter(new TemplateHighlighter(originalHighlighter), EditorColorsManager.getInstance().getGlobalScheme()); + } + } + + private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(FileTemplateTokenType.TEXT); + + private static class TemplateHighlighter extends SyntaxHighlighterBase { + private final Lexer myLexer; + private final SyntaxHighlighter myOriginalHighlighter; + + public TemplateHighlighter(SyntaxHighlighter original) { + myOriginalHighlighter = original; + Lexer originalLexer = original.getHighlightingLexer(); + Lexer templateLexer = new FlexAdapter(new FileTemplateTextLexer()); + templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE); + + myLexer = new CompositeLexer(originalLexer, templateLexer) { + protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) { + if (type2 == FileTemplateTokenType.MACRO || type2 == FileTemplateTokenType.DIRECTIVE) { + return type2; + } + else { + return type1; + } + } + }; + } + + @NotNull + public Lexer getHighlightingLexer() { + return myLexer; + } + + @NotNull + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + if (tokenType == FileTemplateTokenType.MACRO) { + return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES); + } + else if (tokenType == FileTemplateTokenType.DIRECTIVE) { + return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES); + } + + return myOriginalHighlighter.getTokenHighlights(tokenType); + } + } + + + public void focusToNameField() { + myNameField.selectAll(); + myNameField.requestFocus(); + } + + public void focusToExtensionField() { + myExtensionField.selectAll(); + myExtensionField.requestFocus(); + } +} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java b/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java index 2945ddf4d65c..26004caf6e12 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java @@ -112,7 +112,7 @@ public class IndexPatternSearcher implements QueryExecutor(SyntaxHighlighterProvider.class, "com.intellij.syntaxHighlighter").get(); - /** * Returns the lexer used for highlighting the file. The lexer is invoked incrementally when the file is changed, so it must be * capable of saving/restoring state and resuming lexing from the middle of the file. diff --git a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java index 085ce06765bd..f832bae108ad 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java +++ b/platform/platform-api/src/com/intellij/openapi/fileTypes/SyntaxHighlighterFactory.java @@ -23,14 +23,20 @@ import com.intellij.lang.Language; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public abstract class SyntaxHighlighterFactory { - public static SyntaxHighlighterLanguageFactory LANGUAGE_FACTORY = new SyntaxHighlighterLanguageFactory(); + public static final SyntaxHighlighterLanguageFactory LANGUAGE_FACTORY = new SyntaxHighlighterLanguageFactory(); + private static final SyntaxHighlighterProvider PROVIDER = new FileTypeExtensionFactory(SyntaxHighlighterProvider.class, "com.intellij.syntaxHighlighter").get(); public static SyntaxHighlighter getSyntaxHighlighter(Language lang, Project project, VirtualFile virtualFile) { return LANGUAGE_FACTORY.forLanguage(lang).getSyntaxHighlighter(project, virtualFile); } + @Nullable + public static SyntaxHighlighter getSyntaxHighlighter(final FileType fileType, final @Nullable Project project, final @Nullable VirtualFile virtualFile) { + return PROVIDER.create(fileType, project, virtualFile); + } /** * Override this method to provide syntax highlighting (coloring) capabilities for your language implementation. diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java index 4c32efd347a6..27de1506dcc8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java @@ -47,7 +47,7 @@ public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory { return FileTypeEditorHighlighterProviders.INSTANCE.forFileType(fileType).getEditorHighlighter(project, fileType, null, settings); } - SyntaxHighlighter highlighter = SyntaxHighlighter.PROVIDER.create(fileType, project, null); + SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, null); return createEditorHighlighter(highlighter, settings); } @@ -90,7 +90,7 @@ public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory { } } if (highlighter == null) { - highlighter = SyntaxHighlighter.PROVIDER.create(fileType, project, vFile); + highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, vFile); } return createEditorHighlighter(highlighter, settings); } diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java index 0e0bbdb3c1df..39d84cc6c19a 100644 --- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java +++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java @@ -28,6 +28,7 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter; import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Segment; import com.intellij.openapi.util.TextRange; @@ -109,7 +110,7 @@ public class ChunkExtractor { myDocument = PsiDocumentManager.getInstance(project).getDocument(file); LOG.assertTrue(myDocument != null); final FileType fileType = file.getFileType(); - final SyntaxHighlighter highlighter = SyntaxHighlighter.PROVIDER.create(fileType, project, file.getVirtualFile()); + final SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, file.getVirtualFile()); myHighlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter; myLexer = myHighlighter.getHighlightingLexer(); myLexer.start(myDocument.getCharsSequence()); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java index 9d58b3e10272..2c2d0634b709 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java @@ -24,6 +24,7 @@ import com.intellij.openapi.editor.highlighter.*; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Getter; @@ -324,7 +325,7 @@ public class PreparedFragmentedContent { private void setHighlighters(final Document oldDocument, final Document document, List> ranges) { EditorHighlighterFactory editorHighlighterFactory = EditorHighlighterFactory.getInstance(); - final SyntaxHighlighter syntaxHighlighter = SyntaxHighlighter.PROVIDER.create(myFileType, myProject, null); + final SyntaxHighlighter syntaxHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(myFileType, myProject, null); final EditorHighlighter highlighter = editorHighlighterFactory.createEditorHighlighter(syntaxHighlighter, EditorColorsManager.getInstance().getGlobalScheme()); diff --git a/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java b/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java index 01911b6b477e..df1134cecbc7 100644 --- a/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java +++ b/xml/impl/src/com/intellij/lexer/HtmlHighlightingLexer.java @@ -18,7 +18,7 @@ package com.intellij.lexer; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; -import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; import com.intellij.psi.tree.IElementType; import com.intellij.psi.xml.XmlTokenType; import org.jetbrains.annotations.Nullable; @@ -104,13 +104,13 @@ public class HtmlHighlightingLexer extends BaseHtmlLexer { Lexer newLexer = null; if (hasSeenStyle()) { if (styleLexer==null) { - styleLexer = (ourStyleFileType!=null)? SyntaxHighlighter.PROVIDER.create(ourStyleFileType, null, null).getHighlightingLexer():null; + styleLexer = (ourStyleFileType!=null)? SyntaxHighlighterFactory.getSyntaxHighlighter(ourStyleFileType, null, null).getHighlightingLexer():null; } newLexer = styleLexer; } else if (hasSeenScript()) { if (scriptLexer==null) { - scriptLexer = (ourScriptFileType!=null)? SyntaxHighlighter.PROVIDER.create(ourScriptFileType, null, null).getHighlightingLexer():null; + scriptLexer = (ourScriptFileType!=null)? SyntaxHighlighterFactory.getSyntaxHighlighter(ourScriptFileType, null, null).getHighlightingLexer():null; } newLexer = scriptLexer; } else newLexer = createELLexer(newLexer);