• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 
17 package com.android.calendar;
18 
19 import android.content.ContentUris;
20 import android.content.Intent;
21 import android.graphics.Rect;
22 import android.net.Uri;
23 import android.provider.Calendar;
24 import android.provider.Calendar.Events;
25 import android.text.format.Time;
26 import android.util.Log;
27 import android.view.View;
28 import android.widget.AdapterView;
29 import android.widget.ListView;
30 import android.widget.TextView;
31 import android.widget.AdapterView.OnItemClickListener;
32 
33 import com.android.calendar.AgendaAdapter.ViewHolder;
34 import com.android.calendar.AgendaWindowAdapter.EventInfo;
35 
36 public class AgendaListView extends ListView implements OnItemClickListener {
37 
38     private static final String TAG = "AgendaListView";
39     private static final boolean DEBUG = false;
40 
41     private AgendaWindowAdapter mWindowAdapter;
42 
43     private AgendaActivity mAgendaActivity;
44     private DeleteEventHelper mDeleteEventHelper;
45 
AgendaListView(AgendaActivity agendaActivity)46     public AgendaListView(AgendaActivity agendaActivity) {
47         super(agendaActivity, null);
48         mAgendaActivity = agendaActivity;
49         mContext = agendaActivity;
50 
51         setOnItemClickListener(this);
52         setChoiceMode(ListView.CHOICE_MODE_SINGLE);
53         setVerticalScrollBarEnabled(false);
54         mWindowAdapter = new AgendaWindowAdapter(agendaActivity, this);
55         setAdapter(mWindowAdapter);
56         mDeleteEventHelper =
57             new DeleteEventHelper(agendaActivity, false /* don't exit when done */);
58     }
59 
onDetachedFromWindow()60     @Override protected void onDetachedFromWindow() {
61         super.onDetachedFromWindow();
62         mWindowAdapter.close();
63     }
64 
65     // Implementation of the interface OnItemClickListener
onItemClick(AdapterView<?> a, View v, int position, long id)66     public void onItemClick(AdapterView<?> a, View v, int position, long id) {
67         if (id != -1) {
68             // Switch to the EventInfo view
69             EventInfo event = mWindowAdapter.getEventByPosition(position);
70             if (event != null) {
71                 Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, event.id);
72                 Intent intent = new Intent(Intent.ACTION_VIEW, uri);
73                 intent.putExtra(Calendar.EVENT_BEGIN_TIME, event.begin);
74                 intent.putExtra(Calendar.EVENT_END_TIME, event.end);
75                 mAgendaActivity.startActivity(intent);
76             }
77         }
78     }
79 
goTo(Time time, boolean forced)80     public void goTo(Time time, boolean forced) {
81         mWindowAdapter.refresh(time, forced);
82     }
83 
refresh(boolean forced)84     public void refresh(boolean forced) {
85         Time time = new Time();
86         long goToTime = getFirstVisibleTime();
87         if (goToTime <= 0) {
88             goToTime = System.currentTimeMillis();
89         }
90         time.set(goToTime);
91         mWindowAdapter.refresh(time, forced);
92     }
93 
deleteSelectedEvent()94     public void deleteSelectedEvent() {
95         int position = getSelectedItemPosition();
96         EventInfo event = mWindowAdapter.getEventByPosition(position);
97         if (event != null) {
98             mDeleteEventHelper.delete(event.begin, event.end, event.id, -1);
99         }
100     }
101 
102     @Override
getFirstVisiblePosition()103     public int getFirstVisiblePosition() {
104         // TODO File bug!
105         // getFirstVisiblePosition doesn't always return the first visible
106         // item. Sometimes, it is above the visible one.
107         // instead. I loop through the viewgroup children and find the first
108         // visible one. BTW, getFirstVisiblePosition() == getChildAt(0). I
109         // am not looping through the entire list.
110        View v = getFirstVisibleView();
111        if (v != null) {
112            if (DEBUG) {
113                Log.v(TAG, "getFirstVisiblePosition: " + AgendaWindowAdapter.getViewTitle(v));
114            }
115            return getPositionForView(v);
116        }
117        return -1;
118     }
119 
getFirstVisibleView()120     public View getFirstVisibleView() {
121         Rect r = new Rect();
122         int childCount = getChildCount();
123         for (int i = 0; i < childCount; ++i) {
124             View listItem = getChildAt(i);
125             listItem.getLocalVisibleRect(r);
126             if (r.top >= 0) { // if visible
127                 return listItem;
128             }
129         }
130         return null;
131     }
132 
getSelectedTime()133     public long getSelectedTime() {
134         int position = getSelectedItemPosition();
135         if (position >= 0) {
136             EventInfo event = mWindowAdapter.getEventByPosition(position);
137             if (event != null) {
138                 return event.begin;
139             }
140         }
141         return getFirstVisibleTime();
142     }
143 
getFirstVisibleTime()144     public long getFirstVisibleTime() {
145         int position = getFirstVisiblePosition();
146         if (DEBUG) {
147             Log.v(TAG, "getFirstVisiblePosition = " + position);
148         }
149 
150         EventInfo event = mWindowAdapter.getEventByPosition(position);
151         if (event != null) {
152             return event.begin;
153         }
154         return 0;
155     }
156 
157     // Move the currently selected or visible focus down by offset amount.
158     // offset could be negative.
shiftSelection(int offset)159     public void shiftSelection(int offset) {
160         shiftPosition(offset);
161         int position = getSelectedItemPosition();
162         if (position != INVALID_POSITION) {
163             setSelectionFromTop(position + offset, 0);
164         }
165     }
166 
shiftPosition(int offset)167     private void shiftPosition(int offset) {
168         if (DEBUG) {
169             Log.v(TAG, "Shifting position "+ offset);
170         }
171 
172         View firstVisibleItem = getFirstVisibleView();
173 
174         if (firstVisibleItem != null) {
175             Rect r = new Rect();
176             firstVisibleItem.getLocalVisibleRect(r);
177             // if r.top is < 0, getChildAt(0) and getFirstVisiblePosition() is
178             // returning an item above the first visible item.
179             int position = getPositionForView(firstVisibleItem);
180             setSelectionFromTop(position + offset, r.top > 0 ? -r.top : r.top);
181             if (DEBUG) {
182                 if (firstVisibleItem.getTag() instanceof AgendaAdapter.ViewHolder) {
183                     ViewHolder viewHolder = (AgendaAdapter.ViewHolder)firstVisibleItem.getTag();
184                     Log.v(TAG, "Shifting from " + position + " by " + offset + ". Title "
185                             + viewHolder.title.getText());
186                 } else if (firstVisibleItem.getTag() instanceof AgendaByDayAdapter.ViewHolder) {
187                     AgendaByDayAdapter.ViewHolder viewHolder =
188                         (AgendaByDayAdapter.ViewHolder)firstVisibleItem.getTag();
189                     Log.v(TAG, "Shifting from " + position + " by " + offset + ". Date  "
190                             + viewHolder.dateView.getText());
191                 } else if (firstVisibleItem instanceof TextView) {
192                     Log.v(TAG, "Shifting: Looking at header here. " + getSelectedItemPosition());
193                 }
194             }
195         } else if (getSelectedItemPosition() >= 0) {
196             if (DEBUG) {
197                 Log.v(TAG, "Shifting selection from " + getSelectedItemPosition() + " by " + offset);
198             }
199             setSelection(getSelectedItemPosition() + offset);
200         }
201     }
202 
setHideDeclinedEvents(boolean hideDeclined)203     public void setHideDeclinedEvents(boolean hideDeclined) {
204         mWindowAdapter.setHideDeclinedEvents(hideDeclined);
205     }
206 
onResume()207     public void onResume() {
208         mWindowAdapter.notifyDataSetChanged();
209     }
onPause()210     public void onPause() {
211         mWindowAdapter.notifyDataSetInvalidated();
212     }
213 }
214