public void hideCoverageData() { if (myEditor == null) return; final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject); final List<RangeHighlighter> highlighters = myEditor.getUserData(COVERAGE_HIGHLIGHTERS); if (highlighters != null) { for (final RangeHighlighter highlighter : highlighters) { ApplicationManager.getApplication().invokeLater(() -> highlighter.dispose()); } myEditor.putUserData(COVERAGE_HIGHLIGHTERS, null); } final Map<FileEditor, EditorNotificationPanel> map = myFile.getCopyableUserData(NOTIFICATION_PANELS); if (map != null) { final VirtualFile vFile = myFile.getVirtualFile(); LOG.assertTrue(vFile != null); boolean freeAll = !fileEditorManager.isFileOpen(vFile); myFile.putCopyableUserData(NOTIFICATION_PANELS, null); for (FileEditor fileEditor : map.keySet()) { if (!freeAll && !isCurrentEditor(fileEditor)) { continue; } fileEditorManager.removeTopComponent(fileEditor, map.get(fileEditor)); } } final DocumentListener documentListener = myEditor.getUserData(COVERAGE_DOCUMENT_LISTENER); if (documentListener != null) { myDocument.removeDocumentListener(documentListener); myEditor.putUserData(COVERAGE_DOCUMENT_LISTENER, null); } }
private TemplateState initTemplateState(@NotNull Editor editor) { clearTemplateState(editor); TemplateState state = new TemplateState(myProject, editor); Disposer.register(this, state); editor.putUserData(TEMPLATE_STATE_KEY, state); return state; }
static void clearTemplateState(@NotNull Editor editor) { TemplateState prevState = getTemplateState(editor); if (prevState != null) { disposeState(prevState); } editor.putUserData(TEMPLATE_STATE_KEY, null); }
public boolean process( @NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile) { final Document document = editor.getDocument(); final String textForRollback = document.getText(); try { editor.putUserData(SMART_ENTER_TIMESTAMP, editor.getDocument().getModificationStamp()); myFirstErrorOffset = Integer.MAX_VALUE; process(project, editor, psiFile, 0); } catch (TooManyAttemptsException e) { document.replaceString(0, document.getTextLength(), textForRollback); } finally { editor.putUserData(SMART_ENTER_TIMESTAMP, null); } return true; }
private static List<ParameterInfoController> getAllControllers(@NotNull Editor editor) { List<ParameterInfoController> array = editor.getUserData(ALL_CONTROLLERS_KEY); if (array == null) { array = new ArrayList<>(); editor.putUserData(ALL_CONTROLLERS_KEY, array); } return array; }
private static CompletionState getCompletionState(Editor editor) { CompletionState state = editor.getUserData(KEY_STATE); if (state == null) { state = new CompletionState(); editor.putUserData(KEY_STATE, state); } return state; }
private static void clearLineMarkers(Editor editor) { final List<RangeHighlighter> oldHighlighters = editor.getUserData(TAG_TREE_HIGHLIGHTERS_IN_EDITOR_KEY); if (oldHighlighters != null) { final MarkupModelEx markupModel = (MarkupModelEx) editor.getMarkupModel(); for (RangeHighlighter highlighter : oldHighlighters) { if (markupModel.containsHighlighter(highlighter)) { highlighter.dispose(); } } editor.putUserData(TAG_TREE_HIGHLIGHTERS_IN_EDITOR_KEY, null); } }
public static void doAnnotate( final Editor editor, final Project project, final FileAnnotation fileAnnotation) { final UpToDateLineNumberProvider getUpToDateLineNumber = new UpToDateLineNumberProviderImpl(editor.getDocument(), project); editor.getGutter().closeAllAnnotations(); // be careful, not proxies but original items are put there (since only their presence not // behaviour is important) Collection<ActiveAnnotationGutter> annotations = editor.getUserData(KEY_IN_EDITOR); if (annotations == null) { annotations = new HashSet<ActiveAnnotationGutter>(); editor.putUserData(KEY_IN_EDITOR, annotations); } final RevuAnnotationFieldGutter gutter = new RevuAnnotationFieldGutter(fileAnnotation, editor); final AnnotationGutterLineConvertorProxy proxy = new AnnotationGutterLineConvertorProxy(getUpToDateLineNumber, gutter); editor.getGutter().registerTextAnnotation(proxy, proxy); annotations.add(gutter); }
private void recreateEditorsPanel() { myValuesPanel.removeAll(); myValuesPanel.setLayout(new CardLayout()); if (!myProject.isOpen()) return; JPanel valuesPanelComponent = new MyJPanel(new GridBagLayout()); myValuesPanel.add( new JBScrollPane(valuesPanelComponent) { @Override public void updateUI() { super.updateUI(); getViewport().setBackground(UIUtil.getPanelBackground()); } }, VALUES); myValuesPanel.add(myNoPropertySelectedPanel, NO_PROPERTY_SELECTED); List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles(); GridBagConstraints gc = new GridBagConstraints( 0, 0, 0, 0, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0); releaseAllEditors(); myTitledPanels.clear(); int y = 0; Editor previousEditor = null; Editor firstEditor = null; for (final PropertiesFile propertiesFile : propertiesFiles) { final Editor editor = createEditor(); final Editor oldEditor = myEditors.put(propertiesFile, editor); if (firstEditor == null) { firstEditor = editor; } if (previousEditor != null) { editor.putUserData( ChooseSubsequentPropertyValueEditorAction.PREV_EDITOR_KEY, previousEditor); previousEditor.putUserData( ChooseSubsequentPropertyValueEditorAction.NEXT_EDITOR_KEY, editor); } previousEditor = editor; if (oldEditor != null) { EditorFactory.getInstance().releaseEditor(oldEditor); } ((EditorEx) editor) .addFocusListener( new FocusChangeListener() { @Override public void focusGained(final Editor editor) { mySelectedEditor = editor; } @Override public void focusLost(final Editor eventEditor) { writeEditorPropertyValue(editor, propertiesFile, null); } }); gc.gridx = 0; gc.gridy = y++; gc.gridheight = 1; gc.gridwidth = GridBagConstraints.REMAINDER; gc.weightx = 1; gc.weighty = 1; gc.anchor = GridBagConstraints.CENTER; Locale locale = propertiesFile.getLocale(); List<String> names = new ArrayList<String>(); if (!Comparing.strEqual(locale.getDisplayLanguage(), null)) { names.add(locale.getDisplayLanguage()); } if (!Comparing.strEqual(locale.getDisplayCountry(), null)) { names.add(locale.getDisplayCountry()); } if (!Comparing.strEqual(locale.getDisplayVariant(), null)) { names.add(locale.getDisplayVariant()); } String title = propertiesFile.getName(); if (!names.isEmpty()) { title += " (" + StringUtil.join(names, "/") + ")"; } JComponent comp = new JPanel(new BorderLayout()) { @Override public Dimension getPreferredSize() { Insets insets = getBorder().getBorderInsets(this); return new Dimension(100, editor.getLineHeight() * 4 + insets.top + insets.bottom); } }; comp.add(editor.getComponent(), BorderLayout.CENTER); comp.setBorder(IdeBorderFactory.createTitledBorder(title, true)); myTitledPanels.put(propertiesFile, (JPanel) comp); valuesPanelComponent.add(comp, gc); } if (previousEditor != null) { previousEditor.putUserData( ChooseSubsequentPropertyValueEditorAction.NEXT_EDITOR_KEY, firstEditor); firstEditor.putUserData( ChooseSubsequentPropertyValueEditorAction.PREV_EDITOR_KEY, previousEditor); } gc.gridx = 0; gc.gridy = y; gc.gridheight = GridBagConstraints.REMAINDER; gc.gridwidth = GridBagConstraints.REMAINDER; gc.weightx = 10; gc.weighty = 1; valuesPanelComponent.add(new JPanel(), gc); selectionChanged(); myValuesPanel.repaint(); UIUtil.invokeAndWaitIfNeeded( new Runnable() { @Override public void run() { updateEditorsFromProperties(); } }); }
public void navigate(int injectedOffset) { if (myAction.isShowInBalloon()) { final JComponent component = myAction.createBalloonComponent(myNewFile); if (component != null) { final Balloon balloon = JBPopupFactory.getInstance() .createBalloonBuilder(component) .setShadow(true) .setAnimationCycle(0) .setHideOnClickOutside(true) .setHideOnKeyOutside(true) .setHideOnAction(false) .setFillColor(UIUtil.getControlColor()) .createBalloon(); new AnAction() { @Override public void actionPerformed(AnActionEvent e) { balloon.hide(); } }.registerCustomShortcutSet(CommonShortcuts.ESCAPE, component); Disposer.register(myNewFile.getProject(), balloon); final Balloon.Position position = QuickEditAction.getBalloonPosition(myEditor); RelativePoint point = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor); if (position == Balloon.Position.above) { final Point p = point.getPoint(); point = new RelativePoint( point.getComponent(), new Point(p.x, p.y - myEditor.getLineHeight())); } balloon.show(point, position); } } else { final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(myProject); final FileEditor[] editors = fileEditorManager.getEditors(myNewVirtualFile); if (editors.length == 0) { final EditorWindow curWindow = fileEditorManager.getCurrentWindow(); mySplittedWindow = curWindow.split(SwingConstants.HORIZONTAL, false, myNewVirtualFile, true); } Editor editor = fileEditorManager.openTextEditor( new OpenFileDescriptor(myProject, myNewVirtualFile, injectedOffset), true); // fold missing values if (editor != null) { editor.putUserData(QuickEditAction.QUICK_EDIT_HANDLER, this); final FoldingModel foldingModel = editor.getFoldingModel(); foldingModel.runBatchFoldingOperation( () -> { for (RangeMarker o : ContainerUtil.reverse(((DocumentEx) myNewDocument).getGuardedBlocks())) { String replacement = o.getUserData(REPLACEMENT_KEY); if (StringUtil.isEmpty(replacement)) continue; FoldRegion region = foldingModel.addFoldRegion(o.getStartOffset(), o.getEndOffset(), replacement); if (region != null) region.setExpanded(false); } }); } SwingUtilities.invokeLater( () -> myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE)); } }
private static void doPaste( final Editor editor, final Project project, final PsiFile file, final Document document, final Producer<Transferable> producer) { Transferable content = null; if (producer != null) { content = producer.produce(); } else { CopyPasteManager manager = CopyPasteManager.getInstance(); if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) { content = manager.getContents(); if (content != null) { manager.stopKillRings(); } } } if (content != null) { String text = null; try { text = (String) content.getTransferData(DataFlavor.stringFlavor); } catch (Exception e) { editor.getComponent().getToolkit().beep(); } if (text == null) return; final CodeInsightSettings settings = CodeInsightSettings.getInstance(); final Map<CopyPastePostProcessor, TextBlockTransferableData> extraData = new HashMap<CopyPastePostProcessor, TextBlockTransferableData>(); for (CopyPastePostProcessor processor : Extensions.getExtensions(CopyPastePostProcessor.EP_NAME)) { TextBlockTransferableData data = processor.extractTransferableData(content); if (data != null) { extraData.put(processor, data); } } text = TextBlockTransferable.convertLineSeparators(text, "\n", extraData.values()); final CaretModel caretModel = editor.getCaretModel(); final SelectionModel selectionModel = editor.getSelectionModel(); final int col = caretModel.getLogicalPosition().column; // There is a possible case that we want to perform paste while there is an active selection // at the editor and caret is located // inside it (e.g. Ctrl+A is pressed while caret is not at the zero column). We want to insert // the text at selection start column // then, hence, inserted block of text should be indented according to the selection start as // well. final int blockIndentAnchorColumn; final int caretOffset = caretModel.getOffset(); if (selectionModel.hasSelection() && caretOffset >= selectionModel.getSelectionStart()) { blockIndentAnchorColumn = editor.offsetToLogicalPosition(selectionModel.getSelectionStart()).column; } else { blockIndentAnchorColumn = col; } // We assume that EditorModificationUtil.insertStringAtCaret() is smart enough to remove // currently selected text (if any). RawText rawText = RawText.fromTransferable(content); String newText = text; for (CopyPastePreProcessor preProcessor : Extensions.getExtensions(CopyPastePreProcessor.EP_NAME)) { newText = preProcessor.preprocessOnPaste(project, file, editor, newText, rawText); } int indentOptions = text.equals(newText) ? settings.REFORMAT_ON_PASTE : CodeInsightSettings.REFORMAT_BLOCK; text = newText; if (LanguageFormatting.INSTANCE.forContext(file) == null && indentOptions != CodeInsightSettings.NO_REFORMAT) { indentOptions = CodeInsightSettings.INDENT_BLOCK; } final String _text = text; ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { EditorModificationUtil.insertStringAtCaret(editor, _text, false, true); } }); int length = text.length(); int offset = caretModel.getOffset() - length; if (offset < 0) { length += offset; offset = 0; } final RangeMarker bounds = document.createRangeMarker(offset, offset + length); caretModel.moveToOffset(bounds.getEndOffset()); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); selectionModel.removeSelection(); final Ref<Boolean> indented = new Ref<Boolean>(Boolean.FALSE); for (Map.Entry<CopyPastePostProcessor, TextBlockTransferableData> e : extraData.entrySet()) { //noinspection unchecked e.getKey() .processTransferableData(project, editor, bounds, caretOffset, indented, e.getValue()); } boolean pastedTextContainsWhiteSpacesOnly = CharArrayUtil.shiftForward(document.getCharsSequence(), bounds.getStartOffset(), " \n\t") >= bounds.getEndOffset(); VirtualFile virtualFile = file.getVirtualFile(); if (!pastedTextContainsWhiteSpacesOnly && (virtualFile == null || !SingleRootFileViewProvider.isTooLargeForIntelligence(virtualFile))) { final int indentOptions1 = indentOptions; ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { switch (indentOptions1) { case CodeInsightSettings.INDENT_BLOCK: if (!indented.get()) { indentBlock( project, editor, bounds.getStartOffset(), bounds.getEndOffset(), blockIndentAnchorColumn); } break; case CodeInsightSettings.INDENT_EACH_LINE: if (!indented.get()) { indentEachLine( project, editor, bounds.getStartOffset(), bounds.getEndOffset()); } break; case CodeInsightSettings.REFORMAT_BLOCK: indentEachLine( project, editor, bounds.getStartOffset(), bounds .getEndOffset()); // this is needed for example when inserting a // comment before method reformatBlock( project, editor, bounds.getStartOffset(), bounds.getEndOffset()); break; } } }); } if (bounds.isValid()) { caretModel.moveToOffset(bounds.getEndOffset()); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); selectionModel.removeSelection(); editor.putUserData(EditorEx.LAST_PASTED_REGION, TextRange.create(bounds)); } } }
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 MarkupModel markupModel = DocumentMarkupModel.forDocument(document, myProject, true); final List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>(); 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 VirtualFile file = psiFile.getVirtualFile(); LOG.assertTrue(file != null); 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); 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<Integer, LineData>(); final TreeMap<Integer, Object[]> classLines = new TreeMap<Integer, Object[]>(); final TreeMap<Integer, String> classNames = new TreeMap<Integer, String>(); 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; } LOG.assertTrue(lineNumberInCurrent < document.getLineCount()); executableLines.put(line, (LineData) lineData); classLines.put(line, postProcessedLines); classNames.put(line, qualifiedName); ApplicationManager.getApplication() .invokeLater( () -> { if (lineNumberInCurrent >= document.getLineCount()) return; final RangeHighlighter highlighter = createRangeHighlighter( suite.getLastCoverageTimeStamp(), markupModel, coverageByTestApplicable, executableLines, qualifiedName, line, lineNumberInCurrent, suite, postProcessedLines); highlighters.add(highlighter); }); } } } } else if (outputFile != null && !subCoverageActive && engine.includeUntouchedFileInCoverage(qualifiedName, outputFile, psiFile, suite)) { collectNonCoveredFileInfo( outputFile, highlighters, markupModel, executableLines, coverageByTestApplicable); } } } 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 (myEditor != null && 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<RangeHighlighter>(); 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()); if (newToOldLineMapping != null) { ApplicationManager.getApplication() .invokeLater( () -> { if (editor.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)); highlighters.add(rangeHighlighter); } } editor.putUserData( COVERAGE_HIGHLIGHTERS, highlighters.size() > 0 ? highlighters : null); }); } }, 100); } } }; document.addDocumentListener(documentListener); editor.putUserData(COVERAGE_DOCUMENT_LISTENER, documentListener); }
public void show() { replaceCriteriaEdit.putUserData( SubstitutionShortInfoHandler.CURRENT_CONFIGURATION_KEY, model.getConfig()); super.show(); }