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