SlideshowEditActivity.java revision 3dbc13db0e4e332b0ab7e9515a7e47cefd70f627
1/* 2 * Copyright (C) 2008 Esmertec AG. 3 * Copyright (C) 2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mms.ui; 19 20import com.google.android.mms.MmsException; 21import com.android.mms.R; 22import com.android.mms.model.IModelChangedObserver; 23import com.android.mms.model.Model; 24import com.android.mms.model.SlideModel; 25import com.android.mms.model.SlideshowModel; 26 27import com.google.android.mms.pdu.PduBody; 28import com.google.android.mms.pdu.PduPersister; 29 30import android.app.ListActivity; 31import android.content.Context; 32import android.content.Intent; 33import android.net.Uri; 34import android.os.Bundle; 35import android.util.Config; 36import android.util.Log; 37import android.view.LayoutInflater; 38import android.view.Menu; 39import android.view.MenuItem; 40import android.view.View; 41import android.view.ViewGroup; 42import android.widget.ArrayAdapter; 43import android.widget.ImageView; 44import android.widget.ListView; 45import android.widget.TextView; 46import android.widget.Toast; 47 48/** 49 * A list of slides which allows user to edit each item in it. 50 */ 51public class SlideshowEditActivity extends ListActivity { 52 private final static String TAG = "SlideshowEditActivity"; 53 private static final boolean DEBUG = false; 54 private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 55 56 // Menu ids. 57 private final static int MENU_MOVE_UP = 0; 58 private final static int MENU_MOVE_DOWN = 1; 59 private final static int MENU_REMOVE_SLIDE = 2; 60 private final static int MENU_ADD_SLIDE = 3; 61 private final static int MENU_DISCARD_SLIDESHOW = 4; 62 63 private final static int REQUEST_CODE_EDIT_SLIDE = 6; 64 65 // State. 66 private final static String STATE = "state"; 67 private final static String SLIDE_INDEX = "slide_index"; 68 private final static String MESSAGE_URI = "message_uri"; 69 70 private ListView mList; 71 private SlideListAdapter mSlideListAdapter; 72 73 private SlideshowModel mSlideshowModel = null; 74 private SlideshowEditor mSlideshowEditor = null; 75 76 private Bundle mState; 77 private Uri mUri; 78 private boolean mDirty; 79 80 @Override 81 protected void onCreate(Bundle icicle) { 82 super.onCreate(icicle); 83 84 mList = getListView(); 85 mList.addFooterView(createAddSlideItem()); 86 87 if (icicle != null) { 88 // Retrieve previously saved state of this activity. 89 mState = icicle.getBundle(STATE); 90 } 91 92 if (mState != null) { 93 mUri = Uri.parse(mState.getString(MESSAGE_URI)); 94 } else { 95 mUri = getIntent().getData(); 96 } 97 98 if (mUri == null) { 99 Log.e(TAG, "Cannot startup activity, null Uri."); 100 finish(); 101 return; 102 } 103 104 try { 105 initSlideList(); 106 } catch (MmsException e) { 107 Log.e(TAG, "Failed to initialize the slide-list.", e); 108 finish(); 109 } 110 } 111 112 private View createAddSlideItem() { 113 View v = ((LayoutInflater) getSystemService( 114 Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.slideshow_edit_item, null); 115 116 // Add slide. 117 TextView text = (TextView) v.findViewById(R.id.slide_number_text); 118 text.setText(R.string.add_slide); 119 120 text = (TextView) v.findViewById(R.id.text_preview); 121 text.setText(R.string.add_slide_hint); 122 123 ImageView image = (ImageView) v.findViewById(R.id.image_preview); 124 image.setImageResource(R.drawable.ic_launcher_slideshow_add_sms); 125 126 return v; 127 } 128 129 @Override 130 protected void onListItemClick(ListView l, View v, int position, long id) { 131 if (position == (l.getCount() - 1)) { 132 addNewSlide(); 133 } else { 134 openSlide(position); 135 } 136 } 137 138 @Override 139 protected void onResume() { 140 super.onResume(); 141 142 if (mState != null) { 143 mList.setSelection(mState.getInt(SLIDE_INDEX, 0)); 144 } 145 } 146 147 /* 148 * (non-Javadoc) 149 * @see android.app.Activity#onSaveInstanceState(android.os.Bundle) 150 */ 151 @Override 152 protected void onSaveInstanceState(Bundle outState) { 153 super.onSaveInstanceState(outState); 154 155 mState = new Bundle(); 156 if (mList.getSelectedItemPosition() >= 0) { 157 mState.putInt(SLIDE_INDEX, mList.getSelectedItemPosition()); 158 } 159 160 if (mUri != null) { 161 mState.putString(MESSAGE_URI, mUri.toString()); 162 } 163 164 if (LOCAL_LOGV) { 165 Log.v(TAG, "Saving state: " + mState); 166 } 167 outState.putBundle(STATE, mState); 168 } 169 170 @Override 171 protected void onPause() { 172 super.onPause(); 173 174 synchronized (this) { 175 if (mDirty) { 176 try { 177 PduBody pb = mSlideshowModel.toPduBody(); 178 PduPersister.getPduPersister(this).updateParts(mUri, pb); 179 mSlideshowModel.sync(pb); 180 } catch (MmsException e) { 181 Log.e(TAG, "Cannot update the message: " + mUri, e); 182 } 183 } 184 } 185 } 186 187 @Override 188 protected void onDestroy() { 189 super.onDestroy(); 190 cleanupSlideshowModel(); 191 } 192 193 private void cleanupSlideshowModel() { 194 if (mSlideshowModel != null) { 195 mSlideshowModel.unregisterModelChangedObserver( 196 mModelChangedObserver); 197 mSlideshowModel = null; 198 } 199 } 200 201 private void initSlideList() throws MmsException { 202 cleanupSlideshowModel(); 203 mSlideshowModel = SlideshowModel.createFromMessageUri(this, mUri); 204 mSlideshowModel.registerModelChangedObserver(mModelChangedObserver); 205 mSlideshowEditor = new SlideshowEditor(this, mSlideshowModel); 206 mSlideListAdapter = new SlideListAdapter( 207 this, R.layout.slideshow_edit_item, mSlideshowModel); 208 mList.setAdapter(mSlideListAdapter); 209 } 210 211 @Override 212 public boolean onPrepareOptionsMenu(Menu menu) { 213 menu.clear(); 214 215 int position = mList.getSelectedItemPosition(); 216 if ((position >= 0) && (position != (mList.getCount() - 1))) { 217 // Selected one slide. 218 if (position > 0) { 219 menu.add(0, MENU_MOVE_UP, 0, R.string.move_up).setIcon(R.drawable.ic_menu_move_up); 220 } 221 222 if (position < (mSlideListAdapter.getCount() - 1)) { 223 menu.add(0, MENU_MOVE_DOWN, 0, R.string.move_down).setIcon( 224 R.drawable.ic_menu_move_down); 225 } 226 227 menu.add(0, MENU_ADD_SLIDE, 0, R.string.add_slide).setIcon(R.drawable.ic_menu_add_slide); 228 229 menu.add(0, MENU_REMOVE_SLIDE, 0, R.string.remove_slide).setIcon( 230 android.R.drawable.ic_menu_delete); 231 } else { 232 menu.add(0, MENU_ADD_SLIDE, 0, R.string.add_slide).setIcon(R.drawable.ic_menu_add_slide); 233 } 234 235 menu.add(0, MENU_DISCARD_SLIDESHOW, 0, 236 R.string.discard_slideshow).setIcon(R.drawable.ic_menu_delete_played); 237 238 return true; 239 } 240 241 @Override 242 public boolean onOptionsItemSelected(MenuItem item) { 243 int position = mList.getSelectedItemPosition(); 244 245 switch (item.getItemId()) { 246 case MENU_MOVE_UP: 247 if ((position > 0) && (position < mSlideshowModel.size())) { 248 mSlideshowEditor.moveSlideUp(position); 249 mSlideListAdapter.notifyDataSetChanged(); 250 mList.setSelection(position - 1); 251 } 252 break; 253 case MENU_MOVE_DOWN: 254 if ((position >= 0) && (position < mSlideshowModel.size() - 1)) { 255 mSlideshowEditor.moveSlideDown(position); 256 mSlideListAdapter.notifyDataSetChanged(); 257 mList.setSelection(position + 1); 258 } 259 break; 260 case MENU_REMOVE_SLIDE: 261 if ((position >= 0) && (position < mSlideshowModel.size())) { 262 mSlideshowEditor.removeSlide(position); 263 mSlideListAdapter.notifyDataSetChanged(); 264 } 265 break; 266 case MENU_ADD_SLIDE: 267 addNewSlide(); 268 break; 269 case MENU_DISCARD_SLIDESHOW: 270 // delete all slides from slideshow. 271 mSlideshowEditor.removeAllSlides(); 272 mSlideListAdapter.notifyDataSetChanged(); 273 finish(); 274 break; 275 } 276 277 return true; 278 } 279 280 private void openSlide(int index) { 281 Intent intent = new Intent(this, SlideEditorActivity.class); 282 intent.setData(mUri); 283 intent.putExtra(SlideEditorActivity.SLIDE_INDEX, index); 284 startActivityForResult(intent, REQUEST_CODE_EDIT_SLIDE); 285 } 286 287 private void addNewSlide() { 288 if ( mSlideshowEditor.addNewSlide() ) { 289 // add successfully 290 mSlideListAdapter.notifyDataSetChanged(); 291 292 // Select the new slide. 293 mList.requestFocus(); 294 mList.setSelection(mSlideshowModel.size() - 1); 295 } else { 296 Toast.makeText(this, R.string.cannot_add_slide_anymore, 297 Toast.LENGTH_SHORT).show(); 298 } 299 } 300 301 @Override 302 protected void onActivityResult(int requestCode, int resultCode, 303 Intent data) { 304 if (resultCode != RESULT_OK) { 305 return; 306 } 307 308 switch(requestCode) { 309 case REQUEST_CODE_EDIT_SLIDE: 310 synchronized (this) { 311 mDirty = true; 312 } 313 setResult(RESULT_OK); 314 315 if ((data != null) && data.getBooleanExtra("done", false)) { 316 finish(); 317 return; 318 } 319 320 try { 321 initSlideList(); 322 } catch (MmsException e) { 323 Log.e(TAG, "Failed to initialize the slide-list.", e); 324 finish(); 325 return; 326 } 327 break; 328 } 329 } 330 331 private static class SlideListAdapter extends ArrayAdapter<SlideModel> { 332 private final Context mContext; 333 private final int mResource; 334 private final LayoutInflater mInflater; 335 private final SlideshowModel mSlideshow; 336 337 public SlideListAdapter(Context context, int resource, 338 SlideshowModel slideshow) { 339 super(context, resource, slideshow); 340 341 mContext = context; 342 mResource = resource; 343 mInflater = LayoutInflater.from(context); 344 mSlideshow = slideshow; 345 } 346 347 @Override 348 public View getView(int position, View convertView, ViewGroup parent) { 349 return createViewFromResource(position, convertView, mResource); 350 } 351 352 private View createViewFromResource(int position, View convertView, int resource) { 353 SlideListItemView slideListItemView; 354 slideListItemView = (SlideListItemView) mInflater.inflate( 355 resource, null); 356 357 // Show slide number. 358 TextView text; 359 text = (TextView) slideListItemView.findViewById(R.id.slide_number_text); 360 text.setText("Slide " + (position + 1)); 361 362 SlideModel slide = getItem(position); 363 int dur = slide.getDuration() / 1000; 364 text = (TextView) slideListItemView.findViewById(R.id.duration_text); 365 text.setText(dur + " secs"); 366 367 Presenter presenter = PresenterFactory.getPresenter( 368 "SlideshowPresenter", mContext, slideListItemView, mSlideshow); 369 ((SlideshowPresenter) presenter).setLocation(position); 370 presenter.present(); 371 372 return slideListItemView; 373 } 374 } 375 376 private final IModelChangedObserver mModelChangedObserver = 377 new IModelChangedObserver() { 378 public void onModelChanged(Model model, boolean dataChanged) { 379 synchronized (SlideshowEditActivity.this) { 380 mDirty = true; 381 } 382 setResult(RESULT_OK); 383 } 384 }; 385} 386