Search in sources :

Example 36 with DocumentAdapter

use of com.intellij.openapi.editor.event.DocumentAdapter in project intellij-community by JetBrains.

the class SrcFileAnnotator method showCoverageInformation.

public void showCoverageInformation(final CoverageSuitesBundle suite) {
    // Store the values of myFile and myEditor in local variables to avoid an NPE after dispose() has been called in the EDT.
    final PsiFile psiFile = myFile;
    final Editor editor = myEditor;
    final Document document = myDocument;
    if (editor == null || psiFile == null || document == null)
        return;
    final VirtualFile file = getVirtualFile(psiFile);
    final MyEditorBean editorBean = new MyEditorBean(editor, file, document);
    final MarkupModel markupModel = DocumentMarkupModel.forDocument(document, myProject, true);
    final List<RangeHighlighter> highlighters = new ArrayList<>();
    final ProjectData data = suite.getCoverageData();
    if (data == null) {
        coverageDataNotFound(suite);
        return;
    }
    final CoverageEngine engine = suite.getCoverageEngine();
    final Set<String> qualifiedNames = engine.getQualifiedNames(psiFile);
    // let's find old content in local history and build mapping from old lines to new one
    // local history doesn't index libraries, so let's distinguish libraries content with other one
    final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
    final long fileTimeStamp = file.getTimeStamp();
    final long coverageTimeStamp = suite.getLastCoverageTimeStamp();
    final TIntIntHashMap oldToNewLineMapping;
    //do not show coverage info over cls
    if (engine.isInLibraryClasses(myProject, file)) {
        return;
    }
    // if in libraries content
    if (projectFileIndex.isInLibrarySource(file)) {
        // compare file and coverage timestamps
        if (fileTimeStamp > coverageTimeStamp) {
            showEditorWarningMessage(CodeInsightBundle.message("coverage.data.outdated"));
            return;
        }
        oldToNewLineMapping = null;
    } else {
        // check local history
        oldToNewLineMapping = getOldToNewLineMapping(coverageTimeStamp, editorBean);
        if (oldToNewLineMapping == null) {
            // if history for file isn't available let's check timestamps
            if (fileTimeStamp > coverageTimeStamp && classesArePresentInCoverageData(data, qualifiedNames)) {
                showEditorWarningMessage(CodeInsightBundle.message("coverage.data.outdated"));
                return;
            }
        }
    }
    if (editor.getUserData(COVERAGE_HIGHLIGHTERS) != null) {
        //highlighters already collected - no need to do it twice
        return;
    }
    final Module module = ApplicationManager.getApplication().runReadAction(new Computable<Module>() {

        @Nullable
        @Override
        public Module compute() {
            return ModuleUtilCore.findModuleForPsiElement(psiFile);
        }
    });
    if (module != null) {
        if (engine.recompileProjectAndRerunAction(module, suite, () -> CoverageDataManager.getInstance(myProject).chooseSuitesBundle(suite))) {
            return;
        }
    }
    // now if oldToNewLineMapping is null we should use f(x)=id(x) mapping
    // E.g. all *.class files for java source file with several classes
    final Set<File> outputFiles = engine.getCorrespondingOutputFiles(psiFile, module, suite);
    final boolean subCoverageActive = CoverageDataManager.getInstance(myProject).isSubCoverageActive();
    final boolean coverageByTestApplicable = suite.isCoverageByTestApplicable() && !(subCoverageActive && suite.isCoverageByTestEnabled());
    final TreeMap<Integer, LineData> executableLines = new TreeMap<>();
    final TreeMap<Integer, Object[]> classLines = new TreeMap<>();
    final TreeMap<Integer, String> classNames = new TreeMap<>();
    class HighlightersCollector {

        private void collect(File outputFile, final String qualifiedName) {
            final ClassData fileData = data.getClassData(qualifiedName);
            if (fileData != null) {
                final Object[] lines = fileData.getLines();
                if (lines != null) {
                    final Object[] postProcessedLines = suite.getCoverageEngine().postProcessExecutableLines(lines, editor);
                    for (Object lineData : postProcessedLines) {
                        if (lineData instanceof LineData) {
                            final int line = ((LineData) lineData).getLineNumber() - 1;
                            final int lineNumberInCurrent;
                            if (oldToNewLineMapping != null) {
                                // use mapping based on local history
                                if (!oldToNewLineMapping.contains(line)) {
                                    continue;
                                }
                                lineNumberInCurrent = oldToNewLineMapping.get(line);
                            } else {
                                // use id mapping
                                lineNumberInCurrent = line;
                            }
                            executableLines.put(line, (LineData) lineData);
                            classLines.put(line, postProcessedLines);
                            classNames.put(line, qualifiedName);
                            ApplicationManager.getApplication().invokeLater(() -> {
                                if (lineNumberInCurrent >= document.getLineCount())
                                    return;
                                if (editorBean.isDisposed())
                                    return;
                                final RangeHighlighter highlighter = createRangeHighlighter(suite.getLastCoverageTimeStamp(), markupModel, coverageByTestApplicable, executableLines, qualifiedName, line, lineNumberInCurrent, suite, postProcessedLines, editorBean);
                                highlighters.add(highlighter);
                            });
                        }
                    }
                }
            } else if (outputFile != null && !subCoverageActive && engine.includeUntouchedFileInCoverage(qualifiedName, outputFile, psiFile, suite)) {
                collectNonCoveredFileInfo(outputFile, highlighters, markupModel, executableLines, coverageByTestApplicable, editorBean);
            }
        }
    }
    final HighlightersCollector collector = new HighlightersCollector();
    if (!outputFiles.isEmpty()) {
        for (File outputFile : outputFiles) {
            final String qualifiedName = engine.getQualifiedName(outputFile, psiFile);
            if (qualifiedName != null) {
                collector.collect(outputFile, qualifiedName);
            }
        }
    } else {
        //check non-compilable classes which present in ProjectData
        for (String qName : qualifiedNames) {
            collector.collect(null, qName);
        }
    }
    ApplicationManager.getApplication().invokeLater(() -> {
        if (!editorBean.isDisposed() && highlighters.size() > 0) {
            editor.putUserData(COVERAGE_HIGHLIGHTERS, highlighters);
        }
    });
    final DocumentListener documentListener = new DocumentAdapter() {

        @Override
        public void documentChanged(final DocumentEvent e) {
            myNewToOldLines = null;
            myOldToNewLines = null;
            List<RangeHighlighter> rangeHighlighters = editor.getUserData(COVERAGE_HIGHLIGHTERS);
            if (rangeHighlighters == null)
                rangeHighlighters = new ArrayList<>();
            int offset = e.getOffset();
            final int lineNumber = document.getLineNumber(offset);
            final int lastLineNumber = document.getLineNumber(offset + e.getNewLength());
            final TextRange changeRange = new TextRange(document.getLineStartOffset(lineNumber), document.getLineEndOffset(lastLineNumber));
            for (Iterator<RangeHighlighter> it = rangeHighlighters.iterator(); it.hasNext(); ) {
                final RangeHighlighter highlighter = it.next();
                if (!highlighter.isValid() || TextRange.create(highlighter).intersects(changeRange)) {
                    highlighter.dispose();
                    it.remove();
                }
            }
            final List<RangeHighlighter> highlighters = rangeHighlighters;
            myUpdateAlarm.cancelAllRequests();
            if (!myUpdateAlarm.isDisposed()) {
                myUpdateAlarm.addRequest(() -> {
                    final TIntIntHashMap newToOldLineMapping = getNewToOldLineMapping(suite.getLastCoverageTimeStamp(), editorBean);
                    if (newToOldLineMapping != null) {
                        ApplicationManager.getApplication().invokeLater(() -> {
                            if (editorBean.isDisposed())
                                return;
                            for (int line = lineNumber; line <= lastLineNumber; line++) {
                                final int oldLineNumber = newToOldLineMapping.get(line);
                                final LineData lineData = executableLines.get(oldLineNumber);
                                if (lineData != null) {
                                    RangeHighlighter rangeHighlighter = createRangeHighlighter(suite.getLastCoverageTimeStamp(), markupModel, coverageByTestApplicable, executableLines, classNames.get(oldLineNumber), oldLineNumber, line, suite, classLines.get(oldLineNumber), editorBean);
                                    highlighters.add(rangeHighlighter);
                                }
                            }
                            editor.putUserData(COVERAGE_HIGHLIGHTERS, highlighters.size() > 0 ? highlighters : null);
                        });
                    }
                }, 100);
            }
        }
    };
    document.addDocumentListener(documentListener);
    editor.putUserData(COVERAGE_DOCUMENT_LISTENER, documentListener);
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) DocumentListener(com.intellij.openapi.editor.event.DocumentListener) Document(com.intellij.openapi.editor.Document) PsiFile(com.intellij.psi.PsiFile) TIntIntHashMap(gnu.trove.TIntIntHashMap) ProjectData(com.intellij.rt.coverage.data.ProjectData) DocumentAdapter(com.intellij.openapi.editor.event.DocumentAdapter) TextRange(com.intellij.openapi.util.TextRange) DocumentEvent(com.intellij.openapi.editor.event.DocumentEvent) LineData(com.intellij.rt.coverage.data.LineData) ClassData(com.intellij.rt.coverage.data.ClassData) ProjectFileIndex(com.intellij.openapi.roots.ProjectFileIndex) TextEditor(com.intellij.openapi.fileEditor.TextEditor) FileEditor(com.intellij.openapi.fileEditor.FileEditor) Editor(com.intellij.openapi.editor.Editor) DocumentMarkupModel(com.intellij.openapi.editor.impl.DocumentMarkupModel) Module(com.intellij.openapi.module.Module) VirtualFile(com.intellij.openapi.vfs.VirtualFile) PsiFile(com.intellij.psi.PsiFile) File(java.io.File) Nullable(org.jetbrains.annotations.Nullable)

