OSDN Git Service

Fixed a bunch of problems when moving among agenda/day/week/month views.
authorMichael Chan <mchan@android.com>
Fri, 14 Aug 2009 20:03:39 +0000 (13:03 -0700)
committerMichael Chan <mchan@android.com>
Sat, 5 Sep 2009 00:42:42 +0000 (17:42 -0700)
b/1438315 Fixed problems introduced in the new back behavior.
b/2077287 Fixed the problem where you sometimes end up in 1969 when switch among the agenda/day/week/month views.
b/2076791  The selected date is preserved when switch to various views.
Removed scroll bar in agenda view as the header was not a static list of events anymore
Cleaned up some TODOs.

res/values/strings.xml
src/com/android/calendar/AgendaActivity.java
src/com/android/calendar/AgendaAdapter.java
src/com/android/calendar/AgendaByDayAdapter.java
src/com/android/calendar/AgendaListView.java
src/com/android/calendar/AgendaWindowAdapter.java
src/com/android/calendar/CalendarActivity.java
src/com/android/calendar/MonthActivity.java
src/com/android/calendar/Utils.java
src/com/android/calendar/WeekActivity.java

index 474be03..e6d2d22 100644 (file)
     <!-- Agenda View strings -->
     <skip />
     <!-- This is shown as part of the heading at the top of a list of today's events. -->
-    <string name="agenda_today">Today</string>
+    <string name="agenda_today">Today, <xliff:g id="date">%1$s</xliff:g></string>
     <!-- This is shown while the calendar events are being loading to the screen. -->
     <string name="loading">Loading\u2026</string>
     <!-- This is shown at the top of the agenda view showing the range of events shown. -->
index 4414859..4e98884 100644 (file)
@@ -17,7 +17,6 @@
 package com.android.calendar;
 
 import static android.provider.Calendar.EVENT_BEGIN_TIME;
-import dalvik.system.VMRuntime;
 
 import android.app.Activity;
 import android.content.BroadcastReceiver;
