SlideshowEditActivity.java revision b9bcfdd226bbb6f5b265f925343375192963d58a
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 Intent mResultIntent; 79 private boolean mDirty; 80 81 @Override 82 protected void onCreate(Bundle icicle) { 83 super.onCreate(icicle); 84 85 mList = getListView(); 86 mList.addFooterView(createAddSlideItem()); 87 88 if (icicle != null) { 89 // Retrieve previously saved state of this activity. 90 mState = icicle.getBundle(STATE); 91 } 92 93 if (mState != null) { 94 mUri = Uri.parse(mState.getString(MESSAGE_URI)); 95 } else { 96 mUri = getIntent().getData(); 97 } 98 99 if (mUri == null) { 100 Log.e(TAG, "Cannot startup activity, null Uri."); 101 finish(); 102 return; 103 } 104 105 // Return the Uri of the message to whoever invoked us. 106 mResultIntent = new Intent(); 107 mResultIntent.setData(mUri); 108 109 try { 110 initSlideList(); 111 } catch (MmsException e) { 112 Log.e(TAG, "Failed to initialize the slide-list.", e); 113 finish(); 114 } 115 } 116 117 private View createAddSlideItem() { 118 View v = ((LayoutInflater) getSystemService( 119 Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.slideshow_edit_item, null); 120 121 // Add slide. 122 TextView text = (TextView) v.findViewById(R.id.slide_number_text); 123 text.setText(R.string.add_slide); 124 125 text = (TextView) v.findViewById(R.id.text_preview); 126 text.setText(R.string.add_slide_hint); 127 text.setVisibility(View.VISIBLE); 128 129 ImageView image = (ImageView) v.findViewById(R.id.image_preview); 130 image.setImageResource(R.drawable.ic_launcher_slideshow_add_sms); 131 132 return v; 133 } 134 135 @Override 136 protected void onListItemClick(ListView l, View v, int position, long id) { 137 if (position == (l.getCount() - 1)) { 138 addNewSlide(); 139 } else { 140 openSlide(position); 141 } 142 } 143 144 @Override 145 protected void onResume() { 146 super.onResume(); 147 148 if (mState != null) { 149 mList.setSelection(mState.getInt(SLIDE_INDEX, 0)); 150 } 151 } 152 153 /* 154 * (non-Javadoc) 155 * @see android.app.Activity#onSaveInstanceState(android.os.Bundle) 156 */ 157 @Override 158 protected void onSaveInstanceState(Bundle outState) { 159 super.onSaveInstanceState(outState); 160 161 mState = new Bundle(); 162 if (mList.getSelectedItemPosition() >= 0) { 163 mState.putInt(SLIDE_INDEX, mList.getSelectedItemPosition()); 164 } 165 166 if (mUri != null) { 167 mState.putString(MESSAGE_URI, mUri.toString()); 168 } 169 170 if (LOCAL_LOGV) { 171 Log.v(TAG, "Saving state: " + mState); 172 } 173 outState.putBundle(STATE, mState); 174 } 175 176 @Override 177 protected void onPause() { 178 super.onPause(); 179 180 synchronized (this) { 181 if (mDirty) { 182 try { 183 PduBody pb = mSlideshowModel.toPduBody(); 184 PduPersister.getPduPersister(this).updateParts(mUri, pb); 185 mSlideshowModel.sync(pb); 186 } catch (MmsException e) { 187 Log.e(TAG, "Cannot update the message: " + mUri, e); 188 } 189 } 190 } 191 } 192 193 @Override 194 protected void onDestroy() { 195 super.onDestroy(); 196 cleanupSlideshowModel(); 197 } 198 199 private void cleanupSlideshowModel() { 200 if (mSlideshowModel != null) { 201 mSlideshowModel.unregisterModelChangedObserver( 202 mModelChangedObserver); 203 mSlideshowModel = null; 204 } 205 } 206 207 private void initSlideList() throws MmsException { 208 cleanupSlideshowModel(); 209 mSlideshowModel = SlideshowModel.createFromMessageUri(this, mUri); 210 mSlideshowModel.registerModelChangedObserver(mModelChangedObserver); 211 mSlideshowEditor = new SlideshowEditor(this, mSlideshowModel); 212 mSlideListAdapter = new SlideListAdapter( 213 this, R.layout.slideshow_edit_item, mSlideshowModel); 214 mList.setAdapter(mSlideListAdapter); 215 } 216 217 @Override 218 public boolean onPrepareOptionsMenu(Menu menu) { 219 menu.clear(); 220 221 int position = mList.getSelectedItemPosition(); 222 if ((position >= 0) && (position != (mList.getCount() - 1))) { 223 // Selected one slide. 224 if (position > 0) { 225 menu.add(0, MENU_MOVE_UP, 0, R.string.move_up).setIcon(R.drawable.ic_menu_move_up); 226 } 227 228 if (position < (mSlideListAdapter.getCount() - 1)) { 229 menu.add(0, MENU_MOVE_DOWN, 0, R.string.move_down).setIcon( 230 R.drawable.ic_menu_move_down); 231 } 232 233 menu.add(0, MENU_ADD_SLIDE, 0, R.string.add_slide).setIcon(R.drawable.ic_menu_add_slide); 234 235 menu.add(0, MENU_REMOVE_SLIDE, 0, R.string.remove_slide).setIcon( 236 android.R.drawable.ic_menu_delete); 237 } else { 238 menu.add(0, MENU_ADD_SLIDE, 0, R.string.add_slide).setIcon(R.drawable.ic_menu_add_slide); 239 } 240 241 menu.add(0, MENU_DISCARD_SLIDESHOW, 0, 242 R.string.discard_slideshow).setIcon(R.drawable.ic_menu_delete_played); 243 244 return true; 245 } 246 247 @Override 248 public boolean onOptionsItemSelected(MenuItem item) { 249 int position = mList.getSelectedItemPosition(); 250 251 switch (item.getItemId()) { 252 case MENU_MOVE_UP: 253 if ((position > 0) && (position < mSlideshowModel.size())) { 254 mSlideshowEditor.moveSlideUp(position); 255 mSlideListAdapter.notifyDataSetChanged(); 256 mList.setSelection(position - 1); 257 } 258 break; 259 case MENU_MOVE_DOWN: 260 if ((position >= 0) && (position < mSlideshowModel.size() - 1)) { 261 mSlideshowEditor.moveSlideDown(position); 262 mSlideListAdapter.notifyDataSetChanged(); 263 mList.setSelection(position + 1); 264 } 265 break; 266 case MENU_REMOVE_SLIDE: 267 if ((position >= 0) && (position < mSlideshowModel.size())) { 268 mSlideshowEditor.removeSlide(position); 269 mSlideListAdapter.notifyDataSetChanged(); 270 } 271 break; 272 case MENU_ADD_SLIDE: 273 addNewSlide(); 274 break; 275 case MENU_DISCARD_SLIDESHOW: 276 // delete all slides from slideshow. 277 mSlideshowEditor.removeAllSlides(); 278 mSlideListAdapter.notifyDataSetChanged(); 279 finish(); 280 break; 281 } 282 283 return true; 284 } 285 286 private void openSlide(int index) { 287 Intent intent = new Intent(this, SlideEditorActivity.class); 288 intent.setData(mUri); 289 intent.putExtra(SlideEditorActivity.SLIDE_INDEX, index); 290 startActivityForResult(intent, REQUEST_CODE_EDIT_SLIDE); 291 } 292 293 private void addNewSlide() { 294 if ( mSlideshowEditor.addNewSlide() ) { 295 // add successfully 296 mSlideListAdapter.notifyDataSetChanged(); 297 298 // Select the new slide. 299 mList.requestFocus(); 300 mList.setSelection(mSlideshowModel.size() - 1); 301 } else { 302 Toast.makeText(this, R.string.cannot_add_slide_anymore, 303 Toast.LENGTH_SHORT).show(); 304 } 305 } 306 307 @Override 308 protected void onActivityResult(int requestCode, int resultCode, 309 Intent data) { 310 if (resultCode != RESULT_OK) { 311 return; 312 } 313 314 switch(requestCode) { 315 case REQUEST_CODE_EDIT_SLIDE: 316 synchronized (this) { 317 mDirty = true; 318 } 319 setResult(RESULT_OK, mResultIntent); 320 321 if ((data != null) && data.getBooleanExtra("done", false)) { 322 finish(); 323 return; 324 } 325 326 try { 327 initSlideList(); 328 } catch (MmsException e) { 329 Log.e(TAG, "Failed to initialize the slide-list.", e); 330 finish(); 331 return; 332 } 333 break; 334 } 335 } 336 337 private static class SlideListAdapter extends ArrayAdapter<SlideModel> { 338 private final Context mContext; 339 private final int mResource; 340 private final LayoutInflater mInflater; 341 private final SlideshowModel mSlideshow; 342 343 public SlideListAdapter(Context context, int resource, 344 SlideshowModel slideshow) { 345 super(context, resource, slideshow); 346 347 mContext = context; 348 mResource = resource; 349 mInflater = LayoutInflater.from(context); 350 mSlideshow = slideshow; 351 } 352 353 @Override 354 public View getView(int position, View convertView, ViewGroup parent) { 355 return createViewFromResource(position, convertView, mResource); 356 } 357 358 private View createViewFromResource(int position, View convertView, int resource) { 359 SlideListItemView slideListItemView; 360 slideListItemView = (SlideListItemView) mInflater.inflate( 361 resource, null); 362 363 // Show slide number. 364 TextView text; 365 text = (TextView) slideListItemView.findViewById(R.id.slide_number_text); 366 text.setText("Slide " + (position + 1)); 367 368 SlideModel slide = getItem(position); 369 int dur = slide.getDuration() / 1000; 370 text = (TextView) slideListItemView.findViewById(R.id.duration_text); 371 text.setText(dur + " secs"); 372 373 Presenter presenter = PresenterFactory.getPresenter( 374 "SlideshowPresenter", mContext, slideListItemView, mSlideshow); 375 ((SlideshowPresenter) presenter).setLocation(position); 376 presenter.present(); 377 378 return slideListItemView; 379 } 380 } 381 382 private final IModelChangedObserver mModelChangedObserver = 383 new IModelChangedObserver() { 384 public void onModelChanged(Model model, boolean dataChanged) { 385 synchronized (SlideshowEditActivity.this) { 386 mDirty = true; 387 } 388 setResult(RESULT_OK, mResultIntent); 389 } 390 }; 391} 392