diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java index 4202df86dd97..14d9ab6527dc 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java @@ -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() { + @Override + public String compute() { + return myXmlFile.getText(); + } + }); + } + @Override protected boolean execute(ThrowableRunnable operation, boolean updateProperties) { try { diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/ExternalPSIChangeListener.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/ExternalPSIChangeListener.java index 12ff7e639f9b..377e4821dbd7 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/ExternalPSIChangeListener.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/ExternalPSIChangeListener.java @@ -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() { - @Override - public String compute() { - return myFile.getText(); - } - }); - } - private void updatePsi(PsiTreeChangeEvent event) { if (myRunState && myFile == event.getFile()) { addRequest(); diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java index 8c1f7e6c8d0e..df72fee777aa 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java @@ -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 mySourceSelectionState = new FixedHashMap(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 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 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 expanded = new ArrayList(); for (int[] path : myExpandedState) { pathToComponent(expanded, myRootComponent, path, 0); } myExpandedComponents = expanded; toolManager.expandFromState(); + myExpandedState = null; + } - List selection = new ArrayList(); - for (int[] path : mySelectionState) { + List selection = new ArrayList(); + + 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 extends HashMap { + private final int mySize; + private final List myKeys = new LinkedList(); + + 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); + } + } } \ No newline at end of file