removed old DebuggerEditor and related

This commit is contained in:
Egor.Ushakov
2016-02-18 15:21:45 +03:00
parent c3254e57a7
commit 1d41daae07
11 changed files with 30 additions and 1121 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -20,9 +20,9 @@ import com.intellij.codeInsight.generation.surroundWith.JavaExpressionSurrounder
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerInvocationUtil;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
@@ -52,7 +52,7 @@ public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder {
if (!expr.isPhysical()) return false;
PsiFile file = expr.getContainingFile();
if (!(file instanceof PsiCodeFragment)) return false;
if (file.getUserData(DebuggerExpressionComboBox.KEY) == null) {
if (!DefaultCodeFragmentFactory.isDebuggerFile(file)) {
return false;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -18,7 +18,6 @@ package com.intellij.debugger.engine.evaluation;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -26,6 +25,6 @@ public class DebuggerHighlightFilter implements HighlightInfoFilter {
public boolean accept(@NotNull HighlightInfo highlightInfo, PsiFile file) {
return highlightInfo.type != HighlightInfoType.UNHANDLED_EXCEPTION ||
file == null ||
file.getUserData(DebuggerExpressionComboBox.KEY) == null;
!DefaultCodeFragmentFactory.isDebuggerFile(file);
}
}
@@ -29,6 +29,7 @@ import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.util.PairFunction;
@@ -73,7 +74,7 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory {
}
fragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE);
//noinspection HardCodedStringLiteral
fragment.putUserData(DebuggerExpressionComboBox.KEY, "DebuggerComboBoxEditor.IS_DEBUGGER_EDITOR");
fragment.putUserData(KEY, "DebuggerComboBoxEditor.IS_DEBUGGER_EDITOR");
fragment.putCopyableUserData(JavaCompletionUtil.DYNAMIC_TYPE_EVALUATOR, new PairFunction<PsiExpression, CompletionParameters, PsiType>() {
public PsiType fun(PsiExpression expression, CompletionParameters parameters) {
if (!RuntimeTypeEvaluator.isSubtypeable(expression)) {
@@ -129,4 +130,10 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory {
public EvaluatorBuilder getEvaluatorBuilder() {
return EvaluatorBuilderImpl.getInstance();
}
public static final Key<String> KEY = Key.create("DefaultCodeFragmentFactory.KEY");
public static boolean isDebuggerFile(PsiFile file) {
return file.getUserData(KEY) != null || file.getUserData(DebuggerExpressionComboBox.KEY) != null;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -15,7 +15,6 @@
*/
package com.intellij.debugger.engine.evaluation;
import com.intellij.debugger.ui.DebuggerEditorImpl;
import com.intellij.lang.LanguageUtil;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
@@ -23,7 +22,10 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.JavaCodeFragment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpressionCodeFragment;
import com.intellij.psi.PsiFile;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.evaluation.EvaluationMode;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
@@ -37,6 +39,8 @@ public final class TextWithImportsImpl implements TextWithImports{
private final FileType myFileType;
private final String myImports;
private static final char SEPARATOR = 13;
public TextWithImportsImpl(@NotNull PsiElement expression) {
myKind = CodeFragmentKind.EXPRESSION;
final String text = expression.getText();
@@ -70,7 +74,7 @@ public final class TextWithImportsImpl implements TextWithImports{
}
private static Trinity<String, String, FileType> parseExternalForm(String s) {
String[] split = s.split(String.valueOf(DebuggerEditorImpl.SEPARATOR));
String[] split = s.split(String.valueOf(SEPARATOR));
return Trinity.create(split[0], split.length > 1 ? split[1] : "", split.length > 2 ? FileTypeManager.getInstance().getStdFileType(split[2]) : null);
}
@@ -105,10 +109,10 @@ public final class TextWithImportsImpl implements TextWithImports{
public String toExternalForm() {
String result = myText;
if (StringUtil.isNotEmpty(myImports) || myFileType != null) {
result += DebuggerEditorImpl.SEPARATOR + myImports;
result += SEPARATOR + myImports;
}
if (myFileType != null) {
result += DebuggerEditorImpl.SEPARATOR + myFileType.getName();
result += SEPARATOR + myFileType.getName();
}
return result;
}
@@ -1,34 +0,0 @@
/*
* Copyright 2000-2015 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.debugger.ui;
import com.intellij.debugger.engine.evaluation.TextWithImports;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public abstract class CompletionEditor extends JComponent {
public abstract void setText(TextWithImports text);
public abstract TextWithImports getText();
public abstract void setContext(@Nullable PsiElement context);
public abstract PsiElement getContext();
public abstract String getRecentsId();
}
@@ -1,321 +0,0 @@
/*
* Copyright 2000-2016 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.debugger.ui;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.engine.evaluation.CodeFragmentFactory;
import com.intellij.debugger.engine.evaluation.CodeFragmentFactoryContextWrapper;
import com.intellij.debugger.engine.evaluation.TextWithImports;
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.impl.PositionUtil;
import com.intellij.ide.DataManager;
import com.intellij.openapi.Disposable;
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.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.fileTypes.FileType;
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.psi.*;
import com.intellij.psi.impl.PsiDocumentManagerBase;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.reference.SoftReference;
import com.intellij.ui.ClickListener;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.impl.XDebuggerHistoryManager;
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.List;
/**
* @author lex
*/
public abstract class DebuggerEditorImpl extends CompletionEditor {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerEditorImpl");
public static final char SEPARATOR = 13;
private final Project myProject;
private PsiElement myContext;
private PsiType myThisType;
private final String myRecentsId;
private final List<DocumentListener> myDocumentListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private Document myCurrentDocument;
private final JLabel myChooseFactory = new JLabel();
private WeakReference<ListPopup> myPopup;
private CodeFragmentFactory myFactory;
protected boolean myInitialFactory;
public DebuggerEditorImpl(@NotNull Project project, @NotNull CodeFragmentFactory factory, @NotNull Disposable parentDisposable, @Nullable PsiElement context, @Nullable String recentsId) {
myProject = project;
myContext = context;
myRecentsId = recentsId;
PsiManager.getInstance(project).addPsiTreeChangeListener(new PsiTreeChangeAdapter() {
@Override
public void childRemoved(@NotNull PsiTreeChangeEvent event) {
checkContext();
}
@Override
public void childReplaced(@NotNull PsiTreeChangeEvent event) {
checkContext();
}
@Override
public void childMoved(@NotNull PsiTreeChangeEvent event) {
checkContext();
}
private void checkContext() {
PsiElement contextElement = getContext();
if (contextElement == null || !contextElement.isValid()) {
DebuggerManagerEx manager = DebuggerManagerEx.getInstanceEx(myProject);
if (manager == null) {
LOG.error("Cannot obtain debugger manager for project " + myProject);
return;
}
PsiElement newContextElement = PositionUtil.getContextElement(manager.getContextManager().getContext());
setContext(newContextElement != null && newContextElement.isValid() ? newContextElement : null);
}
}
}, parentDisposable);
setFactory(factory);
myInitialFactory = true;
setFocusable(false);
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;
}
if (myContext == null) {
return true;
}
ListPopup popup = createLanguagePopup();
popup.showUnderneathOf(myChooseFactory);
myPopup = new WeakReference<>(popup);
return true;
}
}.installOn(myChooseFactory);
}
private ListPopup createLanguagePopup() {
DefaultActionGroup actions = new DefaultActionGroup();
for (final CodeFragmentFactory fragmentFactory : DebuggerUtilsEx.getCodeFragmentFactories(myContext)) {
actions.add(new AnAction(fragmentFactory.getFileType().getLanguage().getDisplayName(), null, fragmentFactory.getFileType().getIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
setFactory(fragmentFactory);
setText(getText());
IdeFocusManager.getInstance(getProject()).requestFocus(DebuggerEditorImpl.this, true);
}
});
}
DataContext dataContext = DataManager.getInstance().getDataContext(this);
return JBPopupFactory.getInstance().createActionGroupPopup("Choose Language", actions, dataContext,
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
false);
}
@Override
public void setEnabled(boolean enabled) {
myChooseFactory.setEnabled(enabled);
super.setEnabled(enabled);
}
protected TextWithImports createItem(Document document, Project project) {
if (document != null) {
PsiDocumentManager.getInstance(project).commitDocument(document);
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (psiFile != null) {
return createText(psiFile.getText(), ((JavaCodeFragment)psiFile).importsToString());
}
}
return createText("");
}
protected TextWithImports createText(String text) {
return createText(text, "");
}
protected abstract TextWithImports createText(String text, String importsString);
public abstract JComponent getPreferredFocusedComponent();
@Override
public void setContext(@Nullable PsiElement context) {
myContext = context;
List<CodeFragmentFactory> factories = DebuggerUtilsEx.getCodeFragmentFactories(context);
boolean many = factories.size() > 1;
if (myInitialFactory) {
myInitialFactory = false;
setFactory(factories.get(0));
myChooseFactory.setVisible(many);
}
myChooseFactory.setVisible(myChooseFactory.isVisible() || many);
myChooseFactory.setEnabled(many && factories.contains(myFactory));
updateEditorUi();
}
@Override
public void setText(TextWithImports text) {
doSetText(text);
updateEditorUi();
}
protected abstract void doSetText(TextWithImports text);
protected abstract void updateEditorUi();
@Override
public PsiElement getContext() {
return myContext;
}
protected Project getProject() {
return myProject;
}
@Override
public void requestFocus() {
getPreferredFocusedComponent().requestFocus();
}
public void setThisType(PsiType thisType) {
myThisType = thisType;
}
@Nullable
protected Document createDocument(TextWithImports item) {
LOG.assertTrue(myContext == null || myContext.isValid());
if(item == null) {
item = createText("");
}
JavaCodeFragment codeFragment = getCurrentFactory().createPresentationCodeFragment(item, myContext, getProject());
codeFragment.forceResolveScope(GlobalSearchScope.allScope(myProject));
if (myThisType != null) {
codeFragment.setThisType(myThisType);
}
else if (myContext != null) {
final PsiClass contextClass = PsiTreeUtil.getNonStrictParentOfType(myContext, PsiClass.class);
if (contextClass != null) {
final PsiClassType contextType = JavaPsiFacade.getInstance(codeFragment.getProject()).getElementFactory().createType(contextClass);
codeFragment.setThisType(contextType);
}
}
if(myCurrentDocument != null) {
for (DocumentListener documentListener : myDocumentListeners) {
myCurrentDocument.removeDocumentListener(documentListener);
}
}
myCurrentDocument = PsiDocumentManager.getInstance(getProject()).getDocument(codeFragment);
if (myCurrentDocument != null) {
((PsiDocumentManagerBase)PsiDocumentManager.getInstance(getProject())).associatePsi(myCurrentDocument, codeFragment);
for (DocumentListener documentListener : myDocumentListeners) {
myCurrentDocument.addDocumentListener(documentListener);
}
}
return myCurrentDocument;
}
@Override
public String getRecentsId() {
return myRecentsId;
}
public void addRecent(TextWithImports text) {
if(getRecentsId() != null && text != null && !text.isEmpty()){
XDebuggerHistoryManager.getInstance(getProject()).addRecentExpression(getRecentsId(), TextWithImportsImpl.toXExpression(text));
}
}
public void addDocumentListener(DocumentListener listener) {
myDocumentListeners.add(listener);
if(myCurrentDocument != null) {
myCurrentDocument.addDocumentListener(listener);
}
}
public void removeDocumentListener(DocumentListener listener) {
myDocumentListeners.remove(listener);
if(myCurrentDocument != null) {
myCurrentDocument.removeDocumentListener(listener);
}
}
protected void restoreFactory(TextWithImports text) {
FileType fileType = text.getFileType();
if (fileType == null) return;
if (myContext == null) return;
setFactory(DebuggerUtilsEx.getCodeFragmentFactory(myContext, text.getFileType()));
}
private void setFactory(@NotNull CodeFragmentFactory factory) {
myFactory = factory;
Icon icon = getCurrentFactory().getFileType().getIcon();
myChooseFactory.setIcon(icon);
myChooseFactory.setDisabledIcon(IconLoader.getDisabledIcon(icon));
}
protected CodeFragmentFactory getCurrentFactory() {
return myFactory instanceof CodeFragmentFactoryContextWrapper ? myFactory : new CodeFragmentFactoryContextWrapper(myFactory);
}
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;
}
}
@@ -15,339 +15,14 @@
*/
package com.intellij.debugger.ui;
import com.intellij.debugger.engine.evaluation.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.ui.EditorComboBoxEditor;
import com.intellij.ui.EditorComboBoxRenderer;
import com.intellij.ui.EditorTextField;
import com.intellij.xdebugger.impl.XDebuggerHistoryManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.plaf.basic.ComboPopup;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author ven
*/
public class DebuggerExpressionComboBox extends DebuggerEditorImpl {
@Deprecated
public class DebuggerExpressionComboBox {
/**
* @deprecated use {@link DefaultCodeFragmentFactory#KEY} instead
*/
@Deprecated
public static final Key<String> KEY = Key.create("DebuggerComboBoxEditor.KEY");
public static final int MAX_ROWS = 20;
private final MyEditorComboBoxEditor myEditor;
private final ComboBox myComboBox;
private class MyEditorComboBoxEditor extends EditorComboBoxEditor {
public MyEditorComboBoxEditor(Project project, FileType fileType) {
super(project, fileType);
}
public Object getItem() {
Document document = (Document)super.getItem();
return createItem(document, getProject());
}
public void setItem(Object item) {
TextWithImports twi = (TextWithImports)item;
if (twi != null) {
restoreFactory(twi);
}
final Document document = createDocument(twi);
getEditorComponent().setNewDocumentAndFileType(getCurrentFactory().getFileType(), document);
super.setItem(document);
// need to replace newlines with spaces, see IDEA-81789
if (document != null) {
document.addDocumentListener(REPLACE_NEWLINES_LISTENER);
}
/* Causes PSI being modified from PSI events. See IDEADEV-22102
final Editor editor = getEditor();
if (editor != null) {
DaemonCodeAnalyzer.getInstance(getProject()).updateVisibleHighlighters(editor);
}
*/
}
}
private static final DocumentListener REPLACE_NEWLINES_LISTENER = new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
final String text = e.getNewFragment().toString();
final String replaced = text.replace('\n', ' ');
if (replaced != text) {
e.getDocument().replaceString(e.getOffset(), e.getOffset() + e.getNewLength(), replaced);
}
}
};
public DebuggerExpressionComboBox(@NotNull Project project, @NotNull Disposable parentDisposable, @Nullable PsiElement context, @Nullable String recentsId) {
this(project, parentDisposable, context, recentsId, DefaultCodeFragmentFactory.getInstance());
}
public DebuggerExpressionComboBox(@NotNull Project project, @NotNull Disposable parentDisposable, @Nullable PsiElement context, @Nullable String recentsId, @NotNull CodeFragmentFactory factory) {
super(project, factory, parentDisposable, context, recentsId);
setLayout(new BorderLayout(0, 0));
myComboBox = new ComboBox(new MyComboboxModel(getRecents()), 100);
myComboBox.setSwingPopup(false);
// Have to turn this off because when used in DebuggerTreeInplaceEditor, the combobox popup is hidden on every change of selection
// See comment to SynthComboBoxUI.FocusHandler.focusLost()
myComboBox.setLightWeightPopupEnabled(false);
myEditor = new MyEditorComboBoxEditor(getProject(), getCurrentFactory().getFileType());
//noinspection GtkPreferredJComboBoxRenderer
myComboBox.setRenderer(new EditorComboBoxRenderer(myEditor));
myComboBox.setEditable(true);
myComboBox.setEditor(myEditor);
add(addChooseFactoryLabel(myComboBox, false));
}
public void selectPopupValue() {
//selectAll();
final Object currentPopupValue = getCurrentPopupValue();
if (currentPopupValue != null) {
myComboBox.getModel().setSelectedItem(currentPopupValue);
myComboBox.getEditor().setItem(currentPopupValue);
}
myComboBox.setPopupVisible(false);
}
public boolean isPopupVisible() {
return myComboBox.isVisible() && myComboBox.isPopupVisible();
}
public void setPopupVisible(final boolean b) {
myComboBox.setPopupVisible(b);
}
@Nullable
public Object getCurrentPopupValue() {
if (!isPopupVisible()) return null;
final ComboPopup popup = myComboBox.getPopup();
if (popup != null) {
return popup.getList().getSelectedValue();
}
return null;
}
@Override
protected void doSetText(TextWithImports item) {
final String itemText = item.getText().replace('\n', ' ');
restoreFactory(item);
item.setText(itemText);
if (!StringUtil.isEmpty(itemText)) {
if (myComboBox.getItemCount() == 0 || !item.equals(myComboBox.getItemAt(0))) {
myComboBox.insertItemAt(item, 0);
}
}
if (myComboBox.getItemCount() > 0) {
myComboBox.setSelectedIndex(0);
}
myComboBox.getEditor().setItem(item);
}
@Override
protected void updateEditorUi() {
}
public TextWithImports getText() {
return (TextWithImports)myComboBox.getEditor().getItem();
}
@Nullable
private List<TextWithImports> getRecents() {
final String recentsId = getRecentsId();
if (recentsId != null) {
return XDebuggerHistoryManager.getInstance(getProject()).getRecentExpressions(recentsId).stream()
.filter(expression -> expression.getExpression().indexOf('\n') == -1)
.map(TextWithImportsImpl::fromXExpression)
.collect(Collectors.toList());
}
return null;
}
public Dimension getMinimumSize() {
Dimension size = super.getMinimumSize();
size.width = 100;
return size;
}
public TextWithImports createText(String text, String importsString) {
return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, text, importsString, getCurrentFactory().getFileType());
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
myComboBox.setEnabled(enabled);
//if (enabled) {
// final ComboBoxEditor editor = myComboBox.getEditor();
// editor.setItem(editor.getItem());
//}
}
public JComponent getPreferredFocusedComponent() {
return (JComponent)myComboBox.getEditor().getEditorComponent();
}
public void selectAll() {
myComboBox.getEditor().selectAll();
}
public Editor getEditor() {
return myEditor.getEditor();
}
public JComponent getEditorComponent() {
return myEditor.getEditorComponent();
}
public void addRecent(TextWithImports text) {
if (text.getText().length() != 0) {
Component editorComponent = myComboBox.getEditor().getEditorComponent();
final boolean focusOwner = editorComponent.isFocusOwner();
int offset = -1;
if (editorComponent instanceof EditorTextField) {
final EditorTextField textField = (EditorTextField)editorComponent;
if (textField.getEditor() != null) {
offset = textField.getCaretModel().getOffset();
}
}
super.addRecent(text);
myComboBox.insertItemAt(text, 0);
myComboBox.setSelectedIndex(0);
editorComponent = myComboBox.getEditor().getEditorComponent();
if (offset != -1 && editorComponent instanceof EditorTextField) {
final EditorTextField textField = (EditorTextField)editorComponent;
final Editor editor = textField.getEditor();
if (editor != null) {
int textLength = editor.getDocument().getTextLength();
offset = Math.min(offset, textLength);
textField.getCaretModel().moveToOffset(offset);
editor.getSelectionModel().setSelection(offset, offset);
}
}
if (focusOwner) {
editorComponent.requestFocus();
}
}
}
private static class MyComboboxModel extends AbstractListModel implements MutableComboBoxModel {
private List<TextWithImports> myItems = new ArrayList<>();
private int mySelectedIndex = -1;
private MyComboboxModel(@Nullable final List<TextWithImports> recents) {
if (recents != null) {
myItems = recents;
}
}
@Override
public void setSelectedItem(final Object anItem) {
final int oldSelectedIndex = mySelectedIndex;
mySelectedIndex = anItem instanceof TextWithImports ? myItems.indexOf(anItem) : -1;
if (oldSelectedIndex != mySelectedIndex) fireContentsChanged(this, -1, -1);
}
@Override
public Object getSelectedItem() {
return mySelectedIndex == -1 || mySelectedIndex > myItems.size() - 1 ? null : myItems.get(mySelectedIndex);
}
@Override
public int getSize() {
return myItems.size();
}
@Override
public Object getElementAt(int index) {
return myItems.get(index);
}
@Override
public void addElement(final Object obj) {
insertElementAt(obj, myItems.size() - 1);
if (mySelectedIndex == -1 && myItems.size() == 1 && obj != null) {
setSelectedItem(obj);
}
}
@Override
public void removeElement(Object obj) {
removeElement(obj, true);
}
public void removeElement(final Object obj, final boolean checkSelection) {
if (!(obj instanceof TextWithImports)) throw new IllegalArgumentException();
final int index = myItems.indexOf((TextWithImports)obj);
if (index != -1) {
myItems.remove(index);
if (checkSelection) {
if (mySelectedIndex == index) {
if (myItems.size() == 0) {
setSelectedItem(null);
}
else if (index > myItems.size() - 1) {
setSelectedItem(myItems.get(myItems.size() - 1));
}
}
fireIntervalRemoved(this, index, index);
}
}
}
@Override
public void insertElementAt(final Object obj, final int index) {
if (!(obj instanceof TextWithImports)) throw new IllegalArgumentException();
removeElement(obj, false); // remove duplicate entry if any
myItems.add(index, (TextWithImports)obj);
fireIntervalAdded(this, index, index);
if (myItems.size() > MAX_ROWS) {
for (int i = myItems.size() - 1; i > MAX_ROWS - 1; i--) {
myItems.remove(i);
}
// will not fire events here to not recreate the editor
//fireIntervalRemoved(this, myItems.size() - 1, MAX_ROWS - 1);
}
}
@Override
public void removeElementAt(final int index) {
if (index < 0 || index > myItems.size() - 1) throw new IndexOutOfBoundsException();
removeElement(myItems.get(index));
}
}
}
@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.debugger.ui.tree.render.configurables.ClassChildrenExpressionConfigurable">
<grid id="1ddd" binding="myPanel" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="38" y="77" width="450" height="138"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="cb46f" class="com.intellij.openapi.ui.LabeledComponent" binding="myChildrenPanel">
<constraints>
<xy x="0" y="0" width="450" height="31"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="1" fill="1"/>
</constraints>
<properties>
<componentClass value="javax.swing.JPanel"/>
<labelInsets top="0" left="0" bottom="5" right="0"/>
<text resource-bundle="messages/DebuggerBundle" key="label.node.descendands.expression"/>
</properties>
</component>
<component id="5dbf7" class="com.intellij.openapi.ui.LabeledComponent" binding="myExpandablePanel">
<constraints>
<xy x="0" y="36" width="450" height="31"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="1" fill="1"/>
</constraints>
<properties>
<componentClass value="javax.swing.JPanel"/>
<labelInsets top="0" left="0" bottom="5" right="0"/>
<text resource-bundle="messages/DebuggerBundle" key="node.has.descendands.expression.optional"/>
</properties>
</component>
<vspacer id="2950c">
<constraints>
<xy x="219" y="67" width="11" height="71"/>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -1,85 +0,0 @@
/*
* Copyright 2000-2015 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.debugger.ui.tree.render.configurables;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.ui.CompletionEditor;
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
import com.intellij.debugger.ui.tree.render.ExpressionChildrenRenderer;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
public class ClassChildrenExpressionConfigurable implements UnnamedConfigurable, Disposable {
private final ExpressionChildrenRenderer myRenderer;
private JPanel myPanel;
private LabeledComponent<JPanel> myChildrenPanel;
private LabeledComponent<JPanel> myExpandablePanel;
private final CompletionEditor myChildrenEditor;
private final CompletionEditor myExpandableEditor;
public ClassChildrenExpressionConfigurable(@NotNull Project project, @NotNull ExpressionChildrenRenderer renderer) {
myRenderer = renderer;
PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), project, GlobalSearchScope.allScope(project));
myChildrenEditor = new DebuggerExpressionComboBox(project, this, psiClass, "ClassChildrenExpression");
myExpandableEditor = new DebuggerExpressionComboBox(project, this, psiClass, "ClassChildrenExpression");
myChildrenPanel.getComponent().setLayout(new BorderLayout());
myChildrenPanel.getComponent().add(myChildrenEditor);
myExpandablePanel.getComponent().setLayout(new BorderLayout());
myExpandablePanel.getComponent().add(myExpandableEditor);
}
public JComponent createComponent() {
return myPanel;
}
public boolean isModified() {
return !myRenderer.getChildrenExpression().equals(myChildrenEditor.getText()) ||
!myRenderer.getChildrenExpandable().equals(myExpandableEditor.getText());
}
public void apply() throws ConfigurationException {
myRenderer.setChildrenExpression(myChildrenEditor.getText());
myRenderer.setChildrenExpandable(myExpandableEditor.getText());
}
public void reset() {
myChildrenEditor.setText(myRenderer.getChildrenExpression());
myExpandableEditor.setText(myRenderer.getChildrenExpandable());
}
@Override
public void dispose() {
}
public void disposeUIResources() {
Disposer.dispose(this);
}
}
@@ -1,103 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.debugger.ui.tree.render.configurables.NamedChildrenConfigurable">
<grid id="47245" binding="myPanel" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="57" y="23" width="298" height="252"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="a2d2a" class="javax.swing.JLabel" binding="myTableLabel">
<constraints>
<xy x="0" y="2" width="110" height="16"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0"/>
</constraints>
<properties>
<text resource-bundle="messages/DebuggerBundle" key="label.named.children.configurable.node.descendants"/>
</properties>
</component>
<grid id="c8237" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="0" y="25" width="298" height="227"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<scrollpane class="com.intellij.ui.components.JBScrollPane" id="68272">
<constraints>
<xy x="0" y="0" width="188" height="227"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="8776c" class="com.intellij.util.ui.Table" binding="myTable">
<constraints/>
<properties>
<preferredScrollableViewportSize width="-1" height="-1"/>
</properties>
</component>
</children>
</scrollpane>
<grid id="c7716" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="198" y="0" width="100" height="227"/>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="c1f20" class="javax.swing.JButton" binding="myButtonRemove">
<constraints>
<xy x="0" y="31" width="100" height="26"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1"/>
</constraints>
<properties>
<text resource-bundle="messages/DebuggerBundle" key="button.remove"/>
</properties>
</component>
<component id="f0acb" class="javax.swing.JButton" binding="myButtonUp">
<constraints>
<xy x="0" y="62" width="100" height="26"/>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1"/>
</constraints>
<properties>
<text resource-bundle="messages/DebuggerBundle" key="button.move.up"/>
</properties>
</component>
<component id="66bbb" class="javax.swing.JButton" binding="myButtonDown">
<constraints>
<xy x="0" y="93" width="100" height="26"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1"/>
</constraints>
<properties>
<text resource-bundle="messages/DebuggerBundle" key="button.move.down"/>
</properties>
</component>
<component id="5579c" class="javax.swing.JButton" binding="myButtonAdd">
<constraints>
<xy x="0" y="0" width="100" height="26"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1"/>
</constraints>
<properties>
<text resource-bundle="messages/DebuggerBundle" key="button.add"/>
</properties>
</component>
<vspacer id="d11e5">
<constraints>
<xy x="44" y="119" width="11" height="108"/>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2"/>
</constraints>
</vspacer>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</form>
@@ -1,191 +0,0 @@
/*
* Copyright 2000-2016 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.debugger.ui.tree.render.configurables;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.evaluation.TextWithImports;
import com.intellij.debugger.ui.CompletionEditor;
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
import com.intellij.debugger.ui.tree.render.EnumerationChildrenRenderer;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.TableUtil;
import com.intellij.util.ui.AbstractTableCellEditor;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.Table;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
public class NamedChildrenConfigurable implements UnnamedConfigurable, Disposable {
private Table myTable;
private final EnumerationChildrenRenderer myRenderer;
private JPanel myPanel;
private JLabel myTableLabel;
private JButton myButtonAdd;
private JButton myButtonRemove;
private JButton myButtonUp;
private JButton myButtonDown;
private final CompletionEditor myCompletionEditor;
public NamedChildrenConfigurable(@NotNull Project project, EnumerationChildrenRenderer renderer) {
myRenderer = renderer;
myTableLabel.setLabelFor(myTable);
getModel().addColumn(DebuggerBundle.message("label.named.children.configurable.table.header.column.name"), (Object[])null);
final String expressionColumnName = DebuggerBundle.message("label.named.children.configurable.table.header.column.expression");
getModel().addColumn(expressionColumnName, (Object[])null);
PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), project, GlobalSearchScope.allScope(project));
myCompletionEditor = new DebuggerExpressionComboBox(project, this, psiClass, "NamedChildrenConfigurable");
myTable.setDragEnabled(false);
myTable.setIntercellSpacing(JBUI.emptySize());
myTable.getColumn(expressionColumnName).setCellEditor(new AbstractTableCellEditor() {
public Object getCellEditorValue() {
return myCompletionEditor.getText();
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
myCompletionEditor.setText((TextWithImports)value);
return myCompletionEditor;
}
});
myButtonAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
getModel().addRow(new Object[] {"", DebuggerUtils.getInstance().createExpressionWithImports("") });
}
});
myButtonRemove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int selectedRow = myTable.getSelectedRow();
if(selectedRow >= 0 && selectedRow < myTable.getRowCount()) {
getModel().removeRow(selectedRow);
}
}
});
myButtonDown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
TableUtil.moveSelectedItemsDown(myTable);
}
});
myButtonUp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
TableUtil.moveSelectedItemsUp(myTable);
}
});
myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
updateButtons();
}
});
updateButtons();
}
private void updateButtons() {
int selectedRow = myTable.getSelectedRow();
myButtonRemove.setEnabled(selectedRow != -1);
myButtonUp.setEnabled(selectedRow > 0);
myButtonDown.setEnabled(selectedRow < myTable.getRowCount() - 1);
}
private DefaultTableModel getModel() {
return ((DefaultTableModel)myTable.getModel());
}
public JComponent createComponent() {
return myPanel;
}
public boolean isModified() {
return false;
}
public void apply() throws ConfigurationException {
DefaultTableModel model = getModel();
final int size = model.getRowCount();
List<Pair<String, TextWithImports>> result = new ArrayList<>();
for (int idx = 0; idx < size; idx++) {
result.add(Pair.create((String)model.getValueAt(idx, 0), (TextWithImports)model.getValueAt(idx, 1)));
}
myRenderer.setChildren(result);
}
public void reset() {
while(myTable.getModel().getRowCount() > 0) {
getModel().removeRow(0);
}
for (Pair<String, TextWithImports> pair : myRenderer.getChildren()) {
getModel().addRow(new Object[]{pair.getFirst(), pair.getSecond()});
}
}
public void disposeUIResources() {
Disposer.dispose(this);
}
@Override
public void dispose() {
}
/*
private class TextWithImportsTableRenderer implements TableCellRenderer{
private final CompletionEditor myEditor;
private TextWithImportsTableRenderer () {
PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), myProject);
myEditor = DebuggerUtils.getInstance().createEditor(myProject, psiClass, "NamedChildrenConfigurable");
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if(hasFocus) {
myEditor.setText((TextWithImports)value);
return myEditor;
}
else {
TableCellRenderer defaultRenderer = myTable.getDefaultRenderer(String.class);
return defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
}
*/
}