Java tutorial
/* * Copyright (c) 2016-2016 Vladimir Schneider <vladimir.schneider@gmail.com> * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.vladsch.MissingInActions.settings; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.ValidationInfo; import com.vladsch.MissingInActions.Bundle; import com.vladsch.MissingInActions.manager.EditorPositionFactory; import com.vladsch.MissingInActions.manager.LineSelectionManager; import com.vladsch.MissingInActions.util.CaretOffsets; import com.vladsch.MissingInActions.util.NumberSequenceGenerator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.Action; import javax.swing.JComponent; import javax.swing.JPanel; import java.awt.BorderLayout; import java.util.ArrayList; import java.util.List; public class RenumberingDialog extends DialogWrapper { private JPanel myMainPanel; private NumberingOptionsForm myNumberingOptionsForm; private JPanel myViewPanel; private final @NotNull ApplicationSettings mySettings; private final @NotNull EditorEx myEditor; private final @NotNull EditorEx myViewer; public RenumberingDialog(JComponent parent, @NotNull EditorEx editor) { super(parent, false); setTitle(Bundle.message("renumber.title")); mySettings = ApplicationSettings.getInstance(); myEditor = editor; myViewer = createIdeaEditor(""); myViewPanel.add(myViewer.getComponent(), BorderLayout.CENTER); myNumberingOptionsForm.addBaseChangeListener((oldOptions, newOptions) -> { // save the old base numbering options mySettings.setLastNumberingOptions(oldOptions); NumberingOptions newBaseOptions = new NumberingOptions( mySettings.getNumberingBaseOptions(newOptions.getNumberingBase()), newOptions); mySettings.setLastNumberingOptions(newBaseOptions); myNumberingOptionsForm.setOptions(newBaseOptions); }); myNumberingOptionsForm.addChangeListener(options -> updateResults()); copyEditorSettings(); updateResults(); init(); } private void saveSettings() { NumberingOptions options = myNumberingOptionsForm.getOptions(); mySettings.setLastNumberingOptions(options); } private String updateResults() { NumberingOptions options = myNumberingOptionsForm.getOptions(); List<CaretOffsets> carets = new ArrayList<>(myEditor.getCaretModel().getCaretCount()); StringBuilder sb = new StringBuilder(); // copy caret lines to new editor and re-create the carets by replacing selections if they exist // or inserting number at carets if no selection is present ApplicationManager.getApplication().runReadAction(() -> { NumberSequenceGenerator generator = NumberSequenceGenerator.create(options); int line = -1; int offset = -1; CharSequence chars = myEditor.getDocument().getCharsSequence(); EditorPositionFactory f = LineSelectionManager.getInstance(myViewer).getPositionFactory(); int lastVirtual = -1; for (Caret caret : myEditor.getCaretModel().getAllCarets()) { final int caretLine = caret.getLogicalPosition().line; generator.next(caretLine); String number = generator.getNumber(); if (line == -1 || line != caretLine) { // if prev line did not complete, add trailing chars here if (offset >= 0 && line >= 0) { final int endOffset = myEditor.getDocument().getLineEndOffset(line); if (offset < endOffset + 1) { sb.append(chars.subSequence(offset, endOffset + 1)); offset = endOffset + 1; } } line = caretLine; offset = myEditor.getDocument().getLineStartOffset(line); lastVirtual = -1; } if (caret.hasSelection()) { // replace selection by number sb.append(chars.subSequence(offset, caret.getSelectionStart())); int pos = sb.length(); sb.append(number); int end = sb.length(); offset = caret.getSelectionEnd(); CaretOffsets offsets = new CaretOffsets(pos, pos, end); carets.add(offsets); } else { // add number at caret but may need to add virtual spaces sb.append(chars.subSequence(offset, caret.getOffset())); int virtualSpaces = caret.getLogicalPosition().column - (myEditor.getDocument().getLineEndOffset(caretLine) - myEditor.getDocument().getLineStartOffset(caretLine)); if (lastVirtual > 0) { virtualSpaces -= lastVirtual; lastVirtual += virtualSpaces; } else { lastVirtual = virtualSpaces; } while (virtualSpaces-- > 0) sb.append(' '); int pos = sb.length(); sb.append(number); int end = sb.length(); offset = caret.getOffset(); CaretOffsets offsets = new CaretOffsets(pos, pos, end); carets.add(offsets); } } if (offset >= 0 && line >= 0) { final int endOffset = myEditor.getDocument().getLineEndOffset(line); if (offset < endOffset + 1) { sb.append(chars.subSequence(offset, endOffset + 1)); offset = endOffset; } } }); // do the editor preview update from source editor, include carets and selections, replacing selections with numbers WriteCommandAction.runWriteCommandAction(myViewer.getProject(), () -> { final Document document = myViewer.getDocument(); document.setReadOnly(false); //document.replaceString(0, document.getTextLength(), getStringRep(editor, content, false, true, false)); document.replaceString(0, document.getTextLength(), sb); document.setReadOnly(true); }); // create carets in the viewer boolean first = true; myViewer.getCaretModel().removeSecondaryCarets(); for (CaretOffsets offsets : carets) { Caret caret = first ? myViewer.getCaretModel().getPrimaryCaret() : myViewer.getCaretModel().addCaret(myViewer.offsetToVisualPosition(offsets.pos)); first = false; if (caret != null) { // move to logical position and set selection caret.moveToOffset(offsets.pos); caret.setSelection(offsets.start, offsets.end); } } return ""; } @Nullable @Override protected JComponent createCenterPanel() { return myMainPanel; } @NotNull @Override protected Action[] createActions() { super.createDefaultActions(); return new Action[] { getOKAction(), getCancelAction() }; } public static boolean showDialog(JComponent parent, @NotNull EditorEx editor) { RenumberingDialog dialog = new RenumberingDialog(parent, editor); boolean save = dialog.showAndGet(); dialog.saveSettings(); return save; } @Nullable @Override protected ValidationInfo doValidate() { String error = updateResults(); if (!error.isEmpty()) { return new ValidationInfo(error, myNumberingOptionsForm.getPreferredFocusedComponent()); } return super.doValidate(); } @Nullable @Override protected String getDimensionServiceKey() { return "MissingInActions.RegExTestDialog"; } @Nullable @Override public JComponent getPreferredFocusedComponent() { return myNumberingOptionsForm.getPreferredFocusedComponent(); } protected EditorEx createIdeaEditor(CharSequence charSequence) { Document doc = EditorFactory.getInstance().createDocument(charSequence); Editor editor = EditorFactory.getInstance().createEditor(doc, myEditor.getProject(), myEditor.getVirtualFile().getFileType(), true); editor.getSettings().setFoldingOutlineShown(false); editor.getSettings().setLineNumbersShown(false); editor.getSettings().setLineMarkerAreaShown(false); editor.getSettings().setIndentGuidesShown(false); return (EditorEx) editor; } private void createUIComponents() { myNumberingOptionsForm = new NumberingOptionsForm( ApplicationSettings.getInstance().getLastNumberingOptions()); } private void ignoreErrors(Runnable runnable) { try { runnable.run(); } catch (Throwable ignored) { } } private void copyEditorSettings() { //boolean isRightMarginShown(); void setRightMarginShown(boolean val); //boolean areGutterIconsShown(); void setGutterIconsShown(boolean gutterIconsShown); //boolean isAdditionalPageAtBottom(); void setAdditionalPageAtBottom(boolean val); //boolean isAllowSingleLogicalLineFolding(); void setAllowSingleLogicalLineFolding(boolean allow); //boolean isAnimatedScrolling(); void setAnimatedScrolling(boolean val); //boolean isAutoCodeFoldingEnabled(); void setAutoCodeFoldingEnabled(boolean val); //boolean isBlinkCaret(); void setBlinkCaret(boolean blinkCaret); //boolean isBlockCursor(); void setBlockCursor(boolean blockCursor); //boolean isCamelWords(); void setCamelWords(boolean val); //boolean isCaretInsideTabs(); void setCaretInsideTabs(boolean allow); //boolean isCaretRowShown(); void setCaretRowShown(boolean caretRowShown); //boolean isDndEnabled(); void setDndEnabled(boolean val); //boolean isFoldingOutlineShown(); void setFoldingOutlineShown(boolean val); //boolean isIndentGuidesShown(); void setIndentGuidesShown(boolean val); //boolean isInnerWhitespaceShown(); void setInnerWhitespaceShown(boolean val); //boolean isLeadingWhitespaceShown(); void setLeadingWhitespaceShown(boolean val); //boolean isLineMarkerAreaShown(); void setLineMarkerAreaShown(boolean lineMarkerAreaShown); //boolean isLineNumbersShown(); void setLineNumbersShown(boolean val); //boolean isMouseClickSelectionHonorsCamelWords(); void setMouseClickSelectionHonorsCamelWords(boolean val); //boolean isRefrainFromScrolling(); void setRefrainFromScrolling(boolean b); //boolean isSmartHome(); void setSmartHome(boolean val); //boolean isTrailingWhitespaceShown(); void setTrailingWhitespaceShown(boolean val); //boolean isUseCustomSoftWrapIndent(); void setUseCustomSoftWrapIndent(boolean useCustomSoftWrapIndent); //boolean isUseSoftWraps(); void setUseSoftWraps(boolean use); //boolean isVariableInplaceRenameEnabled(); void setVariableInplaceRenameEnabled(boolean val); //boolean isVirtualSpace(); void setVirtualSpace(boolean allow); //boolean isWheelFontChangeEnabled(); void setWheelFontChangeEnabled(boolean val); //boolean isWhitespacesShown(); void setWhitespacesShown(boolean val); //int getAdditionalColumnsCount(); void setAdditionalColumnsCount(int additionalColumnsCount); //int getAdditionalLinesCount(); void setAdditionalLinesCount(int additionalLinesCount); //int getCaretBlinkPeriod(); void setCaretBlinkPeriod(int blinkPeriod); //int getCustomSoftWrapIndent(); void setCustomSoftWrapIndent(int indent); //int getLineCursorWidth(); void setLineCursorWidth(int width); EditorSettings myViewerSettings = myViewer.getSettings(); EditorSettings myEditorSettings = myEditor.getSettings(); Project myEditorProject = myEditor.getProject(); // @formatter:off ignoreErrors(() -> { myViewerSettings.setRightMarginShown(myEditorSettings.isRightMarginShown()); }); ignoreErrors(() -> { myViewerSettings.setGutterIconsShown(myEditorSettings.areGutterIconsShown()); }); ignoreErrors(() -> { myViewerSettings.setAdditionalPageAtBottom(myEditorSettings.isAdditionalPageAtBottom()); }); ignoreErrors(() -> { myViewerSettings.setAllowSingleLogicalLineFolding(myEditorSettings.isAllowSingleLogicalLineFolding()); }); ignoreErrors(() -> { myViewerSettings.setAnimatedScrolling(myEditorSettings.isAnimatedScrolling()); }); ignoreErrors(() -> { myViewerSettings.setAutoCodeFoldingEnabled(myEditorSettings.isAutoCodeFoldingEnabled()); }); ignoreErrors(() -> { myViewerSettings.setBlinkCaret(myEditorSettings.isBlinkCaret()); }); ignoreErrors(() -> { myViewerSettings.setBlockCursor(myEditorSettings.isBlockCursor()); }); ignoreErrors(() -> { myViewerSettings.setCamelWords(myEditorSettings.isCamelWords()); }); ignoreErrors(() -> { myViewerSettings.setCaretInsideTabs(myEditorSettings.isCaretInsideTabs()); }); ignoreErrors(() -> { myViewerSettings.setCaretRowShown(myEditorSettings.isCaretRowShown()); }); ignoreErrors(() -> { myViewerSettings.setDndEnabled(myEditorSettings.isDndEnabled()); }); ignoreErrors(() -> { myViewerSettings.setFoldingOutlineShown(myEditorSettings.isFoldingOutlineShown()); }); ignoreErrors(() -> { myViewerSettings.setIndentGuidesShown(myEditorSettings.isIndentGuidesShown()); }); ignoreErrors(() -> { myViewerSettings.setInnerWhitespaceShown(myEditorSettings.isInnerWhitespaceShown()); }); ignoreErrors(() -> { myViewerSettings.setLeadingWhitespaceShown(myEditorSettings.isLeadingWhitespaceShown()); }); ignoreErrors(() -> { myViewerSettings.setLineMarkerAreaShown(myEditorSettings.isLineMarkerAreaShown()); }); ignoreErrors(() -> { myViewerSettings.setLineNumbersShown(myEditorSettings.isLineNumbersShown()); }); ignoreErrors(() -> { myViewerSettings.setMouseClickSelectionHonorsCamelWords( myEditorSettings.isMouseClickSelectionHonorsCamelWords()); }); ignoreErrors(() -> { myViewerSettings.setRefrainFromScrolling(myEditorSettings.isRefrainFromScrolling()); }); ignoreErrors(() -> { myViewerSettings.setSmartHome(myEditorSettings.isSmartHome()); }); ignoreErrors(() -> { myViewerSettings.setTrailingWhitespaceShown(myEditorSettings.isTrailingWhitespaceShown()); }); ignoreErrors(() -> { myViewerSettings.setUseCustomSoftWrapIndent(myEditorSettings.isUseCustomSoftWrapIndent()); }); ignoreErrors(() -> { myViewerSettings.setUseSoftWraps(myEditorSettings.isUseSoftWraps()); }); //ignoreErrors(()->{myViewerSettings.setVariableInplaceRenameEnabled(myEditorSettings.isVariableInplaceRenameEnabled()); }); ignoreErrors(() -> { myViewerSettings.setVirtualSpace(myEditorSettings.isVirtualSpace()); }); ignoreErrors(() -> { myViewerSettings.setWheelFontChangeEnabled(myEditorSettings.isWheelFontChangeEnabled()); }); ignoreErrors(() -> { myViewerSettings.setWhitespacesShown(myEditorSettings.isWhitespacesShown()); }); //ignoreErrors(()->{myViewerSettings.setAdditionalColumnsCount(myEditorSettings.getAdditionalColumnsCount()); }); //ignoreErrors(()->{myViewerSettings.setAdditionalLinesCount(myEditorSettings.getAdditionalLinesCount()); }); ignoreErrors(() -> { myViewerSettings.setCaretBlinkPeriod(myEditorSettings.getCaretBlinkPeriod()); }); ignoreErrors(() -> { myViewerSettings.setCustomSoftWrapIndent(myEditorSettings.getCustomSoftWrapIndent()); }); ignoreErrors(() -> { myViewerSettings.setLineCursorWidth(myEditorSettings.getLineCursorWidth()); }); // @formatter:on //boolean isUseTabCharacter(Project project); void setUseTabCharacter(boolean useTabCharacter); //boolean isWrapWhenTypingReachesRightMargin(Project project); void setWrapWhenTypingReachesRightMargin(boolean val); //int getRightMargin(Project project); void setRightMargin(int myRightMargin); //int getTabSize(Project project); void setTabSize(int tabSize); // @formatter:off ignoreErrors(() -> { myViewerSettings.setUseTabCharacter(myEditorSettings.isUseTabCharacter(myEditorProject)); }); //ignoreErrors(() -> { myViewerSettings.setWrapWhenTypingReachesRightMargin(myEditorSettings.isWrapWhenTypingReachesRightMargin(myEditorProject)); }); ignoreErrors(() -> { myViewerSettings.setRightMargin(myEditorSettings.getRightMargin(myEditorProject)); }); ignoreErrors(() -> { myViewerSettings.setTabSize(myEditorSettings.getTabSize(myEditorProject)); }); // @formatter:on } }