| /* |
| * 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.xdebugger.impl.ui; |
| |
| import com.intellij.ide.DataManager; |
| import com.intellij.lang.Language; |
| import com.intellij.openapi.actionSystem.AnAction; |
| import com.intellij.openapi.actionSystem.AnActionEvent; |
| import com.intellij.openapi.actionSystem.DataContext; |
| import com.intellij.openapi.actionSystem.DefaultActionGroup; |
| import com.intellij.openapi.editor.Document; |
| import com.intellij.openapi.editor.Editor; |
| import com.intellij.openapi.fileTypes.FileType; |
| import com.intellij.openapi.fileTypes.LanguageFileType; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.popup.JBPopupFactory; |
| import com.intellij.openapi.ui.popup.ListPopup; |
| import com.intellij.openapi.util.IconLoader; |
| import com.intellij.openapi.wm.IdeFocusManager; |
| import com.intellij.reference.SoftReference; |
| import com.intellij.ui.ClickListener; |
| import com.intellij.xdebugger.XExpression; |
| import com.intellij.xdebugger.XSourcePosition; |
| import com.intellij.xdebugger.evaluation.EvaluationMode; |
| import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; |
| import com.intellij.xdebugger.impl.XDebuggerHistoryManager; |
| import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.border.EmptyBorder; |
| import java.awt.*; |
| import java.awt.event.MouseEvent; |
| import java.lang.ref.WeakReference; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| |
| /** |
| * @author nik |
| */ |
| public abstract class XDebuggerEditorBase { |
| private final Project myProject; |
| private final XDebuggerEditorsProvider myDebuggerEditorsProvider; |
| @NotNull private final EvaluationMode myMode; |
| @Nullable private final String myHistoryId; |
| @Nullable private XSourcePosition mySourcePosition; |
| private int myHistoryIndex; |
| |
| private final JLabel myChooseFactory = new JLabel(); |
| private WeakReference<ListPopup> myPopup; |
| |
| protected XDebuggerEditorBase(final Project project, |
| @NotNull XDebuggerEditorsProvider debuggerEditorsProvider, |
| @NotNull EvaluationMode mode, |
| @Nullable @NonNls String historyId, |
| final @Nullable XSourcePosition sourcePosition) { |
| myProject = project; |
| myDebuggerEditorsProvider = debuggerEditorsProvider; |
| myMode = mode; |
| myHistoryId = historyId; |
| mySourcePosition = sourcePosition; |
| |
| myChooseFactory.setToolTipText("Click to change the language"); |
| myChooseFactory.setBorder(new EmptyBorder(0, 3, 0, 3)); |
| new ClickListener() { |
| @Override |
| public boolean onClick(@NotNull MouseEvent e, int clickCount) { |
| ListPopup oldPopup = SoftReference.dereference(myPopup); |
| if (oldPopup != null && !oldPopup.isDisposed()) { |
| oldPopup.cancel(); |
| myPopup = null; |
| return true; |
| } |
| ListPopup popup = createLanguagePopup(); |
| popup.showUnderneathOf(myChooseFactory); |
| myPopup = new WeakReference<ListPopup>(popup); |
| return true; |
| } |
| }.installOn(myChooseFactory); |
| } |
| |
| private ListPopup createLanguagePopup() { |
| DefaultActionGroup actions = new DefaultActionGroup(); |
| for (final Language language : getEditorsProvider().getSupportedLanguages(myProject, mySourcePosition)) { |
| actions.add(new AnAction(language.getDisplayName(), null, language.getAssociatedFileType().getIcon()) { |
| @Override |
| public void actionPerformed(AnActionEvent e) { |
| XExpression currentExpression = getExpression(); |
| setExpression(new XExpressionImpl(currentExpression.getExpression(), language, currentExpression.getCustomInfo())); |
| IdeFocusManager.getInstance(getProject()).requestFocus(getComponent(), true); |
| } |
| }); |
| } |
| |
| DataContext dataContext = DataManager.getInstance().getDataContext(getComponent()); |
| return JBPopupFactory.getInstance().createActionGroupPopup("Choose language", actions, dataContext, |
| JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, |
| false); |
| } |
| |
| protected JPanel addChooseFactoryLabel(JComponent component, boolean top) { |
| JPanel panel = new JPanel(new BorderLayout()); |
| panel.add(component, BorderLayout.CENTER); |
| |
| JPanel factoryPanel = new JPanel(new BorderLayout()); |
| factoryPanel.add(myChooseFactory, top ? BorderLayout.NORTH : BorderLayout.CENTER); |
| panel.add(factoryPanel, BorderLayout.WEST); |
| return panel; |
| } |
| |
| public void setSourcePosition(@Nullable XSourcePosition sourcePosition) { |
| if (mySourcePosition != sourcePosition) { |
| mySourcePosition = sourcePosition; |
| setExpression(getExpression(), false); |
| } |
| } |
| |
| @NotNull |
| public EvaluationMode getMode() { |
| return myMode; |
| } |
| |
| @Nullable |
| public abstract Editor getEditor(); |
| |
| public abstract JComponent getComponent(); |
| |
| protected abstract void doSetText(XExpression text); |
| |
| public void setExpression(@Nullable XExpression text) { |
| setExpression(text, true); |
| } |
| |
| private void setExpression(@Nullable XExpression text, boolean saveInHistory) { |
| if (text == null) { |
| text = getMode() == EvaluationMode.EXPRESSION ? XExpressionImpl.EMPTY_EXPRESSION : XExpressionImpl.EMPTY_CODE_FRAGMENT; |
| } |
| if (saveInHistory) { |
| saveTextInHistory(text); |
| } |
| Language language = text.getLanguage(); |
| if (language == null) { |
| if (mySourcePosition != null) { |
| language = getFileTypeLanguage(mySourcePosition.getFile().getFileType()); |
| } |
| if (language == null) { |
| language = getFileTypeLanguage(getEditorsProvider().getFileType()); |
| } |
| } |
| text = new XExpressionImpl(text.getExpression(), language, text.getCustomInfo(), getMode()); |
| |
| Collection<Language> languages = getEditorsProvider().getSupportedLanguages(myProject, mySourcePosition); |
| boolean many = languages.size() > 1; |
| |
| if (language != null) { |
| myChooseFactory.setVisible(many); |
| } |
| myChooseFactory.setVisible(myChooseFactory.isVisible() || many); |
| //myChooseFactory.setEnabled(many && languages.contains(language)); |
| |
| if (language != null && language.getAssociatedFileType() != null) { |
| Icon icon = language.getAssociatedFileType().getIcon(); |
| myChooseFactory.setIcon(icon); |
| myChooseFactory.setDisabledIcon(IconLoader.getDisabledIcon(icon)); |
| } |
| |
| doSetText(text); |
| } |
| |
| @Nullable |
| public static Language getFileTypeLanguage(@Nullable FileType fileType) { |
| if (fileType instanceof LanguageFileType) { |
| return ((LanguageFileType)fileType).getLanguage(); |
| } |
| return null; |
| } |
| |
| public abstract XExpression getExpression(); |
| |
| @Nullable |
| public abstract JComponent getPreferredFocusedComponent(); |
| |
| public abstract void selectAll(); |
| |
| protected void onHistoryChanged() { |
| } |
| |
| protected List<XExpression> getRecentExpressions() { |
| if (myHistoryId != null) { |
| return XDebuggerHistoryManager.getInstance(myProject).getRecentExpressions(myHistoryId); |
| } |
| return Collections.emptyList(); |
| } |
| |
| public void saveTextInHistory() { |
| saveTextInHistory(getExpression()); |
| } |
| |
| private void saveTextInHistory(final XExpression text) { |
| if (myHistoryId != null) { |
| boolean update = XDebuggerHistoryManager.getInstance(myProject).addRecentExpression(myHistoryId, text); |
| myHistoryIndex = 0; |
| if (update) { |
| onHistoryChanged(); |
| } |
| } |
| } |
| |
| public XDebuggerEditorsProvider getEditorsProvider() { |
| return myDebuggerEditorsProvider; |
| } |
| |
| public Project getProject() { |
| return myProject; |
| } |
| |
| protected Document createDocument(final XExpression text) { |
| return getEditorsProvider().createDocument(getProject(), text, mySourcePosition, myMode); |
| } |
| |
| public boolean canGoBackward() { |
| return myHistoryIndex < getRecentExpressions().size()-1; |
| } |
| |
| public boolean canGoForward() { |
| return myHistoryIndex > 0; |
| } |
| |
| public void goBackward() { |
| final List<XExpression> expressions = getRecentExpressions(); |
| if (myHistoryIndex < expressions.size() - 1) { |
| myHistoryIndex++; |
| doSetText(expressions.get(myHistoryIndex)); |
| } |
| } |
| |
| public void goForward() { |
| final List<XExpression> expressions = getRecentExpressions(); |
| if (myHistoryIndex > 0) { |
| myHistoryIndex--; |
| doSetText(expressions.get(myHistoryIndex)); |
| } |
| } |
| } |