/**
* Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
* This file is part of CSipSimple.
*
* CSipSimple 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 3 of the License, or
* (at your option) any later version.
* If you own a pjsip commercial license you can also redistribute it
* and/or modify it under the terms of the GNU Lesser General Public License
* as an android library.
*
* CSipSimple 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 CSipSimple. If not, see <http://www.gnu.org/licenses/>.
*/
package com.csipsimple.wizards;
import android.content.ContentUris;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.csipsimple.R;
import com.csipsimple.api.SipManager;
import com.csipsimple.api.SipProfile;
import com.csipsimple.db.DBProvider;
import com.csipsimple.models.Filter;
import com.csipsimple.ui.filters.AccountFilters;
import com.csipsimple.ui.prefs.GenericPrefs;
import com.csipsimple.utils.Log;
import com.csipsimple.utils.PreferencesWrapper;
import com.csipsimple.wizards.WizardUtils.WizardInfo;
import java.util.List;
import java.util.UUID;
public class BasePrefsWizard extends GenericPrefs {
public static final int SAVE_MENU = Menu.FIRST + 1;
public static final int TRANSFORM_MENU = Menu.FIRST + 2;
public static final int FILTERS_MENU = Menu.FIRST + 3;
public static final int DELETE_MENU = Menu.FIRST + 4;
private static final String THIS_FILE = "Base Prefs wizard";
protected SipProfile account = null;
private Button saveButton;
private String wizardId = "";
private WizardIface wizard = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
// Get back the concerned account and if any set the current (if not a
// new account is created)
Intent intent = getIntent();
long accountId = intent.getLongExtra(SipProfile.FIELD_ID, SipProfile.INVALID_ID);
// TODO : ensure this is not null...
setWizardId(intent.getStringExtra(SipProfile.FIELD_WIZARD));
account = SipProfile.getProfileFromDbId(this, accountId, DBProvider.ACCOUNT_FULL_PROJECTION);
super.onCreate(savedInstanceState);
// Bind buttons to their actions
Button bt = (Button) findViewById(R.id.cancel_bt);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setResult(RESULT_CANCELED, getIntent());
finish();
}
});
saveButton = (Button) findViewById(R.id.save_bt);
saveButton.setEnabled(false);
saveButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
saveAndFinish();
}
});
wizard.fillLayout(account);
}
private boolean isResumed = false;
@Override
protected void onResume() {
super.onResume();
isResumed = true;
updateDescriptions();
updateValidation();
wizard.onStart();
}
@Override
protected void onPause() {
super.onPause();
isResumed = false;
wizard.onStop();
}
private boolean setWizardId(String wId) {
if (wizardId == null) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
WizardInfo wizardInfo = WizardUtils.getWizardClass(wId);
if (wizardInfo == null) {
if (!wizardId.equals(WizardUtils.EXPERT_WIZARD_TAG)) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
return false;
}
try {
wizard = (WizardIface) wizardInfo.classObject.newInstance();
} catch (IllegalAccessException e) {
Log.e(THIS_FILE, "Can't access wizard class", e);
if (!wizardId.equals(WizardUtils.EXPERT_WIZARD_TAG)) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
return false;
} catch (InstantiationException e) {
Log.e(THIS_FILE, "Can't access wizard class", e);
if (!wizardId.equals(WizardUtils.EXPERT_WIZARD_TAG)) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
return false;
}
wizardId = wId;
wizard.setParent(this);
if(getSupportActionBar() != null) {
getSupportActionBar().setIcon(WizardUtils.getWizardIconRes(wizardId));
}
return true;
}
@Override
protected void beforeBuildPrefs() {
// Use our custom wizard view
setContentView(R.layout.wizard_prefs_base);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(isResumed) {
updateDescriptions();
updateValidation();
}
}
/**
* Update validation state of the current activity.
* It will check if wizard can be saved and if so
* will enable button
*/
public void updateValidation() {
saveButton.setEnabled(wizard.canSave());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, SAVE_MENU, Menu.NONE, R.string.save).setIcon(android.R.drawable.ic_menu_save);
if (account.id != SipProfile.INVALID_ID) {
menu.add(Menu.NONE, TRANSFORM_MENU, Menu.NONE, R.string.choose_wizard).setIcon(android.R.drawable.ic_menu_edit);
menu.add(Menu.NONE, FILTERS_MENU, Menu.NONE, R.string.filters).setIcon(R.drawable.ic_menu_filter);
menu.add(Menu.NONE, DELETE_MENU, Menu.NONE, R.string.delete_account).setIcon(android.R.drawable.ic_menu_delete);
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(SAVE_MENU).setVisible(wizard.canSave());
return super.onPrepareOptionsMenu(menu);
}
private static final int CHOOSE_WIZARD = 0;
private static final int MODIFY_FILTERS = CHOOSE_WIZARD + 1;
private static final int FINAL_ACTIVITY_CODE = MODIFY_FILTERS;
private int currentActivityCode = FINAL_ACTIVITY_CODE;
public int getFreeSubActivityCode() {
currentActivityCode ++;
return currentActivityCode;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case SAVE_MENU:
saveAndFinish();
return true;
case TRANSFORM_MENU:
startActivityForResult(new Intent(this, WizardChooser.class), CHOOSE_WIZARD);
return true;
case DELETE_MENU:
if (account.id != SipProfile.INVALID_ID) {
getContentResolver().delete(ContentUris.withAppendedId(SipProfile.ACCOUNT_ID_URI_BASE, account.id), null, null);
setResult(RESULT_OK, getIntent());
finish();
}
return true;
case FILTERS_MENU:
if (account.id != SipProfile.INVALID_ID) {
Intent it = new Intent(this, AccountFilters.class);
it.putExtra(SipProfile.FIELD_ID, account.id);
it.putExtra(SipProfile.FIELD_DISPLAY_NAME, account.display_name);
it.putExtra(SipProfile.FIELD_WIZARD, account.wizard);
startActivityForResult(it, MODIFY_FILTERS);
return true;
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CHOOSE_WIZARD && resultCode == RESULT_OK && data != null && data.getExtras() != null) {
String wizardId = data.getStringExtra(WizardUtils.ID);
if (wizardId != null) {
saveAccount(wizardId);
setResult(RESULT_OK, getIntent());
finish();
}
}
if(requestCode > FINAL_ACTIVITY_CODE) {
wizard.onActivityResult(requestCode, resultCode, data);
}
}
/**
* Save account and end the activity
*/
public void saveAndFinish() {
saveAccount();
Intent intent = getIntent();
setResult(RESULT_OK, intent);
finish();
}
/*
* Save the account with current wizard id
*/
private void saveAccount() {
saveAccount(wizardId);
}
@Override
protected void onDestroy() {
super.onDestroy();
getSharedPreferences(WIZARD_PREF_NAME, MODE_PRIVATE).edit().clear().commit();
}
/**
* Save the account with given wizard id
* @param wizardId the wizard to use for account entry
*/
private void saveAccount(String wizardId) {
boolean needRestart = false;
PreferencesWrapper prefs = new PreferencesWrapper(getApplicationContext());
account = wizard.buildAccount(account);
account.wizard = wizardId;
if (account.id == SipProfile.INVALID_ID) {
// This account does not exists yet
prefs.startEditing();
wizard.setDefaultParams(prefs);
prefs.endEditing();
applyNewAccountDefault(account);
Uri uri = getContentResolver().insert(SipProfile.ACCOUNT_URI, account.getDbContentValues());
// After insert, add filters for this wizard
account.id = ContentUris.parseId(uri);
List<Filter> filters = wizard.getDefaultFilters(account);
if (filters != null) {
for (Filter filter : filters) {
// Ensure the correct id if not done by the wizard
filter.account = (int) account.id;
getContentResolver().insert(SipManager.FILTER_URI, filter.getDbContentValues());
}
}
// Check if we have to restart
needRestart = wizard.needRestart();
} else {
// TODO : should not be done there but if not we should add an
// option to re-apply default params
prefs.startEditing();
wizard.setDefaultParams(prefs);
prefs.endEditing();
getContentResolver().update(ContentUris.withAppendedId(SipProfile.ACCOUNT_ID_URI_BASE, account.id), account.getDbContentValues(), null, null);
}
// Mainly if global preferences were changed, we have to restart sip stack
if (needRestart) {
Intent intent = new Intent(SipManager.ACTION_SIP_REQUEST_RESTART);
sendBroadcast(intent);
}
}
/**
* Apply default settings for a new account to check very basic coherence of settings and auto-modify settings missing
* @param account
*/
private void applyNewAccountDefault(SipProfile account) {
if(account.use_rfc5626) {
if(TextUtils.isEmpty(account.rfc5626_instance_id)) {
String autoInstanceId = (UUID.randomUUID()).toString();
account.rfc5626_instance_id = "<urn:uuid:"+autoInstanceId+">";
}
}
}
@Override
protected int getXmlPreferences() {
return wizard.getBasePreferenceResource();
}
@Override
protected void updateDescriptions() {
wizard.updateDescriptions();
}
@Override
protected String getDefaultFieldSummary(String fieldName) {
return wizard.getDefaultFieldSummary(fieldName);
}
private static final String WIZARD_PREF_NAME = "Wizard";
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return super.getSharedPreferences(WIZARD_PREF_NAME, mode);
}
}