mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Restore state: change editor, undo, redo, external psi update
This commit is contained in:
+10
@@ -516,6 +516,16 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
|
||||
return new AndroidPasteFactory(getProject(), xmlComponents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEditorText() {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return myXmlFile.getText();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(ThrowableRunnable<Exception> operation, boolean updateProperties) {
|
||||
try {
|
||||
|
||||
+3
-14
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package com.intellij.android.designer.designSurface;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiTreeChangeAdapter;
|
||||
@@ -44,7 +42,7 @@ public class ExternalPSIChangeListener extends PsiTreeChangeAdapter {
|
||||
myFile = file;
|
||||
myDelayMillis = delayMillis;
|
||||
myRunnable = runnable;
|
||||
myContent = getContent();
|
||||
myContent = myDesigner.getEditorText();
|
||||
}
|
||||
|
||||
public void setInitialize() {
|
||||
@@ -69,7 +67,7 @@ public class ExternalPSIChangeListener extends PsiTreeChangeAdapter {
|
||||
public void activate() {
|
||||
if (!myRunState) {
|
||||
start();
|
||||
if (!ComparatorUtil.equalsNullable(myContent, getContent()) || myDesigner.getRootComponent() == null) {
|
||||
if (!ComparatorUtil.equalsNullable(myContent, myDesigner.getEditorText()) || myDesigner.getRootComponent() == null) {
|
||||
addRequest();
|
||||
}
|
||||
myContent = null;
|
||||
@@ -79,19 +77,10 @@ public class ExternalPSIChangeListener extends PsiTreeChangeAdapter {
|
||||
public void deactivate() {
|
||||
if (myRunState) {
|
||||
stop();
|
||||
myContent = getContent();
|
||||
myContent = myDesigner.getEditorText();
|
||||
}
|
||||
}
|
||||
|
||||
private String getContent() {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return myFile.getText();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updatePsi(PsiTreeChangeEvent event) {
|
||||
if (myRunState && myFile == event.getFile()) {
|
||||
addRequest();
|
||||
|
||||
+87
-17
@@ -60,7 +60,7 @@ import java.awt.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -108,6 +108,8 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
private Property mySelectionProperty;
|
||||
private int[][] myExpandedState;
|
||||
private int[][] mySelectionState;
|
||||
private final Map<String, int[][]> mySourceSelectionState = new FixedHashMap<String, int[][]>(16);
|
||||
private ComponentSelectionListener mySourceSelectionListener;
|
||||
|
||||
private JPanel myErrorPanel;
|
||||
private JPanel myErrorMessages;
|
||||
@@ -286,6 +288,14 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
add(myDesignerCard, DESIGNER_CARD);
|
||||
|
||||
PaletteManager.getInstance(getProject()).addSelectionListener(myPaletteListener);
|
||||
|
||||
mySourceSelectionListener = new ComponentSelectionListener() {
|
||||
@Override
|
||||
public void selectionChanged(EditableArea area) {
|
||||
storeSourceSelectionState();
|
||||
}
|
||||
};
|
||||
mySurfaceArea.addSelectionListener(mySourceSelectionListener);
|
||||
}
|
||||
|
||||
protected final void showDesignerCard() {
|
||||
@@ -521,8 +531,6 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
}
|
||||
|
||||
protected void storeState() {
|
||||
// TODO: store selection state (listener) for source code key
|
||||
|
||||
if (myRootComponent != null && myExpandedState == null && mySelectionState == null) {
|
||||
myExpandedState = new int[myExpandedComponents == null ? 0 : myExpandedComponents.size()][];
|
||||
for (int i = 0; i < myExpandedState.length; i++) {
|
||||
@@ -531,20 +539,34 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
myExpandedState[i] = path.toArray();
|
||||
}
|
||||
|
||||
List<RadComponent> selection = mySurfaceArea.getSelection();
|
||||
mySelectionState = new int[selection.size()][];
|
||||
for (int i = 0; i < mySelectionState.length; i++) {
|
||||
IntArrayList path = new IntArrayList();
|
||||
componentToPath(selection.get(i), path);
|
||||
mySelectionState[i] = path.toArray();
|
||||
}
|
||||
mySelectionState = getSelectionState();
|
||||
|
||||
myExpandedComponents = null;
|
||||
myToolProvider.loadDefaultTool();
|
||||
|
||||
mySurfaceArea.removeSelectionListener(mySourceSelectionListener);
|
||||
mySurfaceArea.deselectAll();
|
||||
mySurfaceArea.addSelectionListener(mySourceSelectionListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeSourceSelectionState() {
|
||||
mySourceSelectionState.put(getEditorText(), getSelectionState());
|
||||
}
|
||||
|
||||
private int[][] getSelectionState() {
|
||||
List<RadComponent> selection = mySurfaceArea.getSelection();
|
||||
int[][] selectionState = new int[selection.size()][];
|
||||
|
||||
for (int i = 0; i < selectionState.length; i++) {
|
||||
IntArrayList path = new IntArrayList();
|
||||
componentToPath(selection.get(i), path);
|
||||
selectionState[i] = path.toArray();
|
||||
}
|
||||
|
||||
return selectionState;
|
||||
}
|
||||
|
||||
private static void componentToPath(RadComponent component, IntArrayList path) {
|
||||
RadComponent parent = component.getParent();
|
||||
|
||||
@@ -557,25 +579,40 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
protected void restoreState() {
|
||||
DesignerToolWindowManager toolManager = DesignerToolWindowManager.getInstance(getProject());
|
||||
|
||||
if (myExpandedState == null || mySelectionProperty == null || myRootComponent == null) {
|
||||
toolManager.refresh(true);
|
||||
}
|
||||
else {
|
||||
if (myExpandedState != null) {
|
||||
List<RadComponent> expanded = new ArrayList<RadComponent>();
|
||||
for (int[] path : myExpandedState) {
|
||||
pathToComponent(expanded, myRootComponent, path, 0);
|
||||
}
|
||||
myExpandedComponents = expanded;
|
||||
toolManager.expandFromState();
|
||||
myExpandedState = null;
|
||||
}
|
||||
|
||||
List<RadComponent> selection = new ArrayList<RadComponent>();
|
||||
for (int[] path : mySelectionState) {
|
||||
List<RadComponent> selection = new ArrayList<RadComponent>();
|
||||
|
||||
int[][] selectionState = mySourceSelectionState.get(getEditorText());
|
||||
if (selectionState != null) {
|
||||
for (int[] path : selectionState) {
|
||||
pathToComponent(selection, myRootComponent, path, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (selection.isEmpty()) {
|
||||
if (mySelectionState != null) {
|
||||
for (int[] path : mySelectionState) {
|
||||
pathToComponent(selection, myRootComponent, path, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selection.isEmpty()) {
|
||||
toolManager.refresh(true);
|
||||
}
|
||||
else {
|
||||
mySurfaceArea.setSelection(selection);
|
||||
}
|
||||
|
||||
myExpandedState = null;
|
||||
mySelectionState = null;
|
||||
}
|
||||
|
||||
@@ -618,6 +655,8 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
@Nullable
|
||||
public abstract ComponentPasteFactory createPasteFactory(String xmlComponents);
|
||||
|
||||
public abstract String getEditorText();
|
||||
|
||||
public void activate() {
|
||||
}
|
||||
|
||||
@@ -812,4 +851,35 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
myAdditionalFixes = additionalFixes;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FixedHashMap<K, V> extends HashMap<K, V> {
|
||||
private final int mySize;
|
||||
private final List<K> myKeys = new LinkedList<K>();
|
||||
|
||||
public FixedHashMap(int size) {
|
||||
mySize = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
if (!myKeys.contains(key)) {
|
||||
if (myKeys.size() >= mySize) {
|
||||
remove(myKeys.remove(0));
|
||||
}
|
||||
myKeys.add(key);
|
||||
}
|
||||
return super.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
if (myKeys.contains(key)) {
|
||||
int index = myKeys.indexOf(key);
|
||||
int last = myKeys.size() - 1;
|
||||
myKeys.set(index, myKeys.get(last));
|
||||
myKeys.set(last, (K)key);
|
||||
}
|
||||
return super.get(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user