<!-- 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. -->
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.view.Menu;
import android.view.MenuItem;
+import dalvik.system.VMRuntime;
+
public class AgendaActivity extends Activity implements Navigator {
private static final String TAG = "AgendaActivity";
// 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());
}
}
}
@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) {
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 {
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 {
| 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) {
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;
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";
setOnItemClickListener(this);
setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ setVerticalScrollBarEnabled(false);
mWindowAdapter = new AgendaWindowAdapter(agendaActivity, this);
setAdapter(mWindowAdapter);
mDeleteEventHelper =
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);
}
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() {
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;
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.
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";
// 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;
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 {
}
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
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;
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;
}
}
}
- if (DEBUGLOG) {
+ if (BASICLOG) {
for (DayAdapterInfo info3 : mAdapterInfos) {
Log.e(TAG, "> " + info3.toString());
}
package com.android.calendar;
-import dalvik.system.VMRuntime;
-
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.widget.ProgressBar;
import android.widget.ViewSwitcher;
+import dalvik.system.VMRuntime;
+
/**
* This is the base class for Day and Week Activities.
*/
}
@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();
if (progress > 1.0f) {
progress = 1.0f;
}
-
+
float inFromXValue, inToXValue;
float outFromXValue, outToXValue;
if (forward) {
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(
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();
}
@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()) {
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);
}
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;
}
@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();