Implement a primitive thread safety mechanism to prohibit saving a rocket while simul...
[debian/openrocket] / android / src / net / sf / openrocket / android / rocket / OpenRocketViewer.java
1 package net.sf.openrocket.android.rocket;\r
2 \r
3 \r
4 import net.sf.openrocket.R;\r
5 import net.sf.openrocket.android.ActivityHelpers;\r
6 import net.sf.openrocket.android.CurrentRocketHolder;\r
7 import net.sf.openrocket.android.simulation.SimulationChart;\r
8 import net.sf.openrocket.android.simulation.SimulationViewActivity;\r
9 import net.sf.openrocket.android.simulation.SimulationViewFragment;\r
10 import net.sf.openrocket.android.simulation.Simulations;\r
11 import net.sf.openrocket.android.util.AndroidLogWrapper;\r
12 import net.sf.openrocket.document.OpenRocketDocument;\r
13 import net.sf.openrocket.document.Simulation;\r
14 import android.app.AlertDialog;\r
15 import android.content.DialogInterface;\r
16 import android.content.Intent;\r
17 import android.content.SharedPreferences;\r
18 import android.content.res.Resources;\r
19 import android.os.Bundle;\r
20 import android.preference.PreferenceManager;\r
21 import android.support.v4.app.Fragment;\r
22 import android.support.v4.app.FragmentManager;\r
23 import android.support.v4.app.FragmentPagerAdapter;\r
24 import android.support.v4.app.FragmentTransaction;\r
25 import android.support.v4.view.ViewPager;\r
26 import android.view.View;\r
27 import android.widget.Toast;\r
28 \r
29 import com.actionbarsherlock.view.Menu;\r
30 import com.actionbarsherlock.view.MenuInflater;\r
31 import com.actionbarsherlock.view.MenuItem;\r
32 import com.actionbarsherlock.view.Window;\r
33 \r
34 public class OpenRocketViewer extends OpenRocketLoaderActivity\r
35 implements Simulations.OnSimulationSelectedListener, OpenRocketSaverFragment.OnOpenRocketFileSaved, SharedPreferences.OnSharedPreferenceChangeListener\r
36 {\r
37 \r
38         private final static int OVERVIEW_POS = 0;\r
39         private final static int COMPONENT_POS = 1;\r
40         private final static int SIMS_POS = 2;\r
41         private final static int CONFIGS_POS = 3;\r
42         private final static int TABSIZE = 4;\r
43 \r
44         private OpenRocketViewerPagerAdapter viewPagerAdapter;\r
45 \r
46         private final static String LOAD_AFTER_SAVE = "net.sf.openrocket.android.loadAfterSave";\r
47         private boolean loadAfterSave = false;\r
48         private String autoSaveEnabledKey;\r
49         private boolean autoSaveEnabled = false;\r
50 \r
51         @Override\r
52         protected void onCreate(Bundle savedInstanceState) {\r
53                 super.onCreate(savedInstanceState);\r
54 \r
55                 // If the application sleeps for a long time, the CurrentRocketHolder might get cleaned\r
56                 // up.  When this happens, we cannot restore this state, so instead we just\r
57                 // go home.\r
58                 OpenRocketDocument rocDoc = CurrentRocketHolder.getCurrentRocket().getRocketDocument();\r
59                 if ( rocDoc == null ) {\r
60                         AndroidLogWrapper.d(OpenRocketViewer.class, "No document - go home");\r
61                         ActivityHelpers.goHome(this);\r
62                         finish();\r
63                         return;\r
64                 }\r
65                 if (savedInstanceState != null ) {\r
66                         loadAfterSave = savedInstanceState.getBoolean(LOAD_AFTER_SAVE);\r
67                 }\r
68                 // Must use com.actionbarsherlock.view.Window.FEATURE_INDETERMINATE_PROGRESS\r
69                 requestWindowFeature(Window.FEATURE_PROGRESS);\r
70                 setSupportProgressBarIndeterminate(true);\r
71 \r
72                 setTitle(rocDoc.getRocket().getName());\r
73                 getSupportActionBar().setHomeButtonEnabled(true);\r
74 \r
75                 setContentView(R.layout.openrocketviewer);\r
76                 ViewPager viewPager = (ViewPager)findViewById(R.id.pager);\r
77                 viewPagerAdapter = new OpenRocketViewerPagerAdapter( this.getSupportFragmentManager() );\r
78                 viewPager.setAdapter( viewPagerAdapter );\r
79         }\r
80 \r
81         @Override\r
82         protected void onPause() {\r
83                 CurrentRocketHolder.getCurrentRocket().setHandler(null);\r
84                 SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);\r
85                 pref.unregisterOnSharedPreferenceChangeListener(this);\r
86                 super.onPause();\r
87         }\r
88 \r
89         @Override\r
90         protected void onResume() {\r
91                 Resources resources = this.getResources();\r
92                 autoSaveEnabledKey = resources.getString(R.string.PreferenceAutoSaveOption);\r
93                 SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);\r
94                 autoSaveEnabled = pref.getBoolean(autoSaveEnabledKey, false);\r
95 \r
96                 pref.registerOnSharedPreferenceChangeListener(this);\r
97 \r
98                 RocketChangedEventHandler handler = new RocketChangedEventHandler();\r
99                 CurrentRocketHolder.getCurrentRocket().setHandler(handler);\r
100                 super.onResume();\r
101         }\r
102 \r
103         @Override\r
104         protected void onSaveInstanceState(Bundle outState) {\r
105                 super.onSaveInstanceState(outState);\r
106                 outState.putBoolean(LOAD_AFTER_SAVE, loadAfterSave);\r
107         }\r
108 \r
109         @Override\r
110         public boolean onCreateOptionsMenu(Menu menu) {\r
111                 MenuInflater inflater = getSupportMenuInflater();\r
112                 inflater.inflate(R.menu.rocket_viewer_option_menu, menu);\r
113                 MenuItem saveAction = menu.findItem(R.id.menu_save);\r
114                 if ( CurrentRocketHolder.getCurrentRocket().canSave() ) {\r
115                         saveAction.setVisible(true);\r
116                         saveAction.setShowAsAction( MenuItem.SHOW_AS_ACTION_ALWAYS );\r
117                 } else {\r
118                         saveAction.setVisible(false);\r
119                         saveAction.setShowAsAction( MenuItem.SHOW_AS_ACTION_NEVER );\r
120                 }\r
121                 return true;\r
122         }\r
123 \r
124         @Override\r
125         public boolean onMenuItemSelected(int featureId, MenuItem item) {\r
126                 AndroidLogWrapper.d(OpenRocketViewer.class,"onMenuItemSelected" + item.getItemId());\r
127                 switch(item.getItemId()) {\r
128                 case R.id.menu_load:\r
129                         if ( CurrentRocketHolder.getCurrentRocket().isModified() ) {\r
130                                 AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
131                                 builder.setMessage(R.string.loadWarnUnsaved);\r
132                                 builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {\r
133                                         @Override\r
134                                         public void onClick(DialogInterface dialog, int which) {\r
135                                                 pickOrkFiles();\r
136                                         }\r
137                                 });\r
138                                 builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {\r
139                                         @Override\r
140                                         public void onClick(DialogInterface dialog, int which) {\r
141                                                 OpenRocketViewer.this.loadAfterSave = true;\r
142                                                 OpenRocketViewer.this.saveRocketDocument();\r
143                                         }\r
144                                 });\r
145                                 builder.create().show();\r
146                         } else {\r
147                                 pickOrkFiles();\r
148                         }\r
149                         return true;\r
150                 case R.id.menu_save:\r
151                         OpenRocketViewer.this.saveRocketDocument();\r
152                         return true;\r
153                 case android.R.id.home:\r
154                         ActivityHelpers.goHome(this);\r
155                         return true;\r
156                 case R.id.motor_list_menu_option:\r
157                         ActivityHelpers.browseMotors(this);\r
158                         return true;\r
159                 case R.id.preference_menu_option:\r
160                         ActivityHelpers.startPreferences(this);\r
161                         return true;\r
162                 case R.id.menu_about:\r
163                         ActivityHelpers.showAbout(this);\r
164                         return true;\r
165                 }\r
166                 return super.onMenuItemSelected(featureId, item);\r
167         }\r
168 \r
169         @Override\r
170         public void onSharedPreferenceChanged(SharedPreferences arg0, String arg1) {\r
171                 if ( autoSaveEnabledKey.equals(arg1) ) {\r
172                         autoSaveEnabled = arg0.getBoolean(autoSaveEnabledKey, false);\r
173                 }\r
174         }\r
175 \r
176         @Override\r
177         public void onSimulationSelected(int simulationId) {\r
178 \r
179                 Simulation sim = CurrentRocketHolder.getCurrentRocket().getRocketDocument().getSimulation(simulationId);\r
180                 // Check if there is data for this simulation.\r
181                 if ( sim.getSimulatedData() == null || sim.getSimulatedData().getBranchCount() == 0 ) {\r
182                         // This shouldn't happen because the Simulations list does the check.\r
183                         return;\r
184                 }\r
185 \r
186                 View sidepane = findViewById(R.id.sidepane);\r
187                 if ( /* if multi pane */ sidepane != null ) {\r
188                         SimulationChart chart = new SimulationChart(simulationId);\r
189 \r
190                         Fragment graph = SimulationViewFragment.newInstance(chart);\r
191 \r
192                         FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
193                         ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);\r
194                         // probably only want to update back stack for first time.\r
195                         ft.addToBackStack("simulationplot");\r
196                         ft.replace(R.id.sidepane, graph);\r
197                         ft.show(graph);\r
198                         ft.commit();\r
199 \r
200 \r
201                 } else {\r
202                         Intent i = new Intent(this, SimulationViewActivity.class);\r
203                         i.putExtra("Simulation",simulationId);\r
204                         startActivity(i);\r
205                 }\r
206         }\r
207 \r
208         private void saveRocketDocument() {\r
209                 getSupportFragmentManager().beginTransaction()\r
210                 .add( OpenRocketSaverFragment.newInstance(true), "saver")\r
211                 .commitAllowingStateLoss();\r
212         }\r
213 \r
214         @Override\r
215         public void onOpenRocketFileSaved(Boolean result) {\r
216                 invalidateOptionsMenu();\r
217                 if ( loadAfterSave ) {\r
218                         loadAfterSave = false;\r
219                         pickOrkFiles();\r
220                 }\r
221         }\r
222 \r
223         private class RocketChangedEventHandler extends net.sf.openrocket.android.RocketChangedEventHandler {\r
224 \r
225                 @Override\r
226                 protected void doSimComplete() {\r
227                         if ( autoSaveEnabled ) {\r
228                                 Toast.makeText(OpenRocketViewer.this, R.string.autoSaveMessage, Toast.LENGTH_SHORT).show();\r
229                                 OpenRocketViewer.this.saveRocketDocument();\r
230                         }\r
231                         doSimsChanged();\r
232                 }\r
233 \r
234                 @Override\r
235                 protected void doSimsChanged() {\r
236                         invalidateOptionsMenu();\r
237                         Simulations sims = (Simulations) viewPagerAdapter.getFragmentAtPos(SIMS_POS);\r
238                         if ( sims != null ) {\r
239                                 sims.refreshSimulationList();\r
240                         }\r
241                 }\r
242 \r
243                 @Override\r
244                 protected void doMotorConfigsChanged() {\r
245                         invalidateOptionsMenu();\r
246                         Configurations configs = (Configurations) viewPagerAdapter.getFragmentAtPos(CONFIGS_POS);\r
247                         if ( configs != null ) {\r
248                                 configs.refreshConfigsList();\r
249                         }\r
250                 }\r
251 \r
252         };\r
253 \r
254 \r
255         private class OpenRocketViewerPagerAdapter extends FragmentPagerAdapter {\r
256 \r
257                 public OpenRocketViewerPagerAdapter( FragmentManager fm ) {\r
258                         super(fm);\r
259                 }\r
260                 @Override\r
261                 public int getCount() {\r
262                         return TABSIZE;\r
263                 }\r
264                 @Override\r
265                 public Fragment getItem( int position ) {\r
266                         switch (position) {\r
267                         case OVERVIEW_POS:\r
268                                 return new Overview();\r
269                         case COMPONENT_POS:\r
270                                 return new Component();\r
271                         case SIMS_POS:\r
272                                 return new Simulations();\r
273                         case CONFIGS_POS:\r
274                                 return new Configurations();\r
275                         }\r
276                         return null;\r
277                 }\r
278                 @Override\r
279                 public CharSequence getPageTitle(int position) {\r
280                         switch (position) {\r
281                         case OVERVIEW_POS:\r
282                                 return "Overview";\r
283                         case COMPONENT_POS:\r
284                                 return "Components";\r
285                         case SIMS_POS:\r
286                                 return "Simulations";\r
287                         case CONFIGS_POS:\r
288                                 return "Configurations";\r
289                         }\r
290                         return null;\r
291                 }\r
292 \r
293                 public Fragment getFragmentAtPos( int pos ) {\r
294                         String tag = "android:switcher:"+R.id.pager+":"+pos;\r
295                         Fragment f = OpenRocketViewer.this.getSupportFragmentManager().findFragmentByTag(tag);\r
296                         return f;\r
297                 }\r
298         }\r
299 \r
300 }\r