Example 37 with DocumentAdapter

use of com.intellij.openapi.editor.event.DocumentAdapter in project intellij-community by JetBrains.

the class AbstractInplaceIntroducer method startInplaceIntroduceTemplate.

/**
   * Begins the in-place refactoring operation.
   *
   * @return true if the in-place refactoring was successfully started, false if it failed to start and a dialog should be shown instead.
   */
public boolean startInplaceIntroduceTemplate() {
    final boolean replaceAllOccurrences = isReplaceAllOccurrences();
    final Ref<Boolean> result = new Ref<>();
    CommandProcessor.getInstance().executeCommand(myProject, () -> {
        final String[] names = suggestNames(replaceAllOccurrences, getLocalVariable());
        final V variable = createFieldToStartTemplateOn(replaceAllOccurrences, names);
        boolean started = false;
        if (variable != null) {
            int caretOffset = getCaretOffset();
            myEditor.getCaretModel().moveToOffset(caretOffset);
            myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
            final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<>();
            nameSuggestions.add(variable.getName());
            nameSuggestions.addAll(Arrays.asList(names));
            initOccurrencesMarkers();
            setElementToRename(variable);
            updateTitle(getVariable());
            started = super.performInplaceRefactoring(nameSuggestions);
            if (started) {
                onRenameTemplateStarted();
                myDocumentAdapter = new DocumentAdapter() {

                    @Override
                    public void documentChanged(DocumentEvent e) {
                        if (myPreview == null)
                            return;
                        final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
                        if (templateState != null) {
                            final TextResult value = templateState.getVariableValue(InplaceRefactoring.PRIMARY_VARIABLE_NAME);
                            if (value != null) {
                                updateTitle(getVariable(), value.getText());
                            }
                        }
                    }
                };
                myEditor.getDocument().addDocumentListener(myDocumentAdapter);
                updateTitle(getVariable());
                if (TemplateManagerImpl.getTemplateState(myEditor) != null) {
                    myEditor.putUserData(ACTIVE_INTRODUCE, this);
                }
            }
        }
        result.set(started);
        if (!started) {
            finish(true);
        }
    }, getCommandName(), getCommandName());
    return result.get();
}
Also used : TextResult(com.intellij.codeInsight.template.TextResult) DocumentAdapter(com.intellij.openapi.editor.event.DocumentAdapter) DocumentEvent(com.intellij.openapi.editor.event.DocumentEvent) TemplateState(com.intellij.codeInsight.template.impl.TemplateState) Ref(com.intellij.openapi.util.Ref)

