summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosiah Gaskin <josiahgaskin@google.com>2014-09-18 12:29:14 -0700
committerJosiah Gaskin <josiahgaskin@google.com>2014-09-22 11:07:43 -0700
commit2738ab790f79408aa80970dfef94cd03c95f32c7 (patch)
tree875e6c0e5c4306e9e9cd2de04306a566e6e23680
parentd574df173252b036e649c4a6e8e83892ad2d4d9b (diff)
downloadidea-2738ab790f79408aa80970dfef94cd03c95f32c7.tar.gz
Add Navigation to Named Steps to Dynamic Wizard Infrastructure
This change allows wizards to "jump" between steps/paths by navigating to steps of a given name. Change-Id: I6238b79529b9430f76e87a9be3ee2e85ce535a68
-rw-r--r--android/src/com/android/tools/idea/wizard/AndroidStudioWizardPath.java19
-rw-r--r--android/src/com/android/tools/idea/wizard/ChooseModuleTypeStep.java2
-rw-r--r--android/src/com/android/tools/idea/wizard/DynamicWizard.java46
-rw-r--r--android/src/com/android/tools/idea/wizard/DynamicWizardPath.java36
-rw-r--r--android/src/com/android/tools/idea/wizard/DynamicWizardStep.java8
-rw-r--r--android/src/com/android/tools/idea/wizard/LegacyPathWrapper.java27
-rw-r--r--android/src/com/android/tools/idea/wizard/SingleStepPath.java13
7 files changed, 148 insertions, 3 deletions
diff --git a/android/src/com/android/tools/idea/wizard/AndroidStudioWizardPath.java b/android/src/com/android/tools/idea/wizard/AndroidStudioWizardPath.java
index 96b6e209e50..d3b0f833b40 100644
--- a/android/src/com/android/tools/idea/wizard/AndroidStudioWizardPath.java
+++ b/android/src/com/android/tools/idea/wizard/AndroidStudioWizardPath.java
@@ -16,6 +16,8 @@
package com.android.tools.idea.wizard;
import com.intellij.ide.wizard.Step;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* Interface for the wizard paths
@@ -75,6 +77,18 @@ public interface AndroidStudioWizardPath {
boolean canGoNext();
/**
+ * Returns true if the path contains a step with the given name.
+ */
+ boolean containsStep(@NotNull String stepName, boolean visibleOnly);
+
+ /**
+ * Set the current step to the step with the given name if it exists.
+ * If the step does not exist or is not visible (and visibleOnly is true)
+ * then this is a no-op.
+ */
+ void navigateToNamedStep(@NotNull String stepName, boolean visibleOnly);
+
+ /**
* Determine whether this path is visible as part of the wizard flow.
* Subclasses which implement branching must override this function.
*
@@ -93,6 +107,11 @@ public interface AndroidStudioWizardPath {
void attachToWizard(DynamicWizard dynamicWizard);
/**
+ * Get the wizard that this path is currently attached to
+ */
+ @Nullable DynamicWizard getWizard();
+
+ /**
* Determine whether this path is optional or required.
* Optional paths should be added to the wizard flow AFTER all required paths.
* Once all remaining paths in the wizard are optional, the wizard's finish button
diff --git a/android/src/com/android/tools/idea/wizard/ChooseModuleTypeStep.java b/android/src/com/android/tools/idea/wizard/ChooseModuleTypeStep.java
index ce7c3fbdf56..596aa75a849 100644
--- a/android/src/com/android/tools/idea/wizard/ChooseModuleTypeStep.java
+++ b/android/src/com/android/tools/idea/wizard/ChooseModuleTypeStep.java
@@ -71,7 +71,7 @@ public class ChooseModuleTypeStep extends DynamicWizardStepWithHeaderAndDescript
@Nullable
@Contract("null->null")
- private static Image iconToImage(@Nullable Icon icon) {
+ public static Image iconToImage(@Nullable Icon icon) {
if (icon == null) {
return null;
}
diff --git a/android/src/com/android/tools/idea/wizard/DynamicWizard.java b/android/src/com/android/tools/idea/wizard/DynamicWizard.java
index c9189790adb..4ab50714631 100644
--- a/android/src/com/android/tools/idea/wizard/DynamicWizard.java
+++ b/android/src/com/android/tools/idea/wizard/DynamicWizard.java
@@ -216,13 +216,13 @@ public abstract class DynamicWizard implements ScopedStateStore.ScopedStoreListe
*/
protected final void addPath(@NotNull AndroidStudioWizardPath path) {
myPaths.add(path);
+ path.attachToWizard(this);
// If this is the first visible path, select it
if (myCurrentPath == null && path.isPathVisible()) {
myCurrentPath = path;
}
// Rebuild the iterator to avoid concurrent modification exceptions
- myPathListIterator = new PathIterator(myPaths);
- path.attachToWizard(this);
+ myPathListIterator = new PathIterator(myPaths, myCurrentPath);
}
/**
@@ -457,6 +457,40 @@ public abstract class DynamicWizard implements ScopedStateStore.ScopedStoreListe
myHost.setTitle(title);
}
+ /**
+ * Returns true if a step with the given name exists in this wizard's current configuration.
+ * If visibleOnly is set to true, only visible steps (that are part of visible paths) will
+ * be considered.
+ */
+ public boolean containsStep(@NotNull String stepName, boolean visibleOnly) {
+ for (AndroidStudioWizardPath path : myPaths) {
+ if (visibleOnly && !path.isPathVisible()) {
+ continue;
+ }
+ if (path.containsStep(stepName, visibleOnly)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Navigates this wizard to the step with the given name if it exists. If not, this function
+ * is a no-op. If the requireVisible parameter is set to true, then only currently visible steps (which
+ * are part of currently visible paths) will be considered.
+ */
+ public void navigateToNamedStep(@NotNull String stepName, boolean requireVisible) {
+ for (AndroidStudioWizardPath path : myPaths) {
+ if ((!requireVisible || path.isPathVisible()) && path.containsStep(stepName, requireVisible)) {
+ myCurrentPath = path;
+ myPathListIterator.myCurrentIndex = myPathListIterator.myList.indexOf(myCurrentPath);
+ myCurrentPath.navigateToNamedStep(stepName, requireVisible);
+ showStep(myCurrentPath.getCurrentStep());
+ return;
+ }
+ }
+ }
+
protected static class PathIterator {
private int myCurrentIndex;
@@ -467,6 +501,14 @@ public abstract class DynamicWizard implements ScopedStateStore.ScopedStoreListe
myCurrentIndex = 0;
}
+ public PathIterator(ArrayList<AndroidStudioWizardPath> list, AndroidStudioWizardPath currentLocation) {
+ this(list);
+ int index = myList.indexOf(currentLocation);
+ if (currentLocation != null && index != -1) {
+ myCurrentIndex = index;
+ }
+ }
+
/**
* @return a copy of this iterator
*/
diff --git a/android/src/com/android/tools/idea/wizard/DynamicWizardPath.java b/android/src/com/android/tools/idea/wizard/DynamicWizardPath.java
index f9f663cfad2..7e3eb458def 100644
--- a/android/src/com/android/tools/idea/wizard/DynamicWizardPath.java
+++ b/android/src/com/android/tools/idea/wizard/DynamicWizardPath.java
@@ -86,6 +86,12 @@ public abstract class DynamicWizardPath implements ScopedStateStore.ScopedStoreL
init();
}
+ @Nullable
+ @Override
+ public DynamicWizard getWizard() {
+ return myWizard;
+ }
+
/**
* Set up this path. Addition of steps and other instantiations should be done here.
*/
@@ -398,4 +404,34 @@ public abstract class DynamicWizardPath implements ScopedStateStore.ScopedStoreL
getCurrentStep().invokeUpdate(null);
}
}
+
+ @Override
+ public boolean containsStep(@NotNull String stepName, boolean visibleOnly) {
+ for (DynamicWizardStep step : mySteps) {
+ if (visibleOnly && !step.isStepVisible()) {
+ continue;
+ }
+ if (stepName.equals(step.getStepName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void navigateToNamedStep(@NotNull String stepName, boolean requireVisible) {
+ for (DynamicWizardStep step : mySteps) {
+ if (requireVisible && !step.isStepVisible()) {
+ continue;
+ }
+ if (stepName.equals(step.getStepName())) {
+ myCurrentStep = step;
+ myCurrentStepIndex = mySteps.indexOf(step);
+ myCurrentStep.onEnterStep();
+ myCurrentStep.invokeUpdate(null);
+ invokeUpdate(null);
+ return;
+ }
+ }
+ }
}
diff --git a/android/src/com/android/tools/idea/wizard/DynamicWizardStep.java b/android/src/com/android/tools/idea/wizard/DynamicWizardStep.java
index 7f6b8fc81c1..46e05672313 100644
--- a/android/src/com/android/tools/idea/wizard/DynamicWizardStep.java
+++ b/android/src/com/android/tools/idea/wizard/DynamicWizardStep.java
@@ -115,6 +115,14 @@ public abstract class DynamicWizardStep extends ScopedDataBinder implements Step
return myPath != null ? myPath.getModule() : null;
}
+ @Nullable
+ protected final DynamicWizard getWizard() {
+ if (myPath != null) {
+ return myPath.getWizard();
+ }
+ return null;
+ }
+
/**
* Optionally add an icon to the left side of the screen.
* @return An icon to be displayed on the left side of the wizard.
diff --git a/android/src/com/android/tools/idea/wizard/LegacyPathWrapper.java b/android/src/com/android/tools/idea/wizard/LegacyPathWrapper.java
index 2071b80927f..00c96678b77 100644
--- a/android/src/com/android/tools/idea/wizard/LegacyPathWrapper.java
+++ b/android/src/com/android/tools/idea/wizard/LegacyPathWrapper.java
@@ -106,6 +106,27 @@ public class LegacyPathWrapper implements NewModuleDynamicPath {
}
@Override
+ public boolean containsStep(@NotNull String stepName, boolean visibleOnly) {
+ for (ModuleWizardStep step : mySteps) {
+ if (stepName.equals(step.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void navigateToNamedStep(@NotNull String stepName, boolean requireVisible) {
+ for (ModuleWizardStep step : mySteps) {
+ if (stepName.equals(step.getName())) {
+ myCurrentStep = mySteps.indexOf(step);
+ updateWizard();
+ return;
+ }
+ }
+ }
+
+ @Override
public boolean isPathVisible() {
ModuleTemplate moduleTemplate = myWizard.getState().get(WizardConstants.SELECTED_MODULE_TYPE_KEY);
return moduleTemplate != null && Iterables.contains(myTypes, moduleTemplate);
@@ -127,6 +148,12 @@ public class LegacyPathWrapper implements NewModuleDynamicPath {
myWizard = dynamicWizard;
}
+ @Nullable
+ @Override
+ public DynamicWizard getWizard() {
+ return myWizard;
+ }
+
@Override
public boolean isPathRequired() {
return true;
diff --git a/android/src/com/android/tools/idea/wizard/SingleStepPath.java b/android/src/com/android/tools/idea/wizard/SingleStepPath.java
index 5f6161881a6..c9fac0e88a9 100644
--- a/android/src/com/android/tools/idea/wizard/SingleStepPath.java
+++ b/android/src/com/android/tools/idea/wizard/SingleStepPath.java
@@ -47,4 +47,17 @@ public class SingleStepPath extends DynamicWizardPath {
public boolean performFinishingActions() {
return true;
}
+
+ @Override
+ public boolean validate() {
+ return myStep.validate();
+ }
+
+ @Override
+ public boolean containsStep(@NotNull String stepName, boolean visibleOnly) {
+ if (visibleOnly && !isPathVisible()) {
+ return false;
+ }
+ return stepName.equals(myStep.getStepName());
+ }
}