/* * Copyright (C) 2005-2009 Team XBMC * http://xbmc.org * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XBMC Remote; see the file license. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ package org.xbmc.android.remote.presentation.controller; import java.util.ArrayList; import java.util.Hashtable; import org.xbmc.android.remote.R; import org.xbmc.android.remote.presentation.activity.HostSettingsActivity; import org.xbmc.android.remote.presentation.activity.SettingsActivity; import org.xbmc.android.util.HostFactory; import org.xbmc.api.object.Host; import org.xbmc.api.presentation.INotifiableController; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.net.Uri; import android.os.Handler; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceScreen; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; public class SettingsController extends AbstractController implements INotifiableController, IController, OnSharedPreferenceChangeListener { private static final String TAG = "SettingsController"; public static final int MENU_ADD_HOST = 1; public static final int MENU_ADD_HOST_WIZARD = 3; public static final int MENU_ADD_FROM_BARCODE = 4; public static final int MENU_GENERATE_BARCODE = 5; public static final int REQUEST_SCAN_BARCODE = 1; private PreferenceActivity mPreferenceActivity; private final Hashtable<String, String> mSummaries = new Hashtable<String, String>(); public SettingsController(PreferenceActivity activity, Handler handler) { mPreferenceActivity = activity; super.onCreate(activity, handler); } /** * Used in SettingsActivity in order to update the %value% placeholder in * the summaries. * @param activity Reference to activity */ public void registerOnSharedPreferenceChangeListener(PreferenceActivity activity) { activity.getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); PreferenceScreen ps = activity.getPreferenceScreen(); // save original summaries to variable for later update mSummaries.clear(); for (String key : ps.getSharedPreferences().getAll().keySet()) { Preference pref = ps.findPreference(key); if (pref != null && pref.getSummary() != null) { mSummaries.put(key, pref.getSummary().toString()); } } updateSummaries(); } /** * Creates the preference screen that contains all the listed hosts. * @param root Root node * @param activity Reference to activity * @return */ public PreferenceScreen createHostsPreferences(PreferenceScreen root, Activity activity) { final ArrayList<Host> hosts = HostFactory.getHosts(activity.getApplicationContext()); if (hosts.size() > 0) { for (Host host : hosts) { HostPreference pref = new HostPreference(activity); pref.setTitle(host.name); pref.setSummary(host.getSummary()); pref.setHost(host); pref.setKey(HostPreference.ID_PREFIX + host.id); root.addPreference(pref); } } else { AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setMessage("No hosts defined. In order to add hosts, press \"Menu\" and choose \"Add host\"."); builder.setPositiveButton("Close", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.create().show(); } return root; } /** * Updates summaries of all known keys with the updated value. */ public void updateSummaries() { PreferenceScreen ps = mPreferenceActivity.getPreferenceScreen(); for (String key : ps.getSharedPreferences().getAll().keySet()) { Preference pref = ps.findPreference(key); if (pref != null && pref.getSummary() != null) { String summary = pref.getSummary().toString(); if (summary.contains(SettingsActivity.SUMMARY_VALUE_PLACEHOLDER)) { pref.setSummary(summary.replaceAll(SettingsActivity.SUMMARY_VALUE_PLACEHOLDER, ps.getSharedPreferences().getString(key, "<not set>"))); } } } } /** * Used in order to replace the %value% placeholders with real values. */ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Log.i("SettingsActivity", "onSharedPreferenceChanged(" + key + ")"); Preference pref = mPreferenceActivity.getPreferenceScreen().findPreference(key); String origSummary = mSummaries.get(key); if (origSummary != null && origSummary.contains(SettingsActivity.SUMMARY_VALUE_PLACEHOLDER)) { pref.setSummary(origSummary.replaceAll(SettingsActivity.SUMMARY_VALUE_PLACEHOLDER, sharedPreferences.getString(key, ""))); } } public void onCreateOptionsMenu(Menu menu) { menu.addSubMenu(0, MENU_ADD_HOST, 0, "Add Host").setIcon(R.drawable.menu_add_host); menu.addSubMenu(0, MENU_ADD_HOST_WIZARD, 0, "Host Wizard").setIcon(R.drawable.menu_add_host); menu.addSubMenu(0, MENU_ADD_FROM_BARCODE, 0, mPreferenceActivity.getString(R.string.add_from_barcode)).setIcon(R.drawable.menu_qr_code); menu.addSubMenu(0, MENU_GENERATE_BARCODE, 0, mPreferenceActivity.getString(R.string.generate_barcode)).setIcon(R.drawable.menu_qr_code); } public void onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case MENU_ADD_HOST: HostPreference pref = new HostPreference(mActivity); pref.setTitle("New XBMC Host"); pref.create(mPreferenceActivity.getPreferenceManager()); mPreferenceActivity.getPreferenceScreen().addPreference(pref); break; case MENU_ADD_FROM_BARCODE: final Intent scanIntent = new Intent("com.google.zxing.client.android.SCAN"); scanIntent.putExtra("SCAN_MODE", "QR_CODE_MODE"); if (mPreferenceActivity.getPackageManager().queryIntentActivities(scanIntent, 0).size() == 0) { showBarcodeUnsupportedDialog(); break; } mPreferenceActivity.startActivityForResult(scanIntent, REQUEST_SCAN_BARCODE); break; case MENU_GENERATE_BARCODE: final Intent intent = new Intent("com.google.zxing.client.android.ENCODE"); intent.putExtra("ENCODE_TYPE", "TEXT_TYPE"); if (mPreferenceActivity.getPackageManager().queryIntentActivities(intent, 0).size() == 0) { showBarcodeUnsupportedDialog(); break; } final ArrayList<Host> hosts = HostFactory.getHosts(mPreferenceActivity); if (hosts.size() == 0) { AlertDialog.Builder builder = new AlertDialog.Builder(mPreferenceActivity); builder.setMessage(mPreferenceActivity.getString(R.string.hosts_required)); builder.setPositiveButton(mPreferenceActivity.getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); break; } else if (hosts.size() == 1) { Host host = hosts.get(0); intent.putExtra("ENCODE_DATA", host.toJson()); mPreferenceActivity.startActivity(intent); } else { AlertDialog.Builder builder = new AlertDialog.Builder(mPreferenceActivity); builder.setTitle(mPreferenceActivity.getString(R.string.pick_host)); String[] names = new String[hosts.size()]; for (int i = 0, size = hosts.size(); i < size; i++) { names[i] = hosts.get(i).name; } builder.setItems(names, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Host host = hosts.get(which); intent.putExtra("ENCODE_DATA", host.toJson()); mPreferenceActivity.startActivity(intent); } }); builder.setCancelable(true); builder.setOnCancelListener(new DialogInterface.OnCancelListener() { public void onCancel(DialogInterface dialog) { dialog.dismiss(); } }); builder.create().show(); } break; } } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_SCAN_BARCODE) { if (resultCode == Activity.RESULT_OK) { String result = data.getStringExtra("SCAN_RESULT"); Host host = HostFactory.getHostFromJson(result); if (host == null) { AlertDialog.Builder builder = new AlertDialog.Builder(mPreferenceActivity); builder.setMessage(mPreferenceActivity.getString(R.string.host_scan_error)); builder.setPositiveButton(mPreferenceActivity.getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); } else { HostFactory.addHost(mPreferenceActivity, host); Toast.makeText(mPreferenceActivity, mPreferenceActivity.getString(R.string.added_host, host.name), Toast.LENGTH_SHORT).show(); // Is there a better way to refresh the preferences screen? mPreferenceActivity.startActivity(new Intent(mPreferenceActivity.getBaseContext(), HostSettingsActivity.class)); mPreferenceActivity.finish(); } } } } private void showBarcodeUnsupportedDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(mPreferenceActivity); builder.setMessage(mPreferenceActivity.getString(R.string.barcode_scanner_required)); builder.setPositiveButton(mPreferenceActivity.getString(R.string.yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("market://search?q=pname:com.google.zxing.client.android")); mPreferenceActivity.startActivity(intent); } }); builder.setNegativeButton(mPreferenceActivity.getString(R.string.no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.create().show(); } public void onActivityPause() { super.onActivityPause(); } public void onActivityResume(Activity activity) { super.onActivityResume(activity); final ArrayList<Host> hosts = HostFactory.getHosts(activity.getApplicationContext()); if (hosts.size() == 1) { final Host host = hosts.get(0); Log.i(TAG, "Setting host to " + (host == null ? "<null>" : host.addr) + "."); HostFactory.saveHost(activity.getApplicationContext(), host); } if (hosts.size() == 0) { Log.i(TAG, "Resetting host to <null>."); HostFactory.saveHost(activity.getApplicationContext(), null); } } }