diff options
Diffstat (limited to 'src/com/cyanogenmod/lockclock/preference')
4 files changed, 360 insertions, 21 deletions
diff --git a/src/com/cyanogenmod/lockclock/preference/CustomLocationPreference.java b/src/com/cyanogenmod/lockclock/preference/CustomLocationPreference.java index d88809a..6d0992f 100644 --- a/src/com/cyanogenmod/lockclock/preference/CustomLocationPreference.java +++ b/src/com/cyanogenmod/lockclock/preference/CustomLocationPreference.java @@ -33,7 +33,6 @@ import android.widget.Toast; import com.cyanogenmod.lockclock.R; import com.cyanogenmod.lockclock.misc.Preferences; import com.cyanogenmod.lockclock.weather.WeatherProvider.LocationResult; -import com.cyanogenmod.lockclock.weather.YahooWeatherProvider; import java.util.HashSet; import java.util.List; @@ -112,7 +111,7 @@ public class CustomLocationPreference extends EditTextPreference { @Override protected List<LocationResult> doInBackground(Void... input) { - return new YahooWeatherProvider(getContext()).getLocations(mLocation); + return Preferences.weatherProvider(getContext()).getLocations(mLocation); } @Override diff --git a/src/com/cyanogenmod/lockclock/preference/IconSelectionPreference.java b/src/com/cyanogenmod/lockclock/preference/IconSelectionPreference.java new file mode 100644 index 0000000..87309a2 --- /dev/null +++ b/src/com/cyanogenmod/lockclock/preference/IconSelectionPreference.java @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project (DvTonder) + * + * 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.cyanogenmod.lockclock.preference; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Locale; + +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.preference.DialogPreference; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.TextView; + +import com.cyanogenmod.lockclock.R; + +public class IconSelectionPreference extends DialogPreference implements + AdapterView.OnItemClickListener { + private static final String INTENT_CATEGORY_ICONPACK = "com.dvtonder.chronus.ICON_PACK"; + + private static final String SEARCH_URI = "https://market.android.com/search?q=%s&c=apps"; + private static final String APP_URI = "market://details?id=%s"; + + private static class IconSetDescriptor { + String name; + CharSequence description; + int descriptionResId; + Drawable previewDrawable; + int previewResId; + public IconSetDescriptor(String name, int descriptionResId, + int previewResId) { + this.name = name; + this.descriptionResId = descriptionResId; + this.previewResId = previewResId; + } + public IconSetDescriptor(String packageName, CharSequence description, + Drawable preview) { + this.name = "ext:" + packageName; + this.description = description; + this.previewDrawable = preview; + } + public CharSequence getDescription(Context context) { + if (description != null) { + return description; + } + return context.getString(descriptionResId); + } + @Override + public boolean equals(Object other) { + if (other instanceof IconSetDescriptor) { + IconSetDescriptor o = (IconSetDescriptor) other; + return name.equals(o.name); + } + return false; + } + } + + private static final IconSetDescriptor ICON_SETS[] = new IconSetDescriptor[] { + new IconSetDescriptor("color", R.string.weather_icons_standard, + R.drawable.weather_color_28), + new IconSetDescriptor("mono", R.string.weather_icons_monochrome, + R.drawable.weather_28), + new IconSetDescriptor("vclouds", R.string.weather_icons_vclouds, + R.drawable.weather_vclouds_28) + }; + + private static final IntentFilter PACKAGE_CHANGE_FILTER = new IntentFilter(); + static { + PACKAGE_CHANGE_FILTER.addAction(Intent.ACTION_PACKAGE_ADDED); + PACKAGE_CHANGE_FILTER.addAction(Intent.ACTION_PACKAGE_REMOVED); + PACKAGE_CHANGE_FILTER.addDataScheme("package"); + } + + private IconSetAdapter mAdapter; + private GridView mGrid; + private String mValue; + private String mSelectedValue; + private String mPreviousSelection; + + private BroadcastReceiver mPackageChangeReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + mAdapter.reenumerateIconSets(); + if (getValueIndex(mSelectedValue) == GridView.INVALID_POSITION) { + selectValue(mAdapter.getItem(0).name); + } else { + // index might have changed + selectValue(mSelectedValue); + } + } + }; + + public IconSelectionPreference(Context context, AttributeSet attrs) { + super(context, attrs); + mAdapter = new IconSetAdapter(getContext()); + } + + public CharSequence getEntry() { + int index = getValueIndex(mValue); + if (index != GridView.INVALID_POSITION) { + return mAdapter.getItem(index).getDescription(getContext()); + } + return null; + } + + @Override + protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { + super.onPrepareDialogBuilder(builder); + builder.setNeutralButton(R.string.icon_set_selection_get_more, null); + } + + @Override + protected void showDialog(Bundle state) { + getContext().registerReceiver(mPackageChangeReceiver, PACKAGE_CHANGE_FILTER); + super.showDialog(state); + + AlertDialog d = (AlertDialog) getDialog(); + d.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String uri = String.format(Locale.US, SEARCH_URI, + getContext().getString(R.string.icon_set_store_filter)); + viewUri(getContext(), uri); + } + }); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + super.onDialogClosed(positiveResult); + + int selected = mGrid.getCheckedItemPosition(); + if (positiveResult && selected != GridView.INVALID_POSITION) { + IconSetDescriptor descriptor = mAdapter.getItem(selected); + if (callChangeListener(descriptor.name)) { + mValue = descriptor.name; + persistString(descriptor.name); + } + } + + getContext().unregisterReceiver(mPackageChangeReceiver); + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getString(index); + } + + @Override + protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) { + String defValue = (String) defaultValue; + mValue = restorePersistedValue ? getPersistedString(defValue) : defValue; + } + + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + IconSetDescriptor descriptor = mAdapter.getItem(mGrid.getCheckedItemPosition()); + mSelectedValue = descriptor.name; + mPreviousSelection = mSelectedValue; + } + + @Override + protected View onCreateDialogView() { + LayoutInflater inflater = LayoutInflater.from(getContext()); + View view = inflater.inflate(R.layout.icon_style_selection, null); + + mGrid = (GridView) view.findViewById(R.id.icon_list); + mGrid.setAdapter(mAdapter); + mGrid.setOnItemClickListener(this); + + selectValue(mValue); + + return view; + } + + private void selectValue(String value) { + int index = getValueIndex(value); + if (index == GridView.INVALID_POSITION) { + index = 0; + } + mGrid.setItemChecked(index, true); + mSelectedValue = mAdapter.getItem(index).name; + mPreviousSelection = mSelectedValue; + } + + private int getValueIndex(String value) { + int count = mAdapter.getCount(); + for (int i = 0; i < count; i++) { + if (mAdapter.getItem(i).name.equals(value)) { + return i; + } + } + return GridView.INVALID_POSITION; + } + + private static void viewUri(Context context, String uri) { + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(uri)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + context.startActivity(intent); + } + + private static class IconSetAdapter extends ArrayAdapter<IconSetDescriptor> { + private LayoutInflater mInflater; + + public IconSetAdapter(Context context) { + super(context, R.layout.icon_item, 0, populateIconSets(context)); + mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + } + + public void reenumerateIconSets() { + ArrayList<IconSetDescriptor> newSets = populateIconSets(getContext()); + boolean changed = false; + + if (newSets.size() != getCount()) { + changed = true; + } else { + for (int i = 0; i < getCount(); i++) { + if (!newSets.get(i).equals(getItem(i))) { + changed = true; + break; + } + } + } + + if (changed) { + setNotifyOnChange(false); + clear(); + addAll(newSets); + notifyDataSetChanged(); + } + } + + private static ArrayList<IconSetDescriptor> populateIconSets(Context context) { + ArrayList<IconSetDescriptor> result = new ArrayList<IconSetDescriptor>(); + for (IconSetDescriptor desc : ICON_SETS) { + result.add(desc); + } + + PackageManager pm = context.getPackageManager(); + Intent i = new Intent(Intent.ACTION_MAIN); + i.addCategory(INTENT_CATEGORY_ICONPACK); + + HashSet<String> installedIconPacks = new HashSet<String>(); + + for (ResolveInfo info : pm.queryIntentActivities(i, 0)) { + ApplicationInfo appInfo = info.activityInfo.applicationInfo; + try { + Resources res = pm.getResourcesForApplication(appInfo); + int previewResId = res.getIdentifier("weather_28", "drawable", appInfo.packageName); + Drawable preview = previewResId != 0 ? res.getDrawable(previewResId) : null; + result.add(new IconSetDescriptor(appInfo.packageName, + appInfo.loadLabel(pm), preview)); + installedIconPacks.add(appInfo.packageName.toLowerCase(Locale.US)); + } catch (PackageManager.NameNotFoundException e) { + // shouldn't happen, ignore package + } + } + return result; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = mInflater.inflate(R.layout.icon_item, parent, false); + } + + IconSetDescriptor descriptor = getItem(position); + ImageView preview = (ImageView) convertView.findViewById(R.id.preview); + TextView name = (TextView) convertView.findViewById(R.id.name); + + if (descriptor.previewDrawable != null) { + preview.setImageDrawable(descriptor.previewDrawable); + } else { + preview.setImageResource(descriptor.previewResId); + } + name.setText(descriptor.getDescription(getContext())); + return convertView; + } + } +} diff --git a/src/com/cyanogenmod/lockclock/preference/Preferences.java b/src/com/cyanogenmod/lockclock/preference/Preferences.java index bb9faa2..f60ab4d 100755 --- a/src/com/cyanogenmod/lockclock/preference/Preferences.java +++ b/src/com/cyanogenmod/lockclock/preference/Preferences.java @@ -16,6 +16,7 @@ package com.cyanogenmod.lockclock.preference; +import android.annotation.SuppressLint; import android.appwidget.AppWidgetManager; import android.content.Intent; import android.preference.PreferenceActivity; @@ -77,4 +78,14 @@ public class Preferences extends PreferenceActivity { setResult(result, new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mNewWidgetId)); } } + + /** + * This is required to be able to build with API level 19 + */ + @SuppressLint("Override") + @Override + public boolean isValidFragment(String fragmentName) { + // Assume a valid fragment name at all times + return true; + } } diff --git a/src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java b/src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java index 327b3e1..9b06246 100644 --- a/src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java +++ b/src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java @@ -58,6 +58,8 @@ public class WeatherPreferences extends PreferenceFragment implements private ListPreference mFontColor; private ListPreference mTimestampFontColor; private CheckBoxPreference mUseMetric; + private IconSelectionPreference mIconSet; + private CheckBoxPreference mUseCustomlocation; private Context mContext; private ContentResolver mResolver; @@ -73,16 +75,15 @@ public class WeatherPreferences extends PreferenceFragment implements // Load items that need custom summaries etc. mUseCustomLoc = (CheckBoxPreference) findPreference(Constants.WEATHER_USE_CUSTOM_LOCATION); mCustomWeatherLoc = (EditTextPreference) findPreference(Constants.WEATHER_CUSTOM_LOCATION_CITY); - mFontColor = (ListPreference) findPreference(Constants.WEATHER_FONT_COLOR); mTimestampFontColor = (ListPreference) findPreference(Constants.WEATHER_TIMESTAMP_FONT_COLOR); - + mIconSet = (IconSelectionPreference) findPreference(Constants.WEATHER_ICONS); mUseMetric = (CheckBoxPreference) findPreference(Constants.WEATHER_USE_METRIC); + mUseCustomlocation = (CheckBoxPreference) findPreference(Constants.WEATHER_USE_CUSTOM_LOCATION); // Show a warning if location manager is disabled and there is no custom location set - if (!Settings.Secure.isLocationProviderEnabled(mResolver, - LocationManager.NETWORK_PROVIDER) - && !mUseCustomLoc.isChecked()) { + LocationManager lm = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE); + if (!lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) && !mUseCustomLoc.isChecked()) { showDialog(); } } @@ -93,6 +94,7 @@ public class WeatherPreferences extends PreferenceFragment implements getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); updateLocationSummary(); updateFontColorsSummary(); + updateIconSetSummary(); } @Override @@ -109,12 +111,16 @@ public class WeatherPreferences extends PreferenceFragment implements pref.setSummary(listPref.getEntry()); } + boolean needWeatherUpdate = false; + boolean forceWeatherUpdate = false; + if (pref == mUseCustomLoc || pref == mCustomWeatherLoc) { updateLocationSummary(); } - boolean needWeatherUpdate = false; - boolean forceWeatherUpdate = false; + if (pref == mIconSet) { + updateIconSetSummary(); + } if (pref == mUseMetric) { // The display format of the temperatures have changed @@ -122,20 +128,23 @@ public class WeatherPreferences extends PreferenceFragment implements forceWeatherUpdate = true; } - for (String k : LOCATION_PREF_KEYS) { - if (TextUtils.equals(key, k)) { - // location pref has changed -> clear out location id cache - Preferences.setCachedLocationId(mContext, null); - forceWeatherUpdate = true; - break; - } + // If the weather source has changes, invalidate the custom location settings and change + // back to GeoLocation to force the user to specify a new custom location if needed + if (TextUtils.equals(key, Constants.WEATHER_SOURCE)) { + Preferences.setCustomWeatherLocationId(mContext, null); + Preferences.setCustomWeatherLocationCity(mContext, null); + Preferences.setUseCustomWeatherLocation(mContext, false); + mUseCustomlocation.setChecked(false); + updateLocationSummary(); } - for (String k : WEATHER_REFRESH_KEYS) { - if (TextUtils.equals(key, k)) { - needWeatherUpdate = true; - break; - } + if (key.equals(Constants.WEATHER_USE_CUSTOM_LOCATION) + || key.equals(Constants.WEATHER_CUSTOM_LOCATION_CITY)) { + forceWeatherUpdate = true; + } + + if (key.equals(Constants.SHOW_WEATHER) || key.equals(Constants.WEATHER_REFRESH_INTERVAL)) { + needWeatherUpdate = true; } if (Constants.DEBUG) { @@ -200,4 +209,10 @@ public class WeatherPreferences extends PreferenceFragment implements mTimestampFontColor.setSummary(mTimestampFontColor.getEntry()); } } + + private void updateIconSetSummary() { + if (mIconSet != null) { + mIconSet.setSummary(mIconSet.getEntry()); + } + } } |