package de.unikassel.android.sdcframework.app.scheduler; /* * Copyright (C) 2012, Katy Hilgenberg. * Special acknowledgments to: Knowledge & Data Engineering Group, University of Kassel (http://www.kde.cs.uni-kassel.de). * Contact: sdcf@cs.uni-kassel.de * * This file is part of the SDCFramework project. * * The SDCFramework is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The SDCFramework 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the SDCFramework. If not, see <http://www.gnu.org/licenses/>. */ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewParent; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import de.unikassel.android.sdcframework.R; import de.unikassel.android.sdcframework.app.facade.DialogUtils; import de.unikassel.android.sdcframework.data.Weekday; import de.unikassel.android.sdcframework.data.WeekdaySchedule; import de.unikassel.android.sdcframework.data.WeekdayScheduleEntry; import de.unikassel.android.sdcframework.data.WeekdaySchedulerAction; import de.unikassel.android.sdcframework.data.WeeklySchedule; import de.unikassel.android.sdcframework.preferences.ApplicationPreferenceManagerImpl; import de.unikassel.android.sdcframework.preferences.facade.ApplicationPreferenceManager; import de.unikassel.android.sdcframework.preferences.facade.SinglePreference; import de.unikassel.android.sdcframework.util.Logger; /** * Scheduler for the the SDCF weekly time schedule. * * @author Katy Hilgenberg * */ public final class SDCFSchedulerActivity extends Activity { /** * Constant to request a new schedule entry. */ private static final int REQUEST_NEW_ENTRY = 0; /** * Constant to request changes for an existing schedule entry. */ private static final int EDIT_OLD_ENTRY = 1; /** * The schedule. */ private WeeklySchedule schedule; /** * The view to weekday schedule mapping. */ private final Map< View, WeekdaySchedule > mapView2Schedule; /** * Currently edited entry. */ private WeekdayScheduleEntry editedEntry; /** * The preference manager */ private final ApplicationPreferenceManager prefManager; /** * The add entry button. */ private Button btnAdd; /** * The add save schedule button. */ private Button btnSave; /** * Constructor */ public SDCFSchedulerActivity() { super(); this.mapView2Schedule = new HashMap< View, WeekdaySchedule >(); this.prefManager = new ApplicationPreferenceManagerImpl(); } /* * (non-Javadoc) * * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); setContentView( R.layout.scheduler_layout ); btnAdd = (Button) findViewById( R.id.btnAdd ); btnAdd.setOnClickListener( new OnClickListener() { @Override public void onClick( View v ) { onAddEntry(); } } ); btnSave = (Button) findViewById( R.id.btnChoose ); btnSave.setOnClickListener( new OnClickListener() { @Override public void onClick( View v ) { onSaveSchedule(); } } ); setSchedule( loadSchedule() ); } /** * @param newSchedule the new schedule to set */ public void setSchedule( WeeklySchedule newSchedule ) { this.schedule = newSchedule; mapView2Schedule.put( findViewById( R.id.Monday ), schedule.getScheduleForWeekday( Weekday.Monday ) ); mapView2Schedule.put( findViewById( R.id.Tuesday ), schedule.getScheduleForWeekday( Weekday.Tuesday ) ); mapView2Schedule.put( findViewById( R.id.Wednesday ), schedule.getScheduleForWeekday( Weekday.Wednesday ) ); mapView2Schedule.put( findViewById( R.id.Thursday ), schedule.getScheduleForWeekday( Weekday.Thursday ) ); mapView2Schedule.put( findViewById( R.id.Friday ), schedule.getScheduleForWeekday( Weekday.Friday ) ); mapView2Schedule.put( findViewById( R.id.Saturday ), schedule.getScheduleForWeekday( Weekday.Saturday ) ); mapView2Schedule.put( findViewById( R.id.Sunday ), schedule.getScheduleForWeekday( Weekday.Sunday ) ); for ( View view : mapView2Schedule.keySet() ) { TextView workDayNameView = (TextView) view.findViewById( R.id.weekdayName ); WeekdaySchedule schedule = mapView2Schedule.get( view ); workDayNameView.setText( schedule.getWeekday().name().substring( 0, 3 ) ); ListView scheduleEntryList = (ListView) view.findViewById( R.id.weekdayScheduleEntryList ); scheduleEntryList.setAdapter( new WeekdayScheduleEntryListAdapter( this, schedule.getEntries() ) ); registerForContextMenu( scheduleEntryList ); } editedEntry = null; refreshView(); } /** * Method to update button states */ protected void refreshView() { btnSave.setEnabled( ScheduleValidator.validate( schedule ) ); for ( View view : mapView2Schedule.keySet() ) { ListView scheduleEntryList = (ListView) view.findViewById( R.id.weekdayScheduleEntryList ); ( (WeekdayScheduleEntryListAdapter) ( (ListView) scheduleEntryList ).getAdapter() ).notifyDataSetChanged(); } } /** * Does load the schedule from the service preferences. * * @return the weekly schedule */ protected WeeklySchedule loadSchedule() { return prefManager.getServicePreferences().getWeeklySchedulePreference().getConfiguration( prefManager.getSharedPreferences( getApplicationContext() ) ); } /* * (non-Javadoc) * * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) */ @Override public boolean onCreateOptionsMenu( Menu menu ) { MenuInflater inflater = getMenuInflater(); inflater.inflate( R.menu.scheduler_option_menu, menu ); return true; } /* * (non-Javadoc) * * @see android.app.Activity#onPrepareOptionsMenu(android.view.Menu) */ @Override public boolean onPrepareOptionsMenu( Menu menu ) { MenuItem menuItem = menu.findItem( R.id.saveSchedule ); if ( menuItem != null ) menuItem.setEnabled( btnSave.isEnabled() ); return super.onPrepareOptionsMenu( menu ); } /* * (non-Javadoc) * * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) */ @Override public boolean onOptionsItemSelected( MenuItem item ) { int itemId = item.getItemId(); if ( itemId == R.id.addEntry ) { return onAddEntry(); } else if ( itemId == R.id.saveSchedule ) { return onSaveSchedule(); } else if ( itemId == R.id.clearSchedule ) { return onClearSchedule(); } return super.onOptionsItemSelected( item ); } /** * Method to save a schedule and leave * @return true if successful, false otherwise. */ private boolean onClearSchedule() { setSchedule( new WeeklySchedule() ); return true; } /** * Method to save a schedule and leave * * @return true if successful, false otherwise. */ private boolean onSaveSchedule() { if ( ScheduleValidator.validate( schedule ) ) { try { SinglePreference< WeeklySchedule > schedulePref = prefManager.getServicePreferences().getWeeklySchedulePreference(); Editor editor = prefManager.getSharedPreferences( getApplicationContext() ).edit(); editor.putString( schedulePref.getKey(), schedule.toXML() ); editor.commit(); Intent result = new Intent(); setResult( Activity.RESULT_OK, result ); Logger.getInstance().debug( this, schedule.toString() ); finish(); return true; } catch ( Exception e ) { Logger.getInstance().error( this, e.getMessage() ); DialogUtils.showAlertMessage( this, String.format( getResources().getString( R.string.err_saving_schedule ), e.getMessage() ) ); } } return false; } /** * Handler for add entry. * * @return true if successful, false otherwise */ private boolean onAddEntry() { Intent intent = new Intent( this, SDCFSchedulerEditEntryActivity.class ); startActivityForResult( intent, REQUEST_NEW_ENTRY ); return true; } /** * Handler for edit entry. * * @param entry * the entry to wedit * * @return true if successful, false otherwise */ private boolean onEditEntry( WeekdayScheduleEntry entry ) { Intent intent = entry.getIntent(); intent.setClass( this, SDCFSchedulerEditEntryActivity.class ); editedEntry = entry; startActivityForResult( intent, EDIT_OLD_ENTRY ); return true; } /* * (non-Javadoc) * * @see android.app.Activity#onActivityResult(int, int, * android.content.Intent) */ @Override protected void onActivityResult( int requestCode, int resultCode, Intent data ) { // Make sure the request was successful if ( resultCode == RESULT_OK ) { switch ( requestCode ) { case REQUEST_NEW_ENTRY: { addNewEntry( data ); break; } case EDIT_OLD_ENTRY: { deleteEntry( editedEntry ); addNewEntry( data ); break; } } } } /** * Method to create a new entry from intent data. * * @param data * the intent data to create new entry from */ protected void addNewEntry( Intent data ) { String val = data.getStringExtra( SDCFSchedulerEditEntryActivity.WEEKDAY ); Entry< View, WeekdaySchedule > weekdayScheduleEntry = getWeekdayScheduleEntry( val ); WeekdaySchedule weekdaySchedule = weekdayScheduleEntry.getValue(); int startTime = data.getIntExtra( SDCFSchedulerEditEntryActivity.TIME, 0 ); val = data.getStringExtra( SDCFSchedulerEditEntryActivity.ACTION ); WeekdayScheduleEntry newEntry = new WeekdayScheduleEntry( startTime, WeekdaySchedulerAction.valueOf( val ) ); weekdaySchedule.addEntry( newEntry ); refreshView(); } /** * Method to request weekday entry value for a string description value. * * @param val * the value to get an entry for * @return the entry for the given value or null */ private Entry< View, WeekdaySchedule > getWeekdayScheduleEntry( String val ) { Weekday weekday = Weekday.valueOf( val ); for ( Entry< View, WeekdaySchedule > entry : mapView2Schedule.entrySet() ) { if ( weekday.equals( entry.getValue().getWeekday() ) ) return entry; } return null; } /* * (non-Javadoc) * * @see android.app.Activity#onDestroy() */ @Override protected void onDestroy() { super.onDestroy(); } /* * (non-Javadoc) * * @see android.app.Activity#onResume() */ @Override protected void onResume() { super.onResume(); } /* * (non-Javadoc) * * @see android.app.Activity#onPause() */ @Override protected void onPause() { super.onPause(); } /* * (non-Javadoc) * * @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, * android.view.View, android.view.ContextMenu.ContextMenuInfo) */ @Override public void onCreateContextMenu( ContextMenu menu, View v, ContextMenuInfo menuInfo ) { super.onCreateContextMenu( menu, v, menuInfo ); MenuInflater inflater = getMenuInflater(); inflater.inflate( R.menu.scheduler_context_menu, menu ); } /* * (non-Javadoc) * * @see android.app.Activity#onContextItemSelected(android.view.MenuItem) */ @Override public boolean onContextItemSelected( MenuItem item ) { if ( item.getItemId() == R.id.editEntry ) { return editEntry( (AdapterContextMenuInfo) item.getMenuInfo() ); } else if ( item.getItemId() == R.id.deleteEntry ) { return deleteEntry( (AdapterContextMenuInfo) item.getMenuInfo() ); } return super.onContextItemSelected( item ); } /** * Delete entry context menu handler. * * @param info * the context menu info * @return true if successful, false otherwise */ private boolean deleteEntry( AdapterContextMenuInfo info ) { ViewParent parent = info.targetView.getParent(); if ( parent instanceof ListView ) { ListView view = (ListView) parent; if ( view.getAdapter() instanceof WeekdayScheduleEntryListAdapter ) { WeekdayScheduleEntryListAdapter adapter = (WeekdayScheduleEntryListAdapter) view.getAdapter(); WeekdayScheduleEntry entry = adapter.getItem( (int) info.id ); deleteEntry( entry ); return true; } } return false; } /** * Method to delete an entry. * @param entry * the entry to delete */ protected void deleteEntry( WeekdayScheduleEntry entry ) { entry.setWeekdaySchedule( null ); refreshView(); } /** * Edit entry context menu handler. * * @param info * the context menu info * @return true if successful, false otherwise */ private boolean editEntry( AdapterContextMenuInfo info ) { ViewParent parent = info.targetView.getParent(); if ( parent instanceof ListView ) { ListView view = (ListView) parent; if ( view.getAdapter() instanceof WeekdayScheduleEntryListAdapter ) { WeekdayScheduleEntryListAdapter adapter = (WeekdayScheduleEntryListAdapter) view.getAdapter(); WeekdayScheduleEntry entry = adapter.getItem( (int) info.id ); return onEditEntry( entry ); } } return false; } }