blob: 89b07ecaf903ce6d39b0d99f3ae29cd0a24acd93 [file] [log] [blame]
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.calendar;
import static android.provider.Calendar.EVENT_BEGIN_TIME;
import dalvik.system.VMRuntime;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.Calendar.Events;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Animation.AnimationListener;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ViewSwitcher;
import android.widget.Gallery.LayoutParams;
import java.util.Calendar;
public class MonthActivity extends Activity implements ViewSwitcher.ViewFactory,
Navigator, AnimationListener {
private static final int INITIAL_HEAP_SIZE = 4 * 1024 * 1024;
private Animation mInAnimationPast;
private Animation mInAnimationFuture;
private Animation mOutAnimationPast;
private Animation mOutAnimationFuture;
private ViewSwitcher mSwitcher;
private Time mTime;
private ContentResolver mContentResolver;
EventLoader mEventLoader;
private int mStartDay;
private ProgressBar mProgressBar;
protected void startProgressSpinner() {
// start the progress spinner
mProgressBar.setVisibility(View.VISIBLE);
}
protected void stopProgressSpinner() {
// stop the progress spinner
mProgressBar.setVisibility(View.GONE);
}
/* ViewSwitcher.ViewFactory interface methods */
public View makeView() {
MonthView mv = new MonthView(this, this);
mv.setLayoutParams(new ViewSwitcher.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
mv.setSelectedTime(mTime);
return mv;
}
/* Navigator interface methods */
public void goTo(Time time) {
TextView title = (TextView) findViewById(R.id.title);
title.setText(Utils.formatMonthYear(time));
MonthView current = (MonthView) mSwitcher.getCurrentView();
current.dismissPopup();
Time currentTime = current.getTime();
// Compute a month number that is monotonically increasing for any
// two adjacent months.
// This is faster than calling getSelectedTime() because we avoid
// a call to Time#normalize().
int currentMonth = currentTime.month + currentTime.year * 12;
int nextMonth = time.month + time.year * 12;
if (nextMonth < currentMonth) {
mSwitcher.setInAnimation(mInAnimationPast);
mSwitcher.setOutAnimation(mOutAnimationPast);
} else {
mSwitcher.setInAnimation(mInAnimationFuture);
mSwitcher.setOutAnimation(mOutAnimationFuture);
}
MonthView next = (MonthView) mSwitcher.getNextView();
next.setSelectionMode(current.getSelectionMode());
next.setSelectedTime(time);
next.reloadEvents();
next.animationStarted();
mSwitcher.showNext();
next.requestFocus();
mTime = time;
}
public void goToToday() {
Time now = new Time();
now.set(System.currentTimeMillis());
TextView title = (TextView) findViewById(R.id.title);
title.setText(Utils.formatMonthYear(now));
mTime = now;
MonthView view = (MonthView) mSwitcher.getCurrentView();
view.setSelectedTime(now);
view.reloadEvents();
}
public long getSelectedTime() {
MonthView mv = (MonthView) mSwitcher.getCurrentView();
return mv.getSelectedTimeInMillis();
}
public boolean getAllDay() {
return false;
}
int getStartDay() {
return mStartDay;
}
void eventsChanged() {
MonthView view = (MonthView) mSwitcher.getCurrentView();
view.reloadEvents();
}
/**
* Listens for intent broadcasts
*/
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_TIME_CHANGED)
|| action.equals(Intent.ACTION_DATE_CHANGED)
|| action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
eventsChanged();
}
}
};
// Create an observer so that we can update the views whenever a
// Calendar event changes.
private ContentObserver mObserver = new ContentObserver(new Handler())
{
@Override
public boolean deliverSelfNotifications() {
return true;
}
@Override
public void onChange(boolean selfChange) {
eventsChanged();
}
};
public void onAnimationStart(Animation animation) {
}
// Notifies the MonthView when an animation has finished.
public void onAnimationEnd(Animation animation) {
MonthView monthView = (MonthView) mSwitcher.getCurrentView();
monthView.animationFinished();
}
public void onAnimationRepeat(Animation animation) {
}
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Eliminate extra GCs during startup by setting the initial heap size to 4MB.
// TODO: We should restore the old heap size once the activity reaches the idle state
long oldHeapSize = VMRuntime.getRuntime().setMinimumHeapSize(INITIAL_HEAP_SIZE);
setContentView(R.layout.month_activity);
mContentResolver = getContentResolver();
long time;
if (icicle != null) {
time = icicle.getLong(EVENT_BEGIN_TIME);
} else {
time = Utils.timeFromIntentInMillis(getIntent());
}
mTime = new Time();
mTime.set(time);
mTime.normalize(true);
// Get first day of week based on locale and populate the day headers
mStartDay = Calendar.getInstance().getFirstDayOfWeek();
int diff = mStartDay - Calendar.SUNDAY - 1;
String dayString = DateUtils.getDayOfWeekString((Calendar.SUNDAY + diff) % 7 + 1,
DateUtils.LENGTH_MEDIUM);
((TextView) findViewById(R.id.day0)).setText(dayString);
dayString = DateUtils.getDayOfWeekString((Calendar.MONDAY + diff) % 7 + 1,
DateUtils.LENGTH_MEDIUM);
((TextView) findViewById(R.id.day1)).setText(dayString);
dayString = DateUtils.getDayOfWeekString((Calendar.TUESDAY + diff) % 7 + 1,
DateUtils.LENGTH_MEDIUM);
((TextView) findViewById(R.id.day2)).setText(dayString);
dayString = DateUtils.getDayOfWeekString((Calendar.WEDNESDAY + diff) % 7 + 1,
DateUtils.LENGTH_MEDIUM);
((TextView) findViewById(R.id.day3)).setText(dayString);
dayString = DateUtils.getDayOfWeekString((Calendar.THURSDAY + diff) % 7 + 1,
DateUtils.LENGTH_MEDIUM);
((TextView) findViewById(R.id.day4)).setText(dayString);
dayString = DateUtils.getDayOfWeekString((Calendar.FRIDAY + diff) % 7 + 1,
DateUtils.LENGTH_MEDIUM);
((TextView) findViewById(R.id.day5)).setText(dayString);
dayString = DateUtils.getDayOfWeekString((Calendar.SATURDAY + diff) % 7 + 1,
DateUtils.LENGTH_MEDIUM);
((TextView) findViewById(R.id.day6)).setText(dayString);
// Set the initial title
TextView title = (TextView) findViewById(R.id.title);
title.setText(Utils.formatMonthYear(mTime));
mEventLoader = new EventLoader(this);
mProgressBar = (ProgressBar) findViewById(R.id.progress_circular);
mSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
mSwitcher.setFactory(this);
mSwitcher.getCurrentView().requestFocus();
mInAnimationPast = AnimationUtils.loadAnimation(this, R.anim.slide_down_in);
mOutAnimationPast = AnimationUtils.loadAnimation(this, R.anim.slide_down_out);
mInAnimationFuture = AnimationUtils.loadAnimation(this, R.anim.slide_up_in);
mOutAnimationFuture = AnimationUtils.loadAnimation(this, R.anim.slide_up_out);
mInAnimationPast.setAnimationListener(this);
mInAnimationFuture.setAnimationListener(this);
}
@Override
protected void onPause() {
super.onPause();
if (isFinishing()) {
mEventLoader.stopBackgroundThread();
}
mContentResolver.unregisterContentObserver(mObserver);
unregisterReceiver(mIntentReceiver);
MonthView view = (MonthView) mSwitcher.getCurrentView();
view.dismissPopup();
view = (MonthView) mSwitcher.getNextView();
view.dismissPopup();
mEventLoader.stopBackgroundThread();
}
@Override
protected void onResume() {
super.onResume();
mEventLoader.startBackgroundThread();
eventsChanged();
MonthView view1 = (MonthView) mSwitcher.getCurrentView();
MonthView view2 = (MonthView) mSwitcher.getNextView();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String str = prefs.getString(CalendarPreferenceActivity.KEY_DETAILED_VIEW,
CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW);
view1.setDetailedView(str);
view2.setDetailedView(str);
// Record Month View as the (new) start view
String activityString = CalendarApplication.ACTIVITY_NAMES[CalendarApplication.MONTH_VIEW_ID];
SharedPreferences.Editor editor = prefs.edit();
editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString);
editor.commit();
// Register for Intent broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(mIntentReceiver, filter);
mContentResolver.registerContentObserver(Events.CONTENT_URI,
true, mObserver);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(EVENT_BEGIN_TIME, mTime.toMillis(true));
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuHelper.onPrepareOptionsMenu(this, menu);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuHelper.onCreateOptionsMenu(menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
MenuHelper.onOptionsItemSelected(this, item, this);
return super.onOptionsItemSelected(item);
}
}