AgendaFragment.java revision 888ffcf22fe26989736b80d826aac211f5ad5c43
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.calendar.agenda; 18 19 20import android.app.Activity; 21import android.app.Fragment; 22import android.app.FragmentManager; 23import android.app.FragmentTransaction; 24import android.content.Context; 25import android.content.SharedPreferences; 26import android.os.Bundle; 27import android.text.format.Time; 28import android.util.Log; 29import android.view.LayoutInflater; 30import android.view.View; 31import android.view.ViewGroup; 32import android.widget.Adapter; 33import android.widget.HeaderViewListAdapter; 34 35import com.android.calendar.CalendarController; 36import com.android.calendar.CalendarController.EventInfo; 37import com.android.calendar.CalendarController.EventType; 38import com.android.calendar.GeneralPreferences; 39import com.android.calendar.R; 40import com.android.calendar.StickyHeaderListView; 41import com.android.calendar.StickyHeaderListView.HeaderIndexer; 42import com.android.calendar.Utils; 43import com.android.calendar.event.EditEventFragment; 44 45 46public class AgendaFragment extends Fragment implements CalendarController.EventHandler { 47 48 private static final String TAG = AgendaFragment.class.getSimpleName(); 49 private static boolean DEBUG = false; 50 51 protected static final String BUNDLE_KEY_RESTORE_TIME = "key_restore_time"; 52 protected static final String BUNDLE_KEY_RESTORE_INSTANCE_ID = "key_restore_instance_id"; 53 private static final long INITIAL_HEAP_SIZE = 4*1024*1024; 54 55 private AgendaListView mAgendaListView; 56 private Activity mActivity; 57 private Time mTime; 58 private String mTimeZone; 59 private long mInitialTimeMillis; 60 private boolean mShowEventDetailsWithAgenda; 61 private CalendarController mController; 62 private EditEventFragment mEventFragment; 63 private String mQuery; 64 private boolean mUsedForSearch = false; 65 66 67 private Runnable mTZUpdater = new Runnable() { 68 @Override 69 public void run() { 70 mTimeZone = Utils.getTimeZone(getActivity(), this); 71 mTime = new Time(mTimeZone); 72 } 73 }; 74 75 public AgendaFragment() { 76 this(0, false); 77 } 78 79 80 // timeMillis - time of first event to show 81 // usedForSearch - indicates if this fragment is used in the search fragment 82 public AgendaFragment(long timeMillis, boolean usedForSearch) { 83 mInitialTimeMillis = timeMillis; 84 mTime = new Time(); 85 mUsedForSearch = usedForSearch; 86 } 87 88 @Override 89 public void onAttach(Activity activity) { 90 super.onAttach(activity); 91 mTimeZone = Utils.getTimeZone(activity, mTZUpdater); 92 mTime = new Time(mTimeZone); 93 if (mInitialTimeMillis == 0) { 94 mTime.setToNow(); 95 } else { 96 mTime.set(mInitialTimeMillis); 97 } 98 mActivity = activity; 99 } 100 101 @Override 102 public void onCreate(Bundle icicle) { 103 super.onCreate(icicle); 104 mController = CalendarController.getInstance(mActivity); 105 mShowEventDetailsWithAgenda = 106 Utils.getConfigBool(mActivity, R.bool.show_event_details_with_agenda); 107 108 } 109 110 @Override 111 public View onCreateView(LayoutInflater inflater, ViewGroup container, 112 Bundle savedInstanceState) { 113 114 long instanceId = -1; 115 if (savedInstanceState != null) { 116 instanceId = savedInstanceState.getLong(BUNDLE_KEY_RESTORE_INSTANCE_ID); 117 } 118 119 View v = inflater.inflate(R.layout.agenda_fragment, null); 120 121 mAgendaListView = (AgendaListView)v.findViewById(R.id.agenda_events_list); 122 mAgendaListView.goTo(mTime, -1, mQuery, false); 123 if (!mShowEventDetailsWithAgenda) { 124 v.findViewById(R.id.agenda_event_info).setVisibility(View.GONE); 125 } 126 127 // Set adapter & HeaderIndexer for StickyHeaderListView 128 StickyHeaderListView lv = 129 (StickyHeaderListView)v.findViewById(R.id.agenda_sticky_header_list); 130 if (lv != null) { 131 Adapter a = mAgendaListView.getAdapter(); 132 lv.setAdapter(a); 133 if (a instanceof HeaderViewListAdapter) { 134 lv.setIndexer((HeaderIndexer) ((HeaderViewListAdapter)a).getWrappedAdapter()); 135 } else if (a instanceof AgendaWindowAdapter) { 136 lv.setIndexer((HeaderIndexer) a); 137 } else { 138 Log.wtf(TAG, "Cannot find HeaderIndexer for StickyHeaderListView"); 139 } 140 } 141 return v; 142 } 143 144 @Override 145 public void onResume() { 146 super.onResume(); 147 if (DEBUG) { 148 Log.v(TAG, "OnResume to " + mTime.toString()); 149 } 150 151 SharedPreferences prefs = GeneralPreferences.getSharedPreferences( 152 getActivity()); 153 boolean hideDeclined = prefs.getBoolean( 154 GeneralPreferences.KEY_HIDE_DECLINED, false); 155 156 mAgendaListView.setHideDeclinedEvents(hideDeclined); 157 mAgendaListView.goTo(mTime, -1, mQuery, true); 158 mAgendaListView.onResume(); 159 160// // Register for Intent broadcasts 161// IntentFilter filter = new IntentFilter(); 162// filter.addAction(Intent.ACTION_TIME_CHANGED); 163// filter.addAction(Intent.ACTION_DATE_CHANGED); 164// filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 165// registerReceiver(mIntentReceiver, filter); 166// 167// mContentResolver.registerContentObserver(Events.CONTENT_URI, true, mObserver); 168 } 169 170 @Override 171 public void onSaveInstanceState(Bundle outState) { 172 super.onSaveInstanceState(outState); 173 174 long firstVisibleTime = mAgendaListView.getFirstVisibleTime(); 175 if (firstVisibleTime > 0) { 176 mTime.set(firstVisibleTime); 177 outState.putLong(BUNDLE_KEY_RESTORE_TIME, firstVisibleTime); 178 if (DEBUG) { 179 Log.v(TAG, "onSaveInstanceState " + mTime.toString()); 180 } 181 } 182 183 long selectedInstance = mAgendaListView.getSelectedInstanceId(); 184 if (selectedInstance >= 0) { 185 outState.putLong(BUNDLE_KEY_RESTORE_INSTANCE_ID, selectedInstance); 186 } 187 } 188 189 @Override 190 public void onDetach() { 191 super.onDetach(); 192 mController.deregisterEventHandler(R.id.agenda_event_info); 193 if (getActivity().isFinishing()) { 194 return; 195 } 196 FragmentManager fragmentManager = getFragmentManager(); 197 FragmentTransaction ft = fragmentManager.beginTransaction(); 198 Fragment f = fragmentManager.findFragmentById(R.id.agenda_event_info); 199 if (f != null) { 200 ft.remove(f); 201 } 202 ft.commit(); 203 } 204 205 206 @Override 207 public void onPause() { 208 super.onPause(); 209 210 mAgendaListView.onPause(); 211// mContentResolver.unregisterContentObserver(mObserver); 212// unregisterReceiver(mIntentReceiver); 213 214 // Record Agenda View as the (new) default detailed view. 215// Utils.setDefaultView(this, CalendarApplication.AGENDA_VIEW_ID); 216 } 217 218 private void goTo(EventInfo event, boolean animate) { 219 if (mAgendaListView == null) { 220 // The view hasn't been set yet. Just save the time and use it 221 // later. 222 mTime.set(event.startTime); 223 return; 224 } 225 mAgendaListView.goTo(event.startTime, event.id, mQuery, false); 226 showEventInfo(event); 227 } 228 229 private void search(String query, Time time) { 230 mQuery = query; 231 if (time != null) { 232 mTime.set(time); 233 } 234 if (mAgendaListView == null) { 235 // The view hasn't been set yet. Just return. 236 return; 237 } 238 mAgendaListView.goTo(time, -1, mQuery, true); 239 } 240 241 @Override 242 public void eventsChanged() { 243 mAgendaListView.refresh(true); 244 } 245 246 @Override 247 public long getSupportedEventTypes() { 248 return EventType.GO_TO | EventType.EVENTS_CHANGED | ((mUsedForSearch)?EventType.SEARCH:0); 249 } 250 251 @Override 252 public void handleEvent(EventInfo event) { 253 if (event.eventType == EventType.GO_TO) { 254 // TODO support a range of time 255 // TODO support event_id 256 // TODO figure out the animate bit 257 goTo(event, true); 258 } else if (event.eventType == EventType.SEARCH) { 259 search(event.query, event.startTime); 260 } else if (event.eventType == EventType.EVENTS_CHANGED) { 261 eventsChanged(); 262 } 263 } 264 265 266 // Shows the selected event in the Agenda view 267 private void showEventInfo(EventInfo event) { 268 269 // Ignore unknown events 270 if (event.id == -1) { 271 Log.e(TAG, "showEventInfo, event ID = " + event.id); 272 return; 273 } 274 275 // Create a fragment to show the event to the side of the agenda list 276 if (mShowEventDetailsWithAgenda) { 277 FragmentManager fragmentManager = getFragmentManager(); 278 FragmentTransaction ft = fragmentManager.beginTransaction(); 279 mEventFragment = new EditEventFragment(event, true, null); 280 ft.replace(R.id.agenda_event_info, mEventFragment); 281 mController.registerEventHandler(R.id.agenda_event_info, 282 mEventFragment); 283 ft.commit(); 284 } 285 /* 286 * else { Intent intent = new Intent(Intent.ACTION_VIEW); Uri eventUri 287 * = ContentUris.withAppendedId(Events.CONTENT_URI, event.id); 288 * intent.setData(eventUri); // intent.setClassName(this, 289 * EventInfoActivity.class.getName()); 290 * intent.putExtra(EVENT_BEGIN_TIME, event.startTime != null ? 291 * event.startTime.toMillis(true) : -1); intent.putExtra( 292 * EVENT_END_TIME, event.endTime != null ? event.endTime.toMillis(true) 293 * : -1); startActivity(intent); } 294 */ 295 } 296} 297