This commit is contained in:
Gregory Shrago
2010-11-10 22:26:05 +03:00
parent 9f8cdadd02
commit c0a5801a9b
2 changed files with 13 additions and 205 deletions
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.intention.LowPriorityAction;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.lang.Language;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonShortcuts;
@@ -40,10 +41,7 @@ import com.intellij.openapi.fileEditor.impl.EditorWindow;
import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
@@ -65,18 +63,10 @@ import java.util.Map;
import java.util.Set;
/**
* "Quick Edit Language" intention action that provides a popup which shows an injected language
* "Quick Edit Language" intention action that provides an editor which shows an injected language
* fragment's complete prefix and suffix in non-editable areas and allows to edit the fragment
* without having to consider any additional escaping rules (e.g. when editing regexes in String
* literals).
* <p/>
* This is a bit experimental because it doesn't play very well with some quickfixes, such as the
* JavaScript's "Create Method/Function" one which opens another editor window. Though harmless,
* this is quite confusing.
* <p/>
* I wonder if such QuickFixes should try to get an Editor from the DataContext
* (see {@link QuickEditEditor.MyPanel#getData(java.lang.String)}) instead of using the "tactical nuke"
* com.intellij.openapi.fileEditor.FileEditorManager#openTextEditor(com.intellij.openapi.fileEditor.OpenFileDescriptor, boolean).
*/
public class QuickEditAction implements IntentionAction, LowPriorityAction {
@@ -139,7 +129,7 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
return handler;
}
private static class MyHandler extends DocumentAdapter {
private static class MyHandler extends DocumentAdapter implements Disposable {
private final Project myProject;
private final PsiFile myInjectedFile;
@@ -199,20 +189,19 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
closeEditor();
}
}.registerCustomShortcutSet(CommonShortcuts.ESCAPE, event.getEditor().getContentComponent());
}
}
@Override
public void editorReleased(EditorFactoryEvent event) {
if (event.getEditor().getDocument() == myNewDocument) {
Disposer.dispose(MyHandler.this);
myReleased = true;
event.getFactory().removeEditorFactoryListener(this);
myOrigDocument.removeDocumentListener(MyHandler.this);
myInjectedFile.putUserData(QUICK_EDIT_HANDLER, null);
}
}
}, project);
}, this);
initMarkers(shreds);
}
@@ -261,15 +250,11 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
myOrigDocument.createRangeMarker(rangeInsideHost.shiftRight(shred.host.getTextRange().getStartOffset()));
myMarkers.put(smartPointerManager.createSmartPsiElementPointer(shred.host), Pair.create(origMarker, rangeMarker));
}
boolean first = true;
for (Pair<RangeMarker, RangeMarker> markers : myMarkers.values()) {
//if (first) {
markers.first.setGreedyToLeft(true);
markers.second.setGreedyToLeft(true);
//}
markers.first.setGreedyToLeft(true);
markers.second.setGreedyToLeft(true);
markers.first.setGreedyToRight(true);
markers.second.setGreedyToRight(true);
first = false;
}
int curOffset = 0;
for (Pair<RangeMarker, RangeMarker> markerPair : myMarkers.values()) {
@@ -346,5 +331,10 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
ElementManipulators.getManipulator(host).handleContentChange(host, insideHost, sb.toString());
}
}
@Override
public void dispose() {
// noop
}
}
}
@@ -1,182 +0,0 @@
/*
* Copyright 2006 Sascha Weinreuter
*
* 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 org.intellij.plugins.intelliLang.inject.quickedit;
import com.intellij.ide.highlighter.HighlighterFactory;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.EditorSettings;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.ui.plaf.beg.BegBorders;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
// Adapted from QuickEditHotspot that came with the source of the first designer release ;)
public class QuickEditEditor {
private final Project myProject;
private final JComponent myPanel;
private final QuickEditSaver mySaver;
private EditorEx myEditor;
private JBPopup myPopup;
private Boolean myCancelFlag;
public QuickEditEditor(Document document, Project project, FileType ft, @NotNull QuickEditSaver saver) {
myProject = project;
mySaver = saver;
myEditor = (EditorImpl)EditorFactory.getInstance().createEditor(document, project);
myEditor.setHighlighter(HighlighterFactory.createHighlighter(project, ft));
myEditor.setEmbeddedIntoDialogWrapper(true);
EditorSettings settings = myEditor.getSettings();
settings.setFoldingOutlineShown(false);
settings.setLineMarkerAreaShown(false);
settings.setIndentGuidesShown(false);
settings.setLineNumbersShown(false);
settings.setVirtualSpace(false);
settings.setAdditionalLinesCount(2);
myPanel = new MyPanel();
}
public JComponent getPreferredFocusedComponent() {
return myEditor.getContentComponent();
}
public Editor getEditor() {
return myEditor;
}
private class MyPanel extends JPanel implements DataProvider {
public MyPanel() {
super(new BorderLayout());
add(myEditor.getComponent(), BorderLayout.CENTER);
setBorder(new BegBorders.FlatLineBorder());
setPreferredSize(new Dimension(400, 100));
}
public Object getData(String s) {
if (LangDataKeys.EDITOR.is(s)) {
return myEditor;
}
return null;
}
}
public void setCancel(boolean cancel) {
if (myCancelFlag == null) myCancelFlag = cancel;
}
private String releaseEditor() {
if (myEditor != null) {
final Document document = myEditor.getDocument();
final String text = document.getText();
PsiDocumentManager.getInstance(myProject).commitDocument(document);
EditorFactory.getInstance().releaseEditor(myEditor);
myEditor = null;
return text;
}
return "";
}
public void install(JBPopup popup) {
myPopup = popup;
final JComponent component = myEditor.getContentComponent();
component.requestFocus();
new EscAction(this).registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)), component);
new SaveAction(this)
.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK)), component);
setStatusBarText("Press Ctrl+Enter to save, Escape to cancel.");
}
private void setStatusBarText(String text) {
StatusBar.Info.set(text, myProject);
}
public void uninstall() {
setStatusBarText("");
final String text = releaseEditor();
assert myCancelFlag != null;
if (!myCancelFlag) {
new WriteCommandAction(myProject) {
protected void run(Result result) throws Throwable {
mySaver.save(text);
}
}.execute();
}
myPopup = null;
}
public JComponent getComponent() {
return myPanel;
}
public interface QuickEditSaver {
void save(String text);
}
private static class EscAction extends AnAction {
private final QuickEditEditor myEditor;
public EscAction(QuickEditEditor editor) {
super("Esc");
myEditor = editor;
}
public void actionPerformed(AnActionEvent event) {
myEditor.setCancel(true);
myEditor.myPopup.cancel();
}
}
private static class SaveAction extends AnAction {
private final QuickEditEditor myEditor;
public SaveAction(QuickEditEditor editor) {
super("Save");
myEditor = editor;
}
public void actionPerformed(AnActionEvent event) {
myEditor.setCancel(false);
myEditor.myPopup.cancel();
}
}
}