From 8df5121cae190c3645670b833de3e4d1aac8d428 Mon Sep 17 00:00:00 2001 From: kruland2607 Date: Mon, 25 Jun 2012 18:30:41 +0000 Subject: [PATCH] Various fixes which should probably be broken into multiple commits:) - Changed the way the ProgressDialog is dismissed from using some non-functional reflection code, to using a FragmentTransaction (which works) - Added code which shows the save button only when the CurrentRocket is modified. - Broke the save functionality into a Fragment with background Task so it is more reliable. git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@808 180e2498-e6e9-4542-8430-84ac67f01cd8 --- ...cket_viewer_configurations_option_menu.xml | 2 +- .../res/menu/rocket_viewer_option_menu.xml | 9 +- .../rocket_viewer_simulation_option_menu.xml | 2 +- .../sf/openrocket/android/CurrentRocket.java | 12 +- .../rocket/OpenRocketLoaderFragment.java | 6 +- .../rocket/OpenRocketSaverFragment.java | 105 ++++++++++++++++++ .../android/rocket/OpenRocketViewer.java | 35 +++--- .../android/util/ProgressDialogFragment.java | 13 --- 8 files changed, 140 insertions(+), 44 deletions(-) create mode 100644 android/src/net/sf/openrocket/android/rocket/OpenRocketSaverFragment.java diff --git a/android/res/menu/rocket_viewer_configurations_option_menu.xml b/android/res/menu/rocket_viewer_configurations_option_menu.xml index e8704258..0464e59a 100644 --- a/android/res/menu/rocket_viewer_configurations_option_menu.xml +++ b/android/res/menu/rocket_viewer_configurations_option_menu.xml @@ -4,7 +4,7 @@ diff --git a/android/res/menu/rocket_viewer_option_menu.xml b/android/res/menu/rocket_viewer_option_menu.xml index 906f539d..eaf7bc22 100644 --- a/android/res/menu/rocket_viewer_option_menu.xml +++ b/android/res/menu/rocket_viewer_option_menu.xml @@ -4,8 +4,8 @@ \ No newline at end of file diff --git a/android/res/menu/rocket_viewer_simulation_option_menu.xml b/android/res/menu/rocket_viewer_simulation_option_menu.xml index e8704258..0464e59a 100644 --- a/android/res/menu/rocket_viewer_simulation_option_menu.xml +++ b/android/res/menu/rocket_viewer_simulation_option_menu.xml @@ -4,7 +4,7 @@ diff --git a/android/src/net/sf/openrocket/android/CurrentRocket.java b/android/src/net/sf/openrocket/android/CurrentRocket.java index a5468eeb..596e2e0c 100644 --- a/android/src/net/sf/openrocket/android/CurrentRocket.java +++ b/android/src/net/sf/openrocket/android/CurrentRocket.java @@ -20,6 +20,8 @@ public class CurrentRocket { private RocketChangedEventHandler handler; + private boolean isModified = false; + public void setHandler( RocketChangedEventHandler handler ) { this.handler = handler; } @@ -32,6 +34,7 @@ public class CurrentRocket { } public void notifySimsChanged() { + isModified = true; if ( handler != null ) { handler.simsChangedMessage(); } @@ -52,6 +55,7 @@ public class CurrentRocket { } public String addNewMotorConfig() { + isModified = true; String configId = rocketDocument.getRocket().newMotorConfigurationID(); if ( handler != null ) { handler.configsChangedMessage(); @@ -63,6 +67,7 @@ public class CurrentRocket { */ public void setRocketDocument(OpenRocketDocument rocketDocument) { this.rocketDocument = rocketDocument; + isModified = false; } public WarningSet getWarnings() { @@ -81,14 +86,17 @@ public class CurrentRocket { this.fileUri = fileUri; } + public boolean isModified() { + return this.isModified; + } + public void saveOpenRocketDocument() throws IOException { OpenRocketSaver saver = new OpenRocketSaver(); StorageOptions options = new StorageOptions(); options.setCompressionEnabled(true); options.setSimulationTimeSkip(StorageOptions.SIMULATION_DATA_ALL); saver.save(new File(fileUri.getPath()),rocketDocument,options); - + isModified = false; } - } diff --git a/android/src/net/sf/openrocket/android/rocket/OpenRocketLoaderFragment.java b/android/src/net/sf/openrocket/android/rocket/OpenRocketLoaderFragment.java index 26193b4a..01b9549f 100644 --- a/android/src/net/sf/openrocket/android/rocket/OpenRocketLoaderFragment.java +++ b/android/src/net/sf/openrocket/android/rocket/OpenRocketLoaderFragment.java @@ -103,10 +103,12 @@ public class OpenRocketLoaderFragment extends Fragment { @Override protected void onPostExecute(OpenRocketLoaderResult result) { super.onPostExecute(result); - AndroidLogWrapper.d(OpenRocketLoaderActivity.class,"Finished loading " + OpenRocketLoaderTask.this); + AndroidLogWrapper.d(OpenRocketLoaderFragment.class,"Finished loading " + OpenRocketLoaderTask.this); Fragment progress = getActivity().getSupportFragmentManager().findFragmentByTag(PROGRESS_DIALOG_TAG); if ( progress != null ) { - ((ProgressDialogFragment)progress).dismissAllowingStateLoss(); + // Remove the fragment instead of trying to use DialogFragment.dismiss. + // If the dialog is now currently shown, dismiss fails. + getFragmentManager().beginTransaction().remove(progress).commitAllowingStateLoss(); } if ( listener != null ) { listener.onOpenRocketFileLoaded(result); diff --git a/android/src/net/sf/openrocket/android/rocket/OpenRocketSaverFragment.java b/android/src/net/sf/openrocket/android/rocket/OpenRocketSaverFragment.java new file mode 100644 index 00000000..353b15c6 --- /dev/null +++ b/android/src/net/sf/openrocket/android/rocket/OpenRocketSaverFragment.java @@ -0,0 +1,105 @@ +package net.sf.openrocket.android.rocket; + +import net.sf.openrocket.android.CurrentRocketHolder; +import net.sf.openrocket.android.util.AndroidLogWrapper; +import net.sf.openrocket.android.util.ProgressDialogFragment; +import android.app.Activity; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class OpenRocketSaverFragment extends Fragment { + + private final static String SAVING_MESSAGE = "Savinging file..."; + + public static OpenRocketSaverFragment newInstance() { + OpenRocketSaverFragment frag = new OpenRocketSaverFragment(); + Bundle b = new Bundle(); + frag.setArguments(b); + return frag; + } + + public interface OnOpenRocketFileSaved { + public void onOpenRocketFileSaved( Boolean result ); + } + + private OpenRocketSaverTask task; + private OnOpenRocketFileSaved listener; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setRetainInstance(true); + Bundle b = getArguments(); + if ( task == null ) { + // since we retain instance state, task will be non-null if it is already loading. + task = new OpenRocketSaverTask(); + task.execute(); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return null; + } + + @Override + public void onActivityCreated(Bundle arg0) { + super.onActivityCreated(arg0); + Activity parent = getActivity(); + if ( parent instanceof OnOpenRocketFileSaved ) { + listener = (OnOpenRocketFileSaved) parent; + } + } + + public class OpenRocketSaverTask extends AsyncTask { + + private final static String PROGRESS_DIALOG_TAG = "progress_dialog"; + + @Override + protected void onPreExecute() { + super.onPreExecute(); + DialogFragment newFragment = ProgressDialogFragment.newInstance("", SAVING_MESSAGE); + newFragment.show(getFragmentManager(), PROGRESS_DIALOG_TAG); + } + + /* (non-Javadoc) + * @see android.os.AsyncTask#doInBackground(Params[]) + */ + @Override + protected Boolean doInBackground(Void... arg0) { + AndroidLogWrapper.d(OpenRocketSaverTask.class, "doInBackgroud"); + + try { + CurrentRocketHolder.getCurrentRocket().saveOpenRocketDocument(); + return true; + } catch (Throwable ex) { + AndroidLogWrapper.e(OpenRocketSaverTask.class, "doInBackground rocketLaoder.load threw {}", ex); + } + return false; + + } + + @Override + protected void onPostExecute(Boolean result) { + super.onPostExecute(result); + AndroidLogWrapper.d(OpenRocketSaverFragment.class,"Finished saving " + OpenRocketSaverTask.this); + Fragment progress = getActivity().getSupportFragmentManager().findFragmentByTag(PROGRESS_DIALOG_TAG); + if ( progress != null ) { + // Remove the fragment instead of trying to use DialogFragment.dismiss. + // If the dialog is now currently shown, dismiss fails. + getFragmentManager().beginTransaction().remove(progress).commitAllowingStateLoss(); + } + if ( listener != null ) { + listener.onOpenRocketFileSaved(result); + } + } + + } + +} diff --git a/android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java b/android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java index 58bb8275..34f8b9d0 100644 --- a/android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java +++ b/android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java @@ -1,8 +1,6 @@ package net.sf.openrocket.android.rocket; -import java.io.IOException; - import net.sf.openrocket.R; import net.sf.openrocket.android.ActivityHelpers; import net.sf.openrocket.android.CurrentRocketHolder; @@ -37,8 +35,6 @@ implements Simulations.OnSimulationSelectedListener private final static int TABSIZE = 4; private OpenRocketViewerPagerAdapter viewPagerAdapter; - - private MenuItem saveAction; @Override protected void onCreate(Bundle savedInstanceState) { @@ -80,7 +76,14 @@ implements Simulations.OnSimulationSelectedListener public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getSupportMenuInflater(); inflater.inflate(R.menu.rocket_viewer_option_menu, menu); - saveAction = menu.findItem(R.id.menu_save); + MenuItem saveAction = menu.findItem(R.id.menu_save); + if ( CurrentRocketHolder.getCurrentRocket().isModified() ) { + saveAction.setVisible(true); + saveAction.setShowAsAction( MenuItem.SHOW_AS_ACTION_ALWAYS ); + } else { + saveAction.setVisible(false); + saveAction.setShowAsAction( MenuItem.SHOW_AS_ACTION_NEVER ); + } return true; } @@ -94,13 +97,9 @@ implements Simulations.OnSimulationSelectedListener return true; case R.id.menu_save: // FIXME - Probably want to open a dialog here. - try { - CurrentRocketHolder.getCurrentRocket().saveOpenRocketDocument(); - saveAction.setVisible(false); - invalidateOptionsMenu(); - } catch ( IOException iex ) { - AndroidLogWrapper.d(OpenRocketViewer.class, iex.getMessage()); - } + getSupportFragmentManager().beginTransaction() + .add( OpenRocketSaverFragment.newInstance(), "saver") + .commitAllowingStateLoss(); return true; case android.R.id.home: ActivityHelpers.goHome(this); @@ -154,13 +153,10 @@ implements Simulations.OnSimulationSelectedListener } private class RocketChangedEventHandler extends net.sf.openrocket.android.RocketChangedEventHandler { - + @Override protected void doSimsChanged() { - if (saveAction != null ) { - saveAction.setVisible(true); - invalidateOptionsMenu(); - } + invalidateOptionsMenu(); Simulations sims = (Simulations) viewPagerAdapter.getFragmentAtPos(SIMS_POS); if ( sims != null ) { sims.refreshSimulationList(); @@ -169,10 +165,7 @@ implements Simulations.OnSimulationSelectedListener @Override protected void doMotorConfigsChanged() { - if (saveAction != null ) { - saveAction.setVisible(true); - invalidateOptionsMenu(); - } + invalidateOptionsMenu(); Configurations configs = (Configurations) viewPagerAdapter.getFragmentAtPos(CONFIGS_POS); if ( configs != null ) { configs.refreshConfigsList(); diff --git a/android/src/net/sf/openrocket/android/util/ProgressDialogFragment.java b/android/src/net/sf/openrocket/android/util/ProgressDialogFragment.java index 954f714a..20a369b5 100644 --- a/android/src/net/sf/openrocket/android/util/ProgressDialogFragment.java +++ b/android/src/net/sf/openrocket/android/util/ProgressDialogFragment.java @@ -20,19 +20,6 @@ public class ProgressDialogFragment extends DialogFragment { return fragment; } - /** - * Expose the private method to allow dismissing a dialog after saveInstanceState. - */ - public void dismissAllowingStateLoss() { - try { - Method dismissInternalMethod = ProgressDialogFragment.class.getMethod("dismissInternal", Boolean.class); - dismissInternalMethod.setAccessible(true); - dismissInternalMethod.invoke(this, true); - } catch (Exception ex ) { - AndroidLogWrapper.d(ProgressDialogFragment.class, "Exception calling dismissAllowingStateInteral"); - } - } - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); -- 2.30.2