MonthByWeekAdapter.java revision 90b01744006009ed5ca7205099523f83ced380f5
1/*
2 * Copyright (C) 2010 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.month;
18
19import com.android.calendar.CalendarController;
20import com.android.calendar.CalendarController.EventType;
21import com.android.calendar.CalendarController.ViewType;
22import com.android.calendar.Event;
23import com.android.calendar.Utils;
24
25import android.content.Context;
26import android.content.res.Configuration;
27import android.text.format.Time;
28import android.util.Log;
29import android.view.View;
30import android.view.ViewGroup;
31import android.widget.AbsListView.LayoutParams;
32
33import java.util.ArrayList;
34import java.util.HashMap;
35
36public class MonthByWeekAdapter extends SimpleWeeksAdapter {
37    private static final String TAG = "MonthByWeek";
38
39    public static final String WEEK_PARAMS_IS_MINI = "mini_month";
40    protected static int DEFAULT_QUERY_DAYS = 7 * 8; // 8 weeks
41
42    protected CalendarController mController;
43    protected String mHomeTimeZone;
44    protected Time mTempTime;
45    protected Time mToday;
46    protected int mFirstJulianDay;
47    protected int mQueryDays;
48    protected boolean mIsMiniMonth = true;
49    protected int mOrientation = Configuration.ORIENTATION_LANDSCAPE;
50
51    protected ArrayList<ArrayList<Event>> mEventDayList = new ArrayList<ArrayList<Event>>();
52
53    public MonthByWeekAdapter(Context context, HashMap<String, Integer> params) {
54        super(context, params);
55        if (params.containsKey(WEEK_PARAMS_IS_MINI)) {
56            mIsMiniMonth = params.get(WEEK_PARAMS_IS_MINI) != 0;
57        }
58    }
59
60    @Override
61    protected void init() {
62        super.init();
63        mController = CalendarController.getInstance(mContext);
64        mHomeTimeZone = Utils.getTimeZone(mContext, null);
65        mSelectedDay.switchTimezone(mHomeTimeZone);
66        mToday = new Time(mHomeTimeZone);
67        mToday.setToNow();
68        mTempTime = new Time(mHomeTimeZone);
69    }
70
71    private void updateTimeZones() {
72        mSelectedDay.timezone = mHomeTimeZone;
73        mSelectedDay.normalize(true);
74        mToday.timezone = mHomeTimeZone;
75        mToday.setToNow();
76        mTempTime.switchTimezone(mHomeTimeZone);
77    }
78
79    @Override
80    public void setSelectedDay(Time selectedTime) {
81        mSelectedDay.set(selectedTime);
82        long millis = mSelectedDay.normalize(true);
83        mSelectedWeek = Utils.getWeeksSinceEpochFromJulianDay(
84                Time.getJulianDay(millis, mSelectedDay.gmtoff), mFirstDayOfWeek);
85        notifyDataSetChanged();
86    }
87
88    public void setEvents(int firstJulianDay, int numDays, ArrayList<Event> events) {
89        if (mIsMiniMonth) {
90            if (Log.isLoggable(TAG, Log.ERROR)) {
91                Log.e(TAG, "Attempted to set events for mini view. Events only supported in full"
92                        + " view.");
93            }
94            return;
95        }
96        mFirstJulianDay = firstJulianDay;
97        mQueryDays = numDays;
98        // Create a new list, this is necessary since the weeks are referencing
99        // pieces of the old list
100        ArrayList<ArrayList<Event>> eventDayList = new ArrayList<ArrayList<Event>>();
101        for (int i = 0; i < numDays; i++) {
102            eventDayList.add(new ArrayList<Event>());
103        }
104
105        if (events == null || events.size() == 0) {
106            if(Log.isLoggable(TAG, Log.DEBUG)) {
107                Log.d(TAG, "No events. Returning early--go schedule something fun.");
108            }
109            refresh();
110            return;
111        }
112
113        // Compute the new set of days with events
114        for (Event event : events) {
115            int startDay = event.startDay - mFirstJulianDay;
116            int endDay = event.endDay - mFirstJulianDay + 1;
117            if (startDay < numDays || endDay >= 0) {
118                if (startDay < 0) {
119                    startDay = 0;
120                }
121                if (startDay > numDays) {
122                    continue;
123                }
124                if (endDay < 0) {
125                    continue;
126                }
127                if (endDay > numDays) {
128                    endDay = numDays;
129                }
130                for (int j = startDay; j < endDay; j++) {
131                    eventDayList.get(j).add(event);
132                }
133            }
134        }
135        if(Log.isLoggable(TAG, Log.DEBUG)) {
136            Log.d(TAG, "Processed " + events.size() + " events.");
137        }
138        mEventDayList = eventDayList;
139        refresh();
140    }
141
142    @SuppressWarnings("unchecked")
143    @Override
144    public View getView(int position, View convertView, ViewGroup parent) {
145        if (mIsMiniMonth) {
146            return super.getView(position, convertView, parent);
147        }
148        MonthWeekEventsView v;
149        LayoutParams params = new LayoutParams(
150                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
151        HashMap<String, Integer> drawingParams = null;
152        if (convertView != null) {
153            v = (MonthWeekEventsView) convertView;
154            // TODO Store drawing params in the view's Tag instead of having a
155            // new getter method
156            drawingParams = (HashMap<String, Integer>) v.getTag();
157        } else {
158            v = new MonthWeekEventsView(mContext);
159        }
160        if (drawingParams == null) {
161            drawingParams = new HashMap<String, Integer>();
162        }
163        drawingParams.clear();
164
165        v.setLayoutParams(params);
166        v.setClickable(true);
167        v.setOnTouchListener(this);
168
169        int selectedDay = -1;
170        if (mSelectedWeek == position) {
171            selectedDay = mSelectedDay.weekDay;
172        }
173
174        drawingParams.put(SimpleWeekView.VIEW_PARAMS_HEIGHT,
175                (parent.getHeight() - WEEK_7_OVERHANG_HEIGHT) / mNumWeeks);
176        drawingParams.put(SimpleWeekView.VIEW_PARAMS_SELECTED_DAY, selectedDay);
177        drawingParams.put(SimpleWeekView.VIEW_PARAMS_SHOW_WK_NUM, mShowWeekNumber ? 1 : 0);
178        drawingParams.put(SimpleWeekView.VIEW_PARAMS_WEEK_START, mFirstDayOfWeek);
179        drawingParams.put(SimpleWeekView.VIEW_PARAMS_NUM_DAYS, mDaysPerWeek);
180        drawingParams.put(SimpleWeekView.VIEW_PARAMS_WEEK, position);
181        drawingParams.put(SimpleWeekView.VIEW_PARAMS_FOCUS_MONTH, mFocusMonth);
182        drawingParams.put(MonthWeekEventsView.VIEW_PARAMS_ORIENTATION, mOrientation);
183        v.setWeekParams(drawingParams, mSelectedDay.timezone);
184
185        sendEventsToView(v);
186
187        return v;
188    }
189
190    private void sendEventsToView(MonthWeekEventsView v) {
191        if (mEventDayList.size() == 0) {
192            if (Log.isLoggable(TAG, Log.DEBUG)) {
193                Log.d(TAG, "No events loaded, did not pass any events to view.");
194            }
195            v.setEvents(null);
196            return;
197        }
198        int viewJulianDay = v.getFirstJulianDay();
199        int start = viewJulianDay - mFirstJulianDay;
200        int end = start + v.mNumDays;
201        if (start < 0 || end > mEventDayList.size()) {
202            if (Log.isLoggable(TAG, Log.DEBUG)) {
203                Log.d(TAG, "Week is outside range of loaded events. viewStart: " + viewJulianDay
204                        + " eventsStart: " + mFirstJulianDay);
205            }
206            v.setEvents(null);
207            return;
208        }
209        v.setEvents(mEventDayList.subList(start, end));
210    }
211
212    @Override
213    protected void refresh() {
214        mFirstDayOfWeek = Utils.getFirstDayOfWeek(mContext);
215        mShowWeekNumber = Utils.getShowWeekNumber(mContext);
216        mHomeTimeZone = Utils.getTimeZone(mContext, null);
217        mOrientation = mContext.getResources().getConfiguration().orientation;
218        updateTimeZones();
219        notifyDataSetChanged();
220    }
221
222    @Override
223    protected void onDayTapped(Time day) {
224        day.timezone = mHomeTimeZone;
225        Time currTime = new Time(mHomeTimeZone);
226        currTime.set(mController.getTime());
227        day.hour = currTime.hour;
228        day.minute = currTime.minute;
229        day.allDay = false;
230        day.normalize(true);
231        mController.sendEvent(mContext, EventType.GO_TO, day, day, -1,
232                mIsMiniMonth ? ViewType.CURRENT : ViewType.DETAIL);
233    }
234
235}
236