diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
index 91d01df8..939a0683 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
@@ -31,7 +31,6 @@ import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBar;
-import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.*;
@@ -40,7 +39,6 @@ import android.widget.TextView;
import org.solovyev.android.Activities;
import org.solovyev.android.Android;
import org.solovyev.android.Threads;
-import org.solovyev.android.calculator.about.CalculatorReleaseNotesFragment;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.wizard.CalculatorWizards;
import org.solovyev.android.fragments.FragmentUtils;
@@ -49,7 +47,6 @@ import org.solovyev.android.wizard.Wizard;
import org.solovyev.android.wizard.Wizards;
import org.solovyev.common.Objects;
import org.solovyev.common.history.HistoryAction;
-import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -58,7 +55,9 @@ import static android.os.Build.VERSION_CODES.GINGERBREAD_MR1;
import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static org.solovyev.android.calculator.Preferences.Gui.preventScreenFromFading;
+import static org.solovyev.android.calculator.about.CalculatorReleaseNotesFragment.hasReleaseNotes;
import static org.solovyev.android.wizard.WizardUi.continueWizard;
+import static org.solovyev.android.wizard.WizardUi.createLaunchIntent;
import static org.solovyev.android.wizard.WizardUi.startWizard;
public class CalculatorActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEventListener {
@@ -164,15 +163,11 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference
} else {
if (savedVersion < appVersion) {
final boolean showReleaseNotes = Preferences.Gui.showReleaseNotes.getPreference(preferences);
- if (showReleaseNotes) {
- final String releaseNotes = CalculatorReleaseNotesFragment.getReleaseNotes(context, savedVersion + 1);
- if (!Strings.isEmpty(releaseNotes)) {
- final AlertDialog.Builder builder = new AlertDialog.Builder(context).setMessage(Html.fromHtml(releaseNotes));
- builder.setPositiveButton(android.R.string.ok, null);
- builder.setTitle(R.string.c_release_notes);
- builder.create().show();
- dialogShown = true;
- }
+ if (showReleaseNotes && hasReleaseNotes(context, savedVersion + 1)) {
+ final Bundle bundle = new Bundle();
+ bundle.putInt(CalculatorWizards.RELEASE_NOTES_VERSION, savedVersion);
+ context.startActivity(createLaunchIntent(wizards, CalculatorWizards.RELEASE_NOTES, context, bundle));
+ dialogShown = true;
}
}
}
@@ -180,7 +175,7 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference
//Log.d(this.getClass().getName(), "Application was opened " + appOpenedCounter + " time!");
if (!dialogShown) {
- if (appOpenedCounter != null && appOpenedCounter > 100) {
+ if (appOpenedCounter != null && appOpenedCounter > 30) {
dialogShown = showSpecialWindow(preferences, Preferences.Gui.feedbackWindowShown, R.layout.feedback, R.id.feedbackText, context);
}
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/about/CalculatorReleaseNotesFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/about/CalculatorReleaseNotesFragment.java
index 1b5e8047..e97ff99f 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/about/CalculatorReleaseNotesFragment.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/about/CalculatorReleaseNotesFragment.java
@@ -35,6 +35,8 @@ import org.solovyev.android.calculator.R;
import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.List;
import static org.solovyev.android.Android.getAppVersionCode;
@@ -61,11 +63,11 @@ public class CalculatorReleaseNotesFragment extends CalculatorFragment {
@Nonnull
public static String getReleaseNotes(@Nonnull Context context) {
- return getReleaseNotes(context, 0);
+ return getReleaseNotesString(context, 0);
}
@Nonnull
- public static String getReleaseNotes(@Nonnull Context context, int minVersion) {
+ public static String getReleaseNotesString(@Nonnull Context context, int minVersion) {
final StringBuilder result = new StringBuilder();
final String releaseNotesForTitle = context.getString(R.string.c_release_notes_for_title);
@@ -78,7 +80,6 @@ public class CalculatorReleaseNotesFragment extends CalculatorFragment {
final String versionName = getVersionName(textHelper, versionCode);
String releaseNotesForVersion = textHelper.getText(makeReleaseNotesResourceId(versionCode));
if (!Strings.isEmpty(releaseNotesForVersion)) {
- if (releaseNotesForVersion == null) throw new AssertionError();
if (!first) {
result.append("
");
} else {
@@ -94,7 +95,38 @@ public class CalculatorReleaseNotesFragment extends CalculatorFragment {
}
@Nonnull
- private static String getVersionName(@Nonnull TextHelper textHelper, int versionCode) {
+ public static List getReleaseNotesVersions(@Nonnull Context context, int minVersion) {
+ final List releaseNotes = new ArrayList<>();
+
+ final int currentVersionCode = getAppVersionCode(context);
+ final TextHelper textHelper = new TextHelper(context.getResources(), CalculatorApplication.class.getPackage().getName());
+
+ for (int versionCode = currentVersionCode; versionCode >= minVersion; versionCode--) {
+ final String releaseNotesForVersion = textHelper.getText(makeReleaseNotesResourceId(versionCode));
+ if (!Strings.isEmpty(releaseNotesForVersion)) {
+ releaseNotes.add(versionCode);
+ }
+ }
+
+ return releaseNotes;
+ }
+
+ public static boolean hasReleaseNotes(@Nonnull Context context, int minVersion) {
+ final int currentVersionCode = getAppVersionCode(context);
+ final TextHelper textHelper = new TextHelper(context.getResources(), CalculatorApplication.class.getPackage().getName());
+
+ for (int versionCode = currentVersionCode; versionCode >= minVersion; versionCode--) {
+ String releaseNotesForVersion = textHelper.getText(makeReleaseNotesResourceId(versionCode));
+ if (!Strings.isEmpty(releaseNotesForVersion)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Nonnull
+ public static String getVersionName(@Nonnull TextHelper textHelper, int versionCode) {
final String versionName = textHelper.getText(makeVersionResourceId(versionCode));
if (versionName != null) {
return versionName;
@@ -103,7 +135,7 @@ public class CalculatorReleaseNotesFragment extends CalculatorFragment {
}
}
- private static String makeReleaseNotesResourceId(int versionCode) {
+ public static String makeReleaseNotesResourceId(int versionCode) {
return "c_release_notes_for_" + versionCode;
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/about/TextHelper.java b/android-app/src/main/java/org/solovyev/android/calculator/about/TextHelper.java
index 97d2bbcf..7569565a 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/about/TextHelper.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/about/TextHelper.java
@@ -49,6 +49,9 @@ public class TextHelper {
public String getText(@Nonnull String stringName) {
final int stringId = this.resources.getIdentifier(stringName, "string", this.packageName);
try {
+ if (stringId == 0) {
+ return null;
+ }
return resources.getString(stringId);
} catch (Resources.NotFoundException e) {
return null;
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/release/ReleaseNoteFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/release/ReleaseNoteFragment.java
new file mode 100644
index 00000000..42aecdda
--- /dev/null
+++ b/android-app/src/main/java/org/solovyev/android/calculator/release/ReleaseNoteFragment.java
@@ -0,0 +1,56 @@
+package org.solovyev.android.calculator.release;
+
+import android.os.Bundle;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import com.google.common.base.Strings;
+import org.solovyev.android.calculator.CalculatorApplication;
+import org.solovyev.android.calculator.R;
+import org.solovyev.android.calculator.about.CalculatorReleaseNotesFragment;
+import org.solovyev.android.calculator.about.TextHelper;
+import org.solovyev.android.calculator.wizard.WizardFragment;
+
+import javax.annotation.Nonnull;
+
+public class ReleaseNoteFragment extends WizardFragment {
+ @Nonnull
+ public static final String ARG_VERSION = "version";
+
+ private int version;
+
+ @Override
+ protected int getViewResId() {
+ return R.layout.cpp_release_note_step;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ version = getArguments().getInt(ARG_VERSION, 0);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View view = super.onCreateView(inflater, container, savedInstanceState);
+ final TextView title = (TextView) view.findViewById(R.id.release_note_title);
+ final TextHelper textHelper = new TextHelper(getActivity().getResources(), CalculatorApplication.class.getPackage().getName());
+ title.setText(getString(R.string.cpp_new_in_version, getReleaseNoteVersion(textHelper)));
+ final TextView message = (TextView) view.findViewById(R.id.release_note_message);
+ message.setText(Html.fromHtml(getReleaseNote(textHelper)));
+ return view;
+ }
+
+ @Nonnull
+ private String getReleaseNoteVersion(@Nonnull TextHelper textHelper) {
+ return CalculatorReleaseNotesFragment.getVersionName(textHelper, version);
+ }
+
+ @Nonnull
+ private String getReleaseNote(@Nonnull TextHelper textHelper) {
+ final String resourceId = CalculatorReleaseNotesFragment.makeReleaseNotesResourceId(version);
+ return Strings.nullToEmpty(textHelper.getText(resourceId)).replace("\n", "
");
+ }
+}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/release/ReleaseNoteStep.java b/android-app/src/main/java/org/solovyev/android/calculator/release/ReleaseNoteStep.java
new file mode 100644
index 00000000..3aa050e4
--- /dev/null
+++ b/android-app/src/main/java/org/solovyev/android/calculator/release/ReleaseNoteStep.java
@@ -0,0 +1,86 @@
+package org.solovyev.android.calculator.release;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import org.solovyev.android.wizard.WizardStep;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public class ReleaseNoteStep implements WizardStep {
+ private final int version;
+
+ public ReleaseNoteStep(int version) {
+ this.version = version;
+ }
+
+ public ReleaseNoteStep(@Nonnull Bundle arguments) {
+ this(arguments.getInt(ReleaseNoteFragment.ARG_VERSION, 0));
+ }
+
+ @Nonnull
+ @Override
+ public String getFragmentTag() {
+ return getName();
+ }
+
+ @Nonnull
+ @Override
+ public Class extends Fragment> getFragmentClass() {
+ return ReleaseNoteFragment.class;
+ }
+
+ @Nullable
+ @Override
+ public Bundle getFragmentArgs() {
+ final Bundle bundle = new Bundle();
+ bundle.putInt(ReleaseNoteFragment.ARG_VERSION, version);
+ return bundle;
+ }
+
+ @Override
+ public int getTitleResId() {
+ return 0;
+ }
+
+ @Override
+ public int getNextButtonTitleResId() {
+ return 0;
+ }
+
+ @Override
+ public boolean onNext(@Nonnull Fragment fragment) {
+ return false;
+ }
+
+ @Override
+ public boolean onPrev(@Nonnull Fragment fragment) {
+ return false;
+ }
+
+ @Override
+ public boolean isVisible() {
+ return false;
+ }
+
+ @Nonnull
+ @Override
+ public String getName() {
+ return "release-note-" + version;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final ReleaseNoteStep that = (ReleaseNoteStep) o;
+ return version == that.version;
+
+ }
+
+ @Override
+ public int hashCode() {
+ return version;
+ }
+}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizards.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizards.java
index 2983ccc6..35880ab9 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizards.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizards.java
@@ -2,6 +2,9 @@ package org.solovyev.android.calculator.wizard;
import android.app.Activity;
import android.content.Context;
+import android.os.Bundle;
+import org.solovyev.android.calculator.about.CalculatorReleaseNotesFragment;
+import org.solovyev.android.calculator.release.ReleaseNoteStep;
import org.solovyev.android.wizard.*;
import javax.annotation.Nonnull;
@@ -15,6 +18,8 @@ import static org.solovyev.android.calculator.wizard.CalculatorWizardStep.welcom
public class CalculatorWizards implements Wizards {
public static final String FIRST_TIME_WIZARD = "first-wizard";
+ public static final String RELEASE_NOTES = "release-notes";
+ public static final String RELEASE_NOTES_VERSION = "version";
public static final String DEFAULT_WIZARD_FLOW = "app-wizard";
@Nonnull
@@ -32,20 +37,28 @@ public class CalculatorWizards implements Wizards {
@Nonnull
@Override
- public Wizard getWizard(@Nullable String name) {
+ public Wizard getWizard(@Nullable String name, @Nullable Bundle arguments) {
if (name == null) {
- return getWizard(FIRST_TIME_WIZARD);
+ return getWizard(FIRST_TIME_WIZARD, arguments);
}
if (FIRST_TIME_WIZARD.equals(name)) {
return newBaseWizard(FIRST_TIME_WIZARD, newFirstTimeWizardFlow());
} else if (DEFAULT_WIZARD_FLOW.equals(name)) {
return newBaseWizard(DEFAULT_WIZARD_FLOW, newDefaultWizardFlow());
+ } else if (RELEASE_NOTES.equals(name)) {
+ return newBaseWizard(RELEASE_NOTES, newReleaseNotesWizardFlow(context, arguments));
} else {
throw new IllegalArgumentException("Wizard flow " + name + " is not supported");
}
}
+ @Nonnull
+ @Override
+ public Wizard getWizard(@Nullable String name) throws IllegalArgumentException {
+ return getWizard(name, null);
+ }
+
@Nonnull
private BaseWizard newBaseWizard(@Nonnull String name, @Nonnull WizardFlow flow) {
return new BaseWizard(name, context, flow);
@@ -62,6 +75,21 @@ public class CalculatorWizards implements Wizards {
return new ListWizardFlow(wizardSteps);
}
+ @Nonnull
+ static WizardFlow newReleaseNotesWizardFlow(@Nonnull Context context, @Nullable Bundle arguments) {
+ final List wizardSteps = new ArrayList();
+ final int startVersion = arguments != null ? arguments.getInt(RELEASE_NOTES_VERSION, 0) : 0;
+ List versions = CalculatorReleaseNotesFragment.getReleaseNotesVersions(context, startVersion);
+ final int size = versions.size();
+ if (size > 7) {
+ versions = versions.subList(0, 7);
+ }
+ for (Integer version : versions) {
+ wizardSteps.add(new ReleaseNoteStep(version));
+ }
+ return new ListWizardFlow(wizardSteps);
+ }
+
@Nonnull
static WizardFlow newFirstTimeWizardFlow() {
final List wizardSteps = new ArrayList();
@@ -72,4 +100,5 @@ public class CalculatorWizards implements Wizards {
}
return new ListWizardFlow(wizardSteps);
}
+
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java
index 1eea567f..5a3c9f1c 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java
@@ -102,7 +102,8 @@ public class WizardActivity extends BaseActivity implements WizardsAware {
}
public void finishWizardAbruptly() {
- finishWizardAbruptly(false);
+ final boolean confirmed = wizardUi.getWizard().getName().equals(CalculatorWizards.RELEASE_NOTES);
+ finishWizardAbruptly(confirmed);
}
public void finishWizardAbruptly(boolean confirmed) {
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardFragment.java
index 99841d0e..52063ac7 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardFragment.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardFragment.java
@@ -9,6 +9,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.solovyev.android.calculator.R;
+import org.solovyev.android.calculator.release.ReleaseNoteFragment;
+import org.solovyev.android.calculator.release.ReleaseNoteStep;
import org.solovyev.android.wizard.Wizard;
import org.solovyev.android.wizard.WizardFlow;
import org.solovyev.android.wizard.WizardStep;
@@ -34,7 +36,11 @@ public abstract class WizardFragment extends Fragment implements View.OnClickLis
}
@Nonnull
- private CalculatorWizardStep findStepByClassName() {
+ private WizardStep findStepByClassName() {
+ if (this instanceof ReleaseNoteFragment) {
+ return new ReleaseNoteStep(getArguments());
+ }
+
for (CalculatorWizardStep step : CalculatorWizardStep.values()) {
if (step.getFragmentClass().equals(getClass())) {
return step;
diff --git a/android-app/src/main/java/org/solovyev/android/wizard/WizardUi.java b/android-app/src/main/java/org/solovyev/android/wizard/WizardUi.java
index 0702ccef..120fbe8c 100644
--- a/android-app/src/main/java/org/solovyev/android/wizard/WizardUi.java
+++ b/android-app/src/main/java/org/solovyev/android/wizard/WizardUi.java
@@ -12,6 +12,7 @@ import javax.annotation.Nullable;
public class WizardUi {
private static final String FLOW = "flow";
+ private static final String ARGUMENTS = "arguments";
private static final String STEP = "step";
protected WizardStep step;
@@ -44,7 +45,8 @@ public class WizardUi {
stepName = savedInstanceState.getString(STEP);
}
- wizard = wizardsAware.getWizards().getWizard(wizardName);
+ final Bundle arguments = intent.getBundleExtra(ARGUMENTS);
+ wizard = wizardsAware.getWizards().getWizard(wizardName, arguments);
if (stepName != null) {
step = wizard.getFlow().getStepByName(stepName);
@@ -131,10 +133,16 @@ public class WizardUi {
}
@Nonnull
- private static Intent createLaunchIntent(@Nonnull Wizards wizards, @Nullable String name, @Nonnull Context context) {
+ public static Intent createLaunchIntent(@Nonnull Wizards wizards, @Nullable String name, @Nonnull Context context) {
+ return createLaunchIntent(wizards, name, context, null);
+ }
+
+ @Nonnull
+ public static Intent createLaunchIntent(@Nonnull Wizards wizards, @Nullable String name, @Nonnull Context context, @Nullable Bundle arguments) {
final Intent intent = new Intent(context, wizards.getActivityClassName());
intent.putExtra(FLOW, name);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ intent.putExtra(ARGUMENTS, arguments);
return intent;
}
}
diff --git a/android-app/src/main/java/org/solovyev/android/wizard/Wizards.java b/android-app/src/main/java/org/solovyev/android/wizard/Wizards.java
index 23d6deb8..fe401242 100644
--- a/android-app/src/main/java/org/solovyev/android/wizard/Wizards.java
+++ b/android-app/src/main/java/org/solovyev/android/wizard/Wizards.java
@@ -1,6 +1,7 @@
package org.solovyev.android.wizard;
import android.app.Activity;
+import android.os.Bundle;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -10,6 +11,9 @@ public interface Wizards {
@Nonnull
Class extends Activity> getActivityClassName();
+ @Nonnull
+ public Wizard getWizard(@Nullable String name, @Nullable Bundle arguments) throws IllegalArgumentException;
+
@Nonnull
public Wizard getWizard(@Nullable String name) throws IllegalArgumentException;
}
diff --git a/android-app/src/main/res/layout/cpp_release_note_step.xml b/android-app/src/main/res/layout/cpp_release_note_step.xml
new file mode 100644
index 00000000..504b0ee6
--- /dev/null
+++ b/android-app/src/main/res/layout/cpp_release_note_step.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android-app/src/main/res/values/strings.xml b/android-app/src/main/res/values/strings.xml
index 895a93fa..85481516 100644
--- a/android-app/src/main/res/values/strings.xml
+++ b/android-app/src/main/res/values/strings.xml
@@ -15,4 +15,5 @@
The app is set up and ready to use.
Skip
Finish
+ New in %1$s version
\ No newline at end of file