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