Example 38 with DocumentAdapter

use of com.intellij.openapi.editor.event.DocumentAdapter in project intellij-community by JetBrains.

the class HgPullDialog method createUIComponents.

public void createUIComponents() {
    myRepositoryURL = new EditorComboBox("");
    myRepositoryURL.addDocumentListener(new DocumentAdapter() {

        @Override
        public void documentChanged(DocumentEvent e) {
            onChangePullSource();
        }
    });
}
Also used : DocumentAdapter(com.intellij.openapi.editor.event.DocumentAdapter) EditorComboBox(com.intellij.ui.EditorComboBox) DocumentEvent(com.intellij.openapi.editor.event.DocumentEvent)

Example 39 with DocumentAdapter

use of com.intellij.openapi.editor.event.DocumentAdapter in project kotlin by JetBrains.

the class MoveKotlinNestedClassesDialog method initClassChooser.

private void initClassChooser(@NotNull KtClassOrObject initialTargetClass) {
    //noinspection ConstantConditions
    originalClassField.setText(originalClass.getFqName().asString());
    //noinspection ConstantConditions
    targetClassChooser = new ReferenceEditorComboWithBrowseButton(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            TreeClassChooser chooser = new TreeJavaClassChooserDialog(RefactoringBundle.message("choose.destination.class"), myProject, GlobalSearchScope.projectScope(myProject), new ClassFilter() {

                @Override
                public boolean isAccepted(PsiClass aClass) {
                    if (!(aClass instanceof KtLightClassForSourceDeclaration))
                        return false;
                    KtClassOrObject classOrObject = ((KtLightClassForSourceDeclaration) aClass).getKotlinOrigin();
                    if (classOrObject instanceof KtObjectDeclaration) {
                        return !((KtObjectDeclaration) classOrObject).isObjectLiteral();
                    }
                    if (classOrObject instanceof KtClass) {
                        KtClass ktClass = (KtClass) classOrObject;
                        return !(ktClass.isInner() || ktClass.isAnnotation());
                    }
                    return false;
                }
            }, null, null, true) {

                @Nullable
                @Override
                protected PsiClass getSelectedFromTreeUserObject(DefaultMutableTreeNode node) {
                    PsiClass psiClass = super.getSelectedFromTreeUserObject(node);
                    if (psiClass != null)
                        return psiClass;
                    Object userObject = node.getUserObject();
                    if (!(userObject instanceof KtClassOrObjectTreeNode))
                        return null;
                    return LightClassUtilsKt.toLightClass(((KtClassOrObjectTreeNode) userObject).getValue());
                }
            };
            chooser.selectDirectory((targetClass != null ? targetClass : originalClass).getContainingFile().getContainingDirectory());
            chooser.showDialog();
            PsiClass aClass = chooser.getSelected();
            if (aClass instanceof KtLightClassForSourceDeclaration) {
                targetClass = ((KtLightClassForSourceDeclaration) aClass).getKotlinOrigin();
                targetClassChooser.setText(aClass.getQualifiedName());
            }
        }
    }, initialTargetClass.getFqName().asString(), myProject, true, JavaCodeFragment.VisibilityChecker.PROJECT_SCOPE_VISIBLE, RECENTS_KEY);
    targetClassChooser.getChildComponent().getDocument().addDocumentListener(new DocumentAdapter() {

        @Override
        public void documentChanged(DocumentEvent e) {
            PsiClass aClass = JavaPsiFacade.getInstance(myProject).findClass(targetClassChooser.getText(), GlobalSearchScope.projectScope(myProject));
            targetClass = aClass instanceof KtLightClassForSourceDeclaration ? ((KtLightClassForSourceDeclaration) aClass).getKotlinOrigin() : null;
            validateButtons();
        }
    });
    targetClassChooserPanel.add(targetClassChooser);
}
Also used : KtClassOrObjectTreeNode(org.jetbrains.kotlin.idea.projectView.KtClassOrObjectTreeNode) TreeClassChooser(com.intellij.ide.util.TreeClassChooser) KtLightClassForSourceDeclaration(org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration) DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) ActionEvent(java.awt.event.ActionEvent) PsiClass(com.intellij.psi.PsiClass) DocumentAdapter(com.intellij.openapi.editor.event.DocumentAdapter) DocumentEvent(com.intellij.openapi.editor.event.DocumentEvent) ReferenceEditorComboWithBrowseButton(com.intellij.ui.ReferenceEditorComboWithBrowseButton) TreeJavaClassChooserDialog(com.intellij.ide.util.TreeJavaClassChooserDialog) ActionListener(java.awt.event.ActionListener) ClassFilter(com.intellij.ide.util.ClassFilter)

