blob: ac94d481c2f7f06ca3a4c2a4103aefdf52a1f32d [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.deskclock.worldclock;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.android.deskclock.AnalogClock;
import com.android.deskclock.DigitalClock;
import com.android.deskclock.R;
import com.android.deskclock.SettingsActivity;
import com.android.deskclock.Utils;
import java.text.Collator;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;
public class WorldClockAdapter extends BaseAdapter {
protected Object [] mCitiesList;
private final LayoutInflater mInflater;
private final Context mContext;
private String mClockStyle;
private final Collator mCollator = Collator.getInstance();
protected HashMap<String, CityObj> mCitiesDb = new HashMap<String, CityObj>();
public WorldClockAdapter(Context context) {
super();
mContext = context;
loadData(context);
loadCitiesDb(context);
mInflater = LayoutInflater.from(context);
}
public void reloadData(Context context) {
loadData(context);
notifyDataSetChanged();
}
public void loadData(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
mClockStyle = prefs.getString(SettingsActivity.KEY_CLOCK_STYLE,
mContext.getResources().getString(R.string.default_clock_style));
mCitiesList = Cities.readCitiesFromSharedPrefs(prefs).values().toArray();
sortList();
mCitiesList = addHomeCity();
}
public void loadCitiesDb(Context context) {
mCitiesDb.clear();
// Read the cities DB so that the names and timezones will be taken from the DB
// and not from the selected list so that change of locale or changes in the DB will
// be reflected.
CityObj[] cities = Utils.loadCitiesDataBase(context);
if (cities != null) {
for (int i = 0; i < cities.length; i ++) {
mCitiesDb.put(cities[i].mCityId, cities [i]);
}
}
}
/***
* Adds the home city as the first item of the adapter if the feature is on and the device time
* zone is different from the home time zone that was set by the user.
* return the list of cities.
*/
private Object[] addHomeCity() {
if (needHomeCity()) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext);
String homeTZ = sharedPref.getString(SettingsActivity.KEY_HOME_TZ, "");
CityObj c = new CityObj(
mContext.getResources().getString(R.string.home_label), homeTZ, null);
Object[] temp = new Object[mCitiesList.length + 1];
temp[0] = c;
for (int i = 0; i < mCitiesList.length; i++) {
temp[i + 1] = mCitiesList[i];
}
return temp;
} else {
return mCitiesList;
}
}
public boolean needHomeCity() {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext);
if (sharedPref.getBoolean(SettingsActivity.KEY_AUTO_HOME_CLOCK, false)) {
String homeTZ = sharedPref.getString(
SettingsActivity.KEY_HOME_TZ, TimeZone.getDefault().getID());
final Date now = new Date();
return TimeZone.getTimeZone(homeTZ).getOffset(now.getTime())
!= TimeZone.getDefault().getOffset(now.getTime());
} else {
return false;
}
}
public boolean hasHomeCity() {
return (mCitiesList != null) && mCitiesList.length > 0
&& ((CityObj) mCitiesList[0]).mCityId == null;
}
private void sortList() {
final Date now = new Date();
// Sort by the Offset from GMT taking DST into account
// and if the same sort by City Name
Arrays.sort(mCitiesList, new Comparator<Object>() {
private int safeCityNameCompare(CityObj city1, CityObj city2) {
if (city1.mCityName == null && city2.mCityName == null) {
return 0;
} else if (city1.mCityName == null) {
return -1;
} else if (city2.mCityName == null) {
return 1;
} else {
return mCollator.compare(city1.mCityName, city2.mCityName);
}
}
@Override
public int compare(Object object1, Object object2) {
CityObj city1 = (CityObj) object1;
CityObj city2 = (CityObj) object2;
if (city1.mTimeZone == null && city2.mTimeZone == null) {
return safeCityNameCompare(city1, city2);
} else if (city1.mTimeZone == null) {
return -1;
} else if (city2.mTimeZone == null) {
return 1;
}
int gmOffset1 = TimeZone.getTimeZone(city1.mTimeZone).getOffset(now.getTime());
int gmOffset2 = TimeZone.getTimeZone(city2.mTimeZone).getOffset(now.getTime());
if (gmOffset1 == gmOffset2) {
return safeCityNameCompare(city1, city2);
} else {
return gmOffset1 - gmOffset2;
}
}
});
}
@Override
public int getCount() {
// Each item in the list holds 1 or 2 clocks
return (mCitiesList.length + 1)/2;
}
@Override
public Object getItem(int p) {
return null;
}
@Override
public long getItemId(int p) {
return p;
}
@Override
public boolean isEnabled(int p) {
return false;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
// Index in cities list
int index = position * 2;
if (index < 0 || index >= mCitiesList.length) {
return null;
}
if (view == null) {
view = mInflater.inflate(R.layout.world_clock_list_item, parent, false);
}
// The world clock list item can hold two world clocks
View rightClock = view.findViewById(R.id.city_right);
updateView(view.findViewById(R.id.city_left), (CityObj)mCitiesList[index]);
if (index + 1 < mCitiesList.length) {
rightClock.setVisibility(View.VISIBLE);
updateView(rightClock, (CityObj)mCitiesList[index + 1]);
} else {
// To make sure the spacing is right , make sure that the right clock style is selected
// even if the clock is invisible.
DigitalClock dclock = (DigitalClock)(rightClock.findViewById(R.id.digital_clock));
AnalogClock aclock = (AnalogClock)(rightClock.findViewById(R.id.analog_clock));
if (mClockStyle.equals("analog")) {
dclock.setVisibility(View.GONE);
aclock.setVisibility(View.INVISIBLE);
} else {
dclock.setVisibility(View.INVISIBLE);
aclock.setVisibility(View.GONE);
}
rightClock.setVisibility(View.INVISIBLE);
}
return view;
}
private void updateView(View clock, CityObj cityObj) {
View nameLayout= clock.findViewById(R.id.city_name_layout);
TextView name = (TextView)(nameLayout.findViewById(R.id.city_name));
TextView dayOfWeek = (TextView)(nameLayout.findViewById(R.id.city_day));
DigitalClock dclock = (DigitalClock)(clock.findViewById(R.id.digital_clock));
AnalogClock aclock = (AnalogClock)(clock.findViewById(R.id.analog_clock));
if (mClockStyle.equals("analog")) {
dclock.setVisibility(View.GONE);
aclock.setVisibility(View.VISIBLE);
aclock.setTimeZone(cityObj.mTimeZone);
aclock.enableSeconds(false);
} else {
dclock.setVisibility(View.VISIBLE);
aclock.setVisibility(View.GONE);
dclock.setTimeZone(cityObj.mTimeZone);
}
CityObj cityInDb = mCitiesDb.get(cityObj.mCityId);
// Home city or city not in DB , use data from the save selected cities list
name.setText(Utils.getCityName(cityObj, cityInDb));
final Calendar now = Calendar.getInstance();
now.setTimeZone(TimeZone.getDefault());
int myDayOfWeek = now.get(Calendar.DAY_OF_WEEK);
// Get timezone from cities DB if available
String cityTZ = (cityInDb != null) ? cityInDb.mTimeZone : cityObj.mTimeZone;
now.setTimeZone(TimeZone.getTimeZone(cityTZ));
int cityDayOfWeek = now.get(Calendar.DAY_OF_WEEK);
if (myDayOfWeek != cityDayOfWeek) {
dayOfWeek.setText(mContext.getString(R.string.world_day_of_week_label,
now.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault())));
dayOfWeek.setVisibility(View.VISIBLE);
} else {
dayOfWeek.setVisibility(View.GONE);
}
}
}