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