Example 40 with DocumentAdapter

use of com.intellij.openapi.editor.event.DocumentAdapter in project intellij-community by JetBrains.

the class PyChangeSignatureDialog method getTableEditor.

@Override
protected JBTableRowEditor getTableEditor(final JTable t, final ParameterTableModelItemBase<PyParameterInfo> item) {
    return new JBTableRowEditor() {

        private EditorTextField myNameEditor;

        private EditorTextField myDefaultValueEditor;

        private JCheckBox myDefaultInSignature;

        @Override
        public void prepareEditor(JTable table, int row) {
            setLayout(new GridLayout(1, 3));
            final JPanel parameterPanel = createParameterPanel();
            add(parameterPanel);
            final JPanel defaultValuePanel = createDefaultValuePanel();
            add(defaultValuePanel);
            final JPanel defaultValueCheckBox = createDefaultValueCheckBox();
            add(defaultValueCheckBox);
            final String nameText = myNameEditor.getText();
            myDefaultValueEditor.setEnabled(!nameText.startsWith("*") && !PyNames.CANONICAL_SELF.equals(nameText));
            myDefaultInSignature.setEnabled(!nameText.startsWith("*") && !PyNames.CANONICAL_SELF.equals(nameText));
        }

        private JPanel createDefaultValueCheckBox() {
            final JPanel defaultValuePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
            final JBLabel inSignatureLabel = new JBLabel(PyBundle.message("refactoring.change.signature.dialog.default.value.checkbox"), UIUtil.ComponentStyle.SMALL);
            IJSwingUtilities.adjustComponentsOnMac(inSignatureLabel, myDefaultInSignature);
            defaultValuePanel.add(inSignatureLabel, BorderLayout.WEST);
            myDefaultInSignature = new JCheckBox();
            myDefaultInSignature.setSelected(((PyParameterTableModelItem) item).isDefaultInSignature());
            myDefaultInSignature.addItemListener(new ItemListener() {

                @Override
                public void itemStateChanged(ItemEvent event) {
                    ((PyParameterTableModelItem) item).setDefaultInSignature(myDefaultInSignature.isSelected());
                }
            });
            myDefaultInSignature.addChangeListener(mySignatureUpdater);
            myDefaultInSignature.setEnabled(item.parameter.getOldIndex() == -1);
            defaultValuePanel.add(myDefaultInSignature, BorderLayout.EAST);
            return defaultValuePanel;
        }

        private JPanel createDefaultValuePanel() {
            final JPanel defaultValuePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
            final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(item.defaultValueCodeFragment);
            myDefaultValueEditor = new EditorTextField(doc, getProject(), getFileType());
            final JBLabel defaultValueLabel = new JBLabel(PyBundle.message("refactoring.change.signature.dialog.default.value.label"), UIUtil.ComponentStyle.SMALL);
            IJSwingUtilities.adjustComponentsOnMac(defaultValueLabel, myDefaultValueEditor);
            defaultValuePanel.add(defaultValueLabel);
            defaultValuePanel.add(myDefaultValueEditor);
            myDefaultValueEditor.setPreferredWidth(t.getWidth() / 2);
            myDefaultValueEditor.addDocumentListener(mySignatureUpdater);
            return defaultValuePanel;
        }

        private JPanel createParameterPanel() {
            final JPanel namePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
            myNameEditor = new EditorTextField(item.parameter.getName(), getProject(), getFileType());
            final JBLabel nameLabel = new JBLabel(PyBundle.message("refactoring.change.signature.dialog.name.label"), UIUtil.ComponentStyle.SMALL);
            IJSwingUtilities.adjustComponentsOnMac(nameLabel, myNameEditor);
            namePanel.add(nameLabel);
            namePanel.add(myNameEditor);
            myNameEditor.setPreferredWidth(t.getWidth() / 2);
            myNameEditor.addDocumentListener(new DocumentAdapter() {

                @Override
                public void documentChanged(DocumentEvent event) {
                    fireDocumentChanged(event, 0);
                    myDefaultValueEditor.setEnabled(!myNameEditor.getText().startsWith("*"));
                    myDefaultInSignature.setEnabled(!myNameEditor.getText().startsWith("*"));
                }
            });
            myNameEditor.addDocumentListener(mySignatureUpdater);
            return namePanel;
        }

        @Override
        public JBTableRow getValue() {
            return new JBTableRow() {

                @Override
                public Object getValueAt(int column) {
                    switch(column) {
                        case 0:
                            return myNameEditor.getText().trim();
                        case 1:
                            return new Pair<>(item.defaultValueCodeFragment, ((PyParameterTableModelItem) item).isDefaultInSignature());
                    }
                    return null;
                }
            };
        }

        @Override
        public JComponent getPreferredFocusedComponent() {
            return myNameEditor.getFocusTarget();
        }

        @Override
        public JComponent[] getFocusableComponents() {
            final List<JComponent> focusable = new ArrayList<>();
            focusable.add(myNameEditor.getFocusTarget());
            if (myDefaultValueEditor != null) {
                focusable.add(myDefaultValueEditor.getFocusTarget());
            }
            return focusable.toArray(new JComponent[focusable.size()]);
        }
    };
}
Also used : ItemEvent(java.awt.event.ItemEvent) ArrayList(java.util.ArrayList) DocumentAdapter(com.intellij.openapi.editor.event.DocumentAdapter) Document(com.intellij.openapi.editor.Document) DocumentEvent(com.intellij.openapi.editor.event.DocumentEvent) JBTableRowEditor(com.intellij.util.ui.table.JBTableRowEditor) EditorTextField(com.intellij.ui.EditorTextField) JBLabel(com.intellij.ui.components.JBLabel) ItemListener(java.awt.event.ItemListener) JBTableRow(com.intellij.util.ui.table.JBTableRow) VerticalFlowLayout(com.intellij.openapi.ui.VerticalFlowLayout) Pair(com.intellij.openapi.util.Pair)

