• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.deskclock.worldclock;
18 
19 import android.app.ActionBar;
20 import android.app.Activity;
21 import android.content.ActivityNotFoundException;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.os.Bundle;
25 import android.preference.PreferenceManager;
26 import android.text.format.DateFormat;
27 import android.view.LayoutInflater;
28 import android.view.Menu;
29 import android.view.MenuItem;
30 import android.view.View;
31 import android.view.ViewGroup;
32 import android.widget.BaseAdapter;
33 import android.widget.CheckBox;
34 import android.widget.CompoundButton;
35 import android.widget.CompoundButton.OnCheckedChangeListener;
36 import android.widget.ListView;
37 import android.widget.SectionIndexer;
38 import android.widget.TextView;
39 
40 import com.android.deskclock.Alarms;
41 import com.android.deskclock.DeskClock;
42 import com.android.deskclock.R;
43 import com.android.deskclock.SettingsActivity;
44 import com.android.deskclock.Utils;
45 
46 import java.text.Collator;
47 import java.util.ArrayList;
48 import java.util.Calendar;
49 import java.util.HashMap;
50 import java.util.TimeZone;
51 
52 /**
53  * Cities chooser for the world clock
54  */
55 public class CitiesActivity extends Activity implements OnCheckedChangeListener, View.OnClickListener {
56 
57     /** This must be false for production.  If true, turns on logging,
58         test code, etc. */
59     static final boolean DEBUG = false;
60     static final String TAG = "CitiesActivity";
61 
62     private LayoutInflater mFactory;
63     private ListView mCitiesList;
64     private CityAdapter mAdapter;
65     private HashMap<String, CityObj> mUserSelectedCities;
66     private Calendar mCalendar;
67 
68 /***
69 * Adapter for a list of cities with the respected time zone.
70 * The Adapter sorts the list alphabetically and create an indexer.
71 ***/
72 
73     private class CityAdapter extends BaseAdapter implements SectionIndexer {
74         private static final String DELETED_ENTRY = "C0";
75         private Object [] mAllTheCitiesList;                      // full list of the cities
76         private final HashMap<String, CityObj> mSelectedCitiesList; // Selected cities by the use
77         private final LayoutInflater mInflater;
78         private boolean mIs24HoursMode;                            // AM/PM or 24 hours mode
79         private Object [] mSectionHeaders;
80         private Object [] mSectionPositions;
81 
CityAdapter( Context context, HashMap<String, CityObj> selectedList, LayoutInflater factory)82         public CityAdapter(
83                 Context context,  HashMap<String, CityObj> selectedList, LayoutInflater factory) {
84             super();
85             loadCitiesDataBase(context);
86             mSelectedCitiesList = selectedList;
87             mInflater = factory;
88             mCalendar = Calendar.getInstance();
89             mCalendar.setTimeInMillis(System.currentTimeMillis());
90             set24HoursMode(context);
91         }
92 
93         @Override
getCount()94         public int getCount() {
95             return (mAllTheCitiesList != null) ? mAllTheCitiesList.length : 0;
96         }
97 
98         @Override
getItem(int p)99         public Object getItem(int p) {
100             if (mAllTheCitiesList != null && p >=0 && p < mAllTheCitiesList.length) {
101                 return mAllTheCitiesList [p];
102             }
103             return null;
104         }
105 
106         @Override
getItemId(int p)107         public long getItemId(int p) {
108             return p;
109         }
110 
111         @Override
isEnabled(int p)112         public boolean isEnabled(int p) {
113             return mAllTheCitiesList != null && ((CityObj)mAllTheCitiesList[p]).mCityId != null;
114         }
115 
116         @Override
getView(int position, View view, ViewGroup parent)117         public View getView(int position, View view, ViewGroup parent) {
118             if (mAllTheCitiesList == null || position < 0 || position >= mAllTheCitiesList.length) {
119                 return null;
120             }
121             CityObj c = (CityObj)mAllTheCitiesList [position];
122             // Header view (A CityObj with nothing but the first letter as the name
123             if (c.mCityId == null) {
124                 if (view == null || view.findViewById(R.id.header) == null) {
125                     view =  mInflater.inflate(R.layout.city_list_header, parent, false);
126                 }
127                 TextView header = (TextView)view.findViewById(R.id.header);
128                 header.setText(c.mCityName);
129             } else { // City view
130                 // Make sure to recycle a City view only
131                 if (view == null || view.findViewById(R.id.city_name) == null) {
132                     view = mInflater.inflate(R.layout.city_list_item, parent, false);
133                 }
134                 view.setOnClickListener(CitiesActivity.this);
135                 TextView name = (TextView)view.findViewById(R.id.city_name);
136                 TextView tz = (TextView)view.findViewById(R.id.city_time);
137                 CheckBox cb = (CheckBox)view.findViewById(R.id.city_onoff);
138                 cb.setTag(c);
139                 cb.setChecked(mSelectedCitiesList.containsKey(c.mCityId));
140                 cb.setOnCheckedChangeListener(CitiesActivity.this);
141                 mCalendar.setTimeZone(TimeZone.getTimeZone(c.mTimeZone));
142                 tz.setText(DateFormat.format(mIs24HoursMode ? "k:mm" : "h:mmaa", mCalendar));
143                 name.setText(c.mCityName);
144             }
145             return view;
146         }
147 
set24HoursMode(Context c)148         public void set24HoursMode(Context c) {
149             mIs24HoursMode = Alarms.get24HourMode(c);
150             notifyDataSetChanged();
151         }
152 
loadCitiesDataBase(Context c)153         private void loadCitiesDataBase(Context c) {
154             CityObj[] tempList = Utils.loadCitiesDataBase(c);
155             if (tempList == null) {
156                 return;
157             }
158             //Create section indexer and add headers to the cities list
159             String val = null;
160             ArrayList<String> sections = new ArrayList<String> ();
161             ArrayList<Integer> positions = new ArrayList<Integer> ();
162             ArrayList<CityObj> items = new ArrayList<CityObj>();
163             int count = 0;
164             for (int i = 0; i < tempList.length; i++) {
165                 CityObj city = tempList[i];
166                 if (city.mCityId.equals(DELETED_ENTRY)) {
167                     continue;
168                 }
169                 if (!city.mCityName.substring(0, 1).equals(val)) {
170                     val = city.mCityName.substring(0, 1);
171                     sections.add((new String(val)).toUpperCase());
172                     positions.add(count);
173                     // Add a header
174                     items.add(new CityObj(val, null, null));
175                     count++;
176                 }
177                 items.add(city);
178                 count++;
179             }
180             mSectionHeaders = sections.toArray();
181             mSectionPositions = positions.toArray();
182             mAllTheCitiesList = items.toArray();
183          }
184 
185         @Override
getPositionForSection(int section)186         public int getPositionForSection(int section) {
187             return (mSectionPositions != null) ? (Integer) mSectionPositions[section] : 0;
188         }
189 
190         @Override
getSectionForPosition(int p)191         public int getSectionForPosition(int p) {
192             if (mSectionPositions != null) {
193                 for (int i = 0; i < mSectionPositions.length - 1; i++) {
194                     if (p >= (Integer) mSectionPositions[i]
195                             && p < (Integer) mSectionPositions[i + 1]) {
196                         return i;
197                     }
198                 }
199                 if (p >= (Integer)mSectionPositions[mSectionPositions.length - 1]) {
200                     return mSectionPositions.length - 1;
201                 }
202             }
203             return 0;
204         }
205 
206         @Override
getSections()207         public Object[] getSections() {
208             return mSectionHeaders;
209         }
210     }
211 
212 
213     @Override
onCreate(Bundle icicle)214     protected void onCreate(Bundle icicle) {
215         super.onCreate(icicle);
216         mFactory = LayoutInflater.from(this);
217         updateLayout();
218     }
219 
updateLayout()220     private void updateLayout() {
221         setContentView(R.layout.cities_activity);
222         mCitiesList = (ListView) findViewById(R.id.cities_list);
223         mCitiesList.setFastScrollAlwaysVisible(true);
224         mCitiesList.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
225         mCitiesList.setFastScrollEnabled(true);
226         mUserSelectedCities = Cities.readCitiesFromSharedPrefs(
227                 PreferenceManager.getDefaultSharedPreferences(this));
228         mAdapter = new CityAdapter(this, mUserSelectedCities, mFactory);
229         mCitiesList.setAdapter(mAdapter);
230         ActionBar actionBar = getActionBar();
231         if (actionBar != null) {
232             actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
233         }
234     }
235 
236     @Override
onResume()237     public void onResume() {
238         super.onResume();
239         if (mAdapter != null) {
240             mAdapter.set24HoursMode(this);
241         }
242     }
243 
244 
245     @Override
onPause()246     public void onPause() {
247         super.onPause();
248         Cities.saveCitiesToSharedPrefs(PreferenceManager.getDefaultSharedPreferences(this),
249                 mUserSelectedCities);
250         Intent i = new Intent(Cities.WORLDCLOCK_UPDATE_INTENT);
251         sendBroadcast(i);
252     }
253 
254     @Override
onOptionsItemSelected(MenuItem item)255     public boolean onOptionsItemSelected(MenuItem item) {
256         switch (item.getItemId()) {
257             case R.id.menu_item_settings:
258                 startActivity(new Intent(this, SettingsActivity.class));
259                 return true;
260             case R.id.menu_item_help:
261                 Intent i = item.getIntent();
262                 if (i != null) {
263                     try {
264                         startActivity(i);
265                     } catch (ActivityNotFoundException e) {
266                         // No activity found to match the intent - ignore
267                     }
268                 }
269                 return true;
270             case android.R.id.home:
271                 Intent intent = new Intent(this, DeskClock.class);
272                 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
273                 startActivity(intent);
274                 return true;
275             default:
276                 break;
277         }
278         return super.onOptionsItemSelected(item);
279     }
280 
281     @Override
onCreateOptionsMenu(Menu menu)282     public boolean onCreateOptionsMenu(Menu menu) {
283         getMenuInflater().inflate(R.menu.cities_menu, menu);
284         MenuItem help = menu.findItem(R.id.menu_item_help);
285         if (help != null) {
286             Utils.prepareHelpMenuItem(this, help);
287         }
288         return super.onCreateOptionsMenu(menu);
289     }
290 
291     @Override
onCheckedChanged(CompoundButton b, boolean checked)292     public void onCheckedChanged(CompoundButton b, boolean checked) {
293         CityObj c = (CityObj)b.getTag();
294         if (checked) {
295             mUserSelectedCities.put(c.mCityId, c);
296         } else {
297             mUserSelectedCities.remove(c.mCityId);
298         }
299     }
300 
301     @Override
onClick(View v)302     public void onClick(View v) {
303         CompoundButton b = (CompoundButton)v.findViewById(R.id.city_onoff);
304         boolean checked = b.isChecked();
305         onCheckedChanged(b, checked);
306         b.setChecked(!checked);
307     }
308 }
309