@@ -37,6 +36,8 @@ import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 
+import dalvik.system.VMRuntime;
+
 public class AgendaActivity extends Activity implements Navigator {
 
     private static final String TAG = "AgendaActivity";
@@ -106,7 +107,9 @@ public class AgendaActivity extends Activity implements Navigator {
             // Returns 0 if key not found
             millis = getIntent().getLongExtra(EVENT_BEGIN_TIME, 0);
             if (DEBUG) {
-                Log.v(TAG, "Restore value from intent: " + millis);
+                Time time = new Time();
+                time.set(millis);
+                Log.v(TAG, "Restore value from intent: " + time.toString());
             }
         }
 
@@ -131,6 +134,15 @@ public class AgendaActivity extends Activity implements Navigator {
     }
 
     @Override
+    protected void onNewIntent(Intent intent) {
+        long time = Utils.timeFromIntentInMillis(intent);
+        if (time > 0) {
+            mTime.set(time);
+            goTo(mTime);
+        }
+    }
+
+    @Override
     protected void onResume() {
         super.onResume();
         if (DEBUG) {
index 8603fc7..e54e345 100644 (file)
@@ -33,7 +33,8 @@ public class AgendaAdapter extends ResourceCursorAdapter {
     private String mNoTitleLabel;
     private Resources mResources;
     private int mDeclinedColor;
-    private Formatter mFormatter; // TODO fix. not thread safe
+    // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread.
+    private Formatter mFormatter;
     private StringBuilder mStringBuilder;
 
     static class ViewHolder {
index 18cdde6..5349350 100644 (file)
@@ -43,7 +43,8 @@ public class AgendaByDayAdapter extends BaseAdapter {
     private ArrayList<RowInfo> mRowInfo;
     private int mTodayJulianDay;
     private Time mTmpTime = new Time();
-    private Formatter mFormatter; // TODO fix. not thread safe
+    // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread.
+    private Formatter mFormatter;
     private StringBuilder mStringBuilder;
 
     static class ViewHolder {
@@ -136,16 +137,20 @@ public class AgendaByDayAdapter extends BaseAdapter {
                     | DateUtils.FORMAT_SHOW_DATE;
 
             mStringBuilder.setLength(0);
+            String dateViewText;
             if (row.mData == mTodayJulianDay) {
-                String dayText = mContext.getResources().getText(R.string.agenda_today) + ", ";
-                holder.dateView.setText(dayText + DateUtils.formatDateRange(mContext, mFormatter,
-                    millis, millis, flags).toString());
+                dateViewText = mContext.getString(R.string.agenda_today, DateUtils.formatDateRange(
+                        mContext, mFormatter, millis, millis, flags).toString());
             } else {
                 flags |= DateUtils.FORMAT_SHOW_WEEKDAY;
-                holder.dateView.setText(DateUtils.formatDateRange(mContext, mFormatter, millis,
-                    millis, flags).toString());
+                dateViewText = DateUtils.formatDateRange(mContext, mFormatter, millis, millis,
+                        flags).toString();
             }
 
+            if (AgendaWindowAdapter.BASICLOG) {
+                dateViewText += " P:" + position;
+            }
+            holder.dateView.setText(dateViewText);
 
             return agendaDayView;
         } else if (row.mType == TYPE_MEETING) {
index a4e792a..f5e63b4 100644 (file)
@@ -16,9 +16,6 @@
 
 package com.android.calendar;
 
-import com.android.calendar.AgendaAdapter.ViewHolder;
-import com.android.calendar.AgendaWindowAdapter.EventInfo;
-
 import android.content.ContentUris;
 import android.content.Intent;
 import android.graphics.Rect;
@@ -33,6 +30,9 @@ import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.AdapterView.OnItemClickListener;
 
+import com.android.calendar.AgendaAdapter.ViewHolder;
+import com.android.calendar.AgendaWindowAdapter.EventInfo;
+
 public class AgendaListView extends ListView implements OnItemClickListener {
 
     private static final String TAG = "AgendaListView";
@@ -50,6 +50,7 @@ public class AgendaListView extends ListView implements OnItemClickListener {
 
         setOnItemClickListener(this);
         setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        setVerticalScrollBarEnabled(false);
         mWindowAdapter = new AgendaWindowAdapter(agendaActivity, this);
         setAdapter(mWindowAdapter);
         mDeleteEventHelper =
@@ -82,7 +83,11 @@ public class AgendaListView extends ListView implements OnItemClickListener {
 
     public void refresh(boolean forced) {
         Time time = new Time();
-        time.set(getFirstVisiblePosition());
+        long goToTime = getFirstVisibleTime();
+        if (goToTime <= 0) {
+            goToTime = System.currentTimeMillis();
+        }
+        time.set(goToTime);
         mWindowAdapter.refresh(time, forced);
     }
 
@@ -127,12 +132,13 @@ public class AgendaListView extends ListView implements OnItemClickListener {
 
     public long getSelectedTime() {
         int position = getSelectedItemPosition();
-
-        EventInfo event = mWindowAdapter.getEventByPosition(position);
-        if (event != null) {
-            return event.begin;
+        if (position >= 0) {
+            EventInfo event = mWindowAdapter.getEventByPosition(position);
+            if (event != null) {
+                return event.begin;
+            }
         }
-        return 0;
+        return getFirstVisibleTime();
     }
 
     public long getFirstVisibleTime() {
index 72e2538..cee686b 100644 (file)
@@ -32,6 +32,7 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.widget.BaseAdapter;
+import android.widget.ListView;
 import android.widget.TextView;
 
 import java.util.Formatter;
@@ -46,12 +47,11 @@ Bugs Bugs Bugs:
  listview.setSelection() in 2 rapid secessions but it dropped or didn't process the first one.
 - Query of 2009 11 09 to 2010 01 15 didnt't return anything. In fact, Query of 2010 is showing nothing
 - Scroll using trackball isn't repositioning properly after a new adapter is added.
+- Track ball clicks at the header/footer doesn't work.
 - Potential ping pong effect if the prefetch window is big and data is limited
 - Add index in calendar provider
 
 ToDo ToDo ToDo:
-Remove scrollbars
-Remove debug P:XXX from event text
 Get design of header and footer from designer
 
 Make scrolling smoother.
@@ -62,8 +62,8 @@ Check for leaks and excessive allocations
 
 public class AgendaWindowAdapter extends BaseAdapter {
 
-    private static final boolean BASICLOG = false;
-    private static final boolean DEBUGLOG = false;
+    static final boolean BASICLOG = false;
+    static final boolean DEBUGLOG = false;
     private static String TAG = "AgendaWindowAdapter";
 
     private static final String AGENDA_SORT_ORDER = "startDay ASC, begin ASC, title ASC";
@@ -155,8 +155,8 @@ public class AgendaWindowAdapter extends BaseAdapter {
     // Number of "newer" query that has been processed.
     private int mNewerRequestsProcessed;
 
-    private Formatter mFormatter; // TODO fix. not thread safe
-
+    // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread.
+    private Formatter mFormatter;
     private StringBuilder mStringBuilder;
 
     private boolean mShuttingDown;
@@ -181,6 +181,43 @@ public class AgendaWindowAdapter extends BaseAdapter {
         public QuerySpec(int queryType) {
             this.queryType = queryType;
         }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + end;
+            result = prime * result + (int) (queryStartMillis ^ (queryStartMillis >>> 32));
+            result = prime * result + queryType;
+            result = prime * result + start;
+            if (goToTime != null) {
+                long goToTimeMillis = goToTime.toMillis(false);
+                result = prime * result + (int) (goToTimeMillis ^ (goToTimeMillis >>> 32));
+            }
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) return true;
+            if (obj == null) return false;
+            if (getClass() != obj.getClass()) return false;
+            QuerySpec other = (QuerySpec) obj;
+            if (end != other.end || queryStartMillis != other.queryStartMillis
+                    || queryType != other.queryType || start != other.start) {
+                return false;
+            }
+            if (goToTime != null) {
+                if (goToTime.toMillis(false) != other.goToTime.toMillis(false)) {
+                    return false;
+                }
+            } else {
+                if (other.goToTime != null) {
+                    return false;
+                }
+            }
+            return true;
+        }
     }
 
     static class EventInfo {
@@ -420,9 +457,7 @@ public class AgendaWindowAdapter extends BaseAdapter {
     }
 
     public void refresh(Time goToTime, boolean forced) {
-        Time tmpTime = new Time(goToTime);
-        long goToTimeInMillis = tmpTime.normalize(true); //TODO check on ignoreDst
-        int startDay = Time.getJulianDay(goToTimeInMillis, tmpTime.gmtoff);
+        int startDay = Time.getJulianDay(goToTime.toMillis(false), goToTime.gmtoff);
 
         if (!forced && isInRange(startDay, startDay)) {
             // No need to requery
@@ -546,12 +581,10 @@ public class AgendaWindowAdapter extends BaseAdapter {
         synchronized (mQueryQueue) {
             queuedQuery = false;
             Boolean doQueryNow = mQueryQueue.isEmpty();
-            if (!isInRange(queryData.start, queryData.end)) {
-                mQueryQueue.add(queryData);
-                queuedQuery = true;
-                if (doQueryNow) {
-                    doQuery(queryData);
-                }
+            mQueryQueue.add(queryData);
+            queuedQuery = true;
+            if (doQueryNow) {
+                doQuery(queryData);
             }
         }
         return queuedQuery;
@@ -672,12 +705,17 @@ public class AgendaWindowAdapter extends BaseAdapter {
                 int totalAgendaRangeEnd = -1;
 
                 if (cursorSize != 0) {
-                    // TODO check if it's same as "cookie"
                     // Remove the query that just completed
                     QuerySpec x = mQueryQueue.poll();
+                    if (BASICLOG && !x.equals(data)) {
+                        Log.e(TAG, "onQueryComplete - cookie != head of queue");
+                    }
                     mEmptyCursorCount = 0;
-                    mOlderRequests = mOlderRequestsProcessed;
-                    mNewerRequests = mNewerRequestsProcessed;
+                    if (data.queryType == QUERY_TYPE_NEWER) {
+                        mNewerRequestsProcessed++;
+                    } else if (data.queryType == QUERY_TYPE_OLDER) {
+                        mOlderRequestsProcessed++;
+                    }
 
                     totalAgendaRangeStart = mAdapterInfos.getFirst().start;
                     totalAgendaRangeEnd = mAdapterInfos.getLast().end;
@@ -747,7 +785,7 @@ public class AgendaWindowAdapter extends BaseAdapter {
                     }
                 }
             }
-            if (DEBUGLOG) {
+            if (BASICLOG) {
                 for (DayAdapterInfo info3 : mAdapterInfos) {
                     Log.e(TAG, "> " + info3.toString());
                 }
index f245c2b..b8078be 100644 (file)
@@ -16,8 +16,6 @@
 
 package com.android.calendar;
 
-import dalvik.system.VMRuntime;
-
 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -40,6 +38,8 @@ import android.view.animation.TranslateAnimation;
 import android.widget.ProgressBar;
 import android.widget.ViewSwitcher;
 
+import dalvik.system.VMRuntime;
+
 /**
  * This is the base class for Day and Week Activities.
  */
@@ -125,6 +125,16 @@ public class CalendarActivity extends Activity implements Navigator {
     }
 
     @Override
+    protected void onNewIntent(Intent intent) {
+        long timeMillis = Utils.timeFromIntentInMillis(intent);
+        if (timeMillis > 0) {
+            Time time = new Time();
+            time.set(timeMillis);
+            goTo(time);
+        }
+    }
+
+    @Override
     protected void onResume() {
         super.onResume();
         mEventLoader.startBackgroundThread();
@@ -249,7 +259,7 @@ public class CalendarActivity extends Activity implements Navigator {
         if (progress > 1.0f) {
             progress = 1.0f;
         }
-        
+
         float inFromXValue, inToXValue;
         float outFromXValue, outToXValue;
         if (forward) {
@@ -263,7 +273,7 @@ public class CalendarActivity extends Activity implements Navigator {
             outFromXValue = progress;
             outToXValue = 1.0f;
         }
-        
+
         // We have to allocate these animation objects each time we switch views
         // because that is the only way to set the animation parameters.
         TranslateAnimation inAnimation = new TranslateAnimation(
@@ -277,14 +287,14 @@ public class CalendarActivity extends Activity implements Navigator {
                 Animation.RELATIVE_TO_SELF, outToXValue,
                 Animation.ABSOLUTE, 0.0f,
                 Animation.ABSOLUTE, 0.0f);
-        
+
         // Reduce the animation duration based on how far we have already swiped.
         long duration = (long) (ANIMATION_DURATION * (1.0f - progress));
         inAnimation.setDuration(duration);
         outAnimation.setDuration(duration);
         mViewSwitcher.setInAnimation(inAnimation);
         mViewSwitcher.setOutAnimation(outAnimation);
-        
+
         CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
         view.cleanup();
         mViewSwitcher.showNext();
index 9bb8667..b06aa98 100644 (file)
@@ -258,6 +258,16 @@ public class MonthActivity extends Activity implements ViewSwitcher.ViewFactory,
     }
 
     @Override
+    protected void onNewIntent(Intent intent) {
+        long timeMillis = Utils.timeFromIntentInMillis(intent);
+        if (timeMillis > 0) {
+            Time time = new Time();
+            time.set(timeMillis);
+            goTo(time);
+        }
+    }
+
+    @Override
     protected void onPause() {
         super.onPause();
         if (isFinishing()) {
index 5899d3d..fbfcf34 100644 (file)
@@ -30,9 +30,7 @@ public class Utils {
 
         intent.setClassName(context, className);
         intent.putExtra(EVENT_BEGIN_TIME, time);
-        // TODO Setting this flag will cause the EVENT_BEGIN_TIME to be lost for existing activities
-        // Need to pass the EVENT_BEGIN_TIME via other methods or use another flag
-        // intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+        intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
 
         context.startActivity(intent);
     }
index 0e06b51..13fcfdb 100644 (file)
 
 package com.android.calendar;
 
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.text.format.Time;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.widget.ProgressBar;
@@ -55,6 +57,16 @@ public class WeekActivity extends CalendarActivity implements ViewSwitcher.ViewF
     }
 
     @Override
+    protected void onNewIntent(Intent intent) {
+        long timeMillis = Utils.timeFromIntentInMillis(intent);
+        if (timeMillis > 0) {
+            Time time = new Time();
+            time.set(timeMillis);
+            goTo(time);
+        }
+    }
+
+    @Override
     protected void onResume() {
         super.onResume();