Aggregations

DocumentAdapter (com.intellij.openapi.editor.event.DocumentAdapter)41 DocumentEvent (com.intellij.openapi.editor.event.DocumentEvent)40 Document (com.intellij.openapi.editor.Document)10 EditorTextField (com.intellij.ui.EditorTextField)6 ActionEvent (java.awt.event.ActionEvent)6 ActionListener (java.awt.event.ActionListener)6 Disposable (com.intellij.openapi.Disposable)4 AnActionEvent (com.intellij.openapi.actionSystem.AnActionEvent)4 VirtualFile (com.intellij.openapi.vfs.VirtualFile)4 ReferenceEditorComboWithBrowseButton (com.intellij.ui.ReferenceEditorComboWithBrowseButton)4 NotNull (org.jetbrains.annotations.NotNull)4 AnAction (com.intellij.openapi.actionSystem.AnAction)3 Editor (com.intellij.openapi.editor.Editor)3 Module (com.intellij.openapi.module.Module)3 Pair (com.intellij.openapi.util.Pair)3 Ref (com.intellij.openapi.util.Ref)3 Nullable (org.jetbrains.annotations.Nullable)3 TemplateState (com.intellij.codeInsight.template.impl.TemplateState)2 Language (com.intellij.lang.Language)2 CustomShortcutSet (com.intellij.openapi.actionSystem.CustomShortcutSet)2