| /* |
| * 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 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 dalvik.system.VMRuntime; |
| |
| 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, boolean animate) { |
| 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(). |
| if (animate) { |
| 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()); |
| now.minute = 0; |
| now.second = 0; |
| now.normalize(false); |
| |
| 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 |
| 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 onNewIntent(Intent intent) { |
| long timeMillis = Utils.timeFromIntentInMillis(intent); |
| if (timeMillis > 0) { |
| Time time = new Time(); |
| time.set(timeMillis); |
| goTo(time, false); |
| } |
| } |
| |
| @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(); |
| |
| // Record Month View as the (new) start view |
| Utils.setDefaultView(this, CalendarApplication.MONTH_VIEW_ID); |
| } |
| |
| @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); |
| |
| // 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 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); |
| } |
| } |