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