1 /*
2  * Copyright (C) 2010 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.selectcalendars;
18 
19 import android.app.Activity;
20 import android.app.Fragment;
21 import android.content.ContentUris;
22 import android.content.ContentValues;
23 import android.database.Cursor;
24 import android.net.Uri;
25 import android.os.Bundle;
26 import android.provider.CalendarContract.Calendars;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 import android.view.ViewGroup;
30 import android.widget.AdapterView;
31 import android.widget.ListView;
32 
33 import com.android.calendar.AsyncQueryService;
34 import com.android.calendar.CalendarController;
35 import com.android.calendar.CalendarController.EventInfo;
36 import com.android.calendar.CalendarController.EventType;
37 import com.android.calendar.R;
38 import com.android.calendar.Utils;
39 import com.android.calendar.selectcalendars.CalendarColorCache.OnCalendarColorsLoadedListener;
40 
41 public class SelectVisibleCalendarsFragment extends Fragment
42         implements AdapterView.OnItemClickListener, CalendarController.EventHandler,
43         OnCalendarColorsLoadedListener {
44 
45     private static final String TAG = "Calendar";
46     private static final String IS_PRIMARY = "\"primary\"";
47     private static final String SELECTION = Calendars.SYNC_EVENTS + "=?";
48     private static final String[] SELECTION_ARGS = new String[] {"1"};
49 
50     private static final String[] PROJECTION = new String[] {
51         Calendars._ID,
52         Calendars.ACCOUNT_NAME,
53         Calendars.ACCOUNT_TYPE,
54         Calendars.OWNER_ACCOUNT,
55         Calendars.CALENDAR_DISPLAY_NAME,
56         Calendars.CALENDAR_COLOR,
57         Calendars.VISIBLE,
58         Calendars.SYNC_EVENTS,
59         "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + IS_PRIMARY,
60       };
61     private static int mUpdateToken;
62     private static int mQueryToken;
63     private static int mCalendarItemLayout = R.layout.mini_calendar_item;
64 
65     private View mView = null;
66     private CalendarController mController;
67     private ListView mList;
68     private SelectCalendarsSimpleAdapter mAdapter;
69     private Activity mContext;
70     private AsyncQueryService mService;
71     private Cursor mCursor;
72 
SelectVisibleCalendarsFragment()73     public SelectVisibleCalendarsFragment() {
74     }
75 
SelectVisibleCalendarsFragment(int itemLayout)76     public SelectVisibleCalendarsFragment(int itemLayout) {
77         mCalendarItemLayout = itemLayout;
78     }
79 
80     @Override
onAttach(Activity activity)81     public void onAttach(Activity activity) {
82         super.onAttach(activity);
83         mContext = activity;
84         mController = CalendarController.getInstance(activity);
85         mController.registerEventHandler(R.layout.select_calendars_fragment, this);
86         mService = new AsyncQueryService(activity) {
87             @Override
88             protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
89                 mAdapter.changeCursor(cursor);
90                 mCursor = cursor;
91             }
92         };
93     }
94 
95     @Override
onDetach()96     public void onDetach() {
97         super.onDetach();
98         mController.deregisterEventHandler(R.layout.select_calendars_fragment);
99         if (mCursor != null) {
100             mAdapter.changeCursor(null);
101             mCursor.close();
102             mCursor = null;
103         }
104     }
105 
106     @Override
onCreate(Bundle icicle)107     public void onCreate(Bundle icicle) {
108         super.onCreate(icicle);
109     }
110 
111     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)112     public View onCreateView(LayoutInflater inflater, ViewGroup container,
113             Bundle savedInstanceState) {
114         super.onCreateView(inflater, container, savedInstanceState);
115         mView = inflater.inflate(R.layout.select_calendars_fragment, null);
116         mList = (ListView)mView.findViewById(R.id.list);
117 
118         // Hide the Calendars to Sync button on tablets for now.
119         // Long terms stick it in the list of calendars
120         if (Utils.getConfigBool(getActivity(), R.bool.multiple_pane_config)) {
121             // Don't show dividers on tablets
122             mList.setDivider(null);
123             View v = mView.findViewById(R.id.manage_sync_set);
124             if (v != null) {
125                 v.setVisibility(View.GONE);
126             }
127         }
128         return mView;
129     }
130 
131     @Override
onActivityCreated(Bundle savedInstanceState)132     public void onActivityCreated(Bundle savedInstanceState) {
133         super.onActivityCreated(savedInstanceState);
134         mAdapter = new SelectCalendarsSimpleAdapter(mContext, mCalendarItemLayout, null,
135                 getFragmentManager());
136         mList.setAdapter(mAdapter);
137         mList.setOnItemClickListener(this);
138     }
139 
onItemClick(AdapterView<?> parent, View view, int position, long id)140     public void onItemClick(AdapterView<?> parent, View view, int position, long id)  {
141         if (mAdapter == null || mAdapter.getCount() <= position) {
142             return;
143         }
144         toggleVisibility(position);
145     }
146 
147     @Override
onResume()148     public void onResume() {
149         super.onResume();
150         mQueryToken = mService.getNextToken();
151         mService.startQuery(mQueryToken, null, Calendars.CONTENT_URI, PROJECTION, SELECTION,
152                 SELECTION_ARGS, Calendars.ACCOUNT_NAME);
153     }
154 
155     /*
156      * Write back the changes that have been made.
157      */
toggleVisibility(int position)158     public void toggleVisibility(int position) {
159         mUpdateToken = mService.getNextToken();
160         Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, mAdapter.getItemId(position));
161         ContentValues values = new ContentValues();
162         // Toggle the current setting
163         int visibility = mAdapter.getVisible(position)^1;
164         values.put(Calendars.VISIBLE, visibility);
165         mService.startUpdate(mUpdateToken, null, uri, values, null, null, 0);
166         mAdapter.setVisible(position, visibility);
167     }
168 
169     @Override
eventsChanged()170     public void eventsChanged() {
171         if (mService != null) {
172             mService.cancelOperation(mQueryToken);
173             mQueryToken = mService.getNextToken();
174             mService.startQuery(mQueryToken, null, Calendars.CONTENT_URI, PROJECTION, SELECTION,
175                     SELECTION_ARGS, Calendars.ACCOUNT_NAME);
176         }
177     }
178 
179     @Override
getSupportedEventTypes()180     public long getSupportedEventTypes() {
181         return EventType.EVENTS_CHANGED;
182     }
183 
184     @Override
handleEvent(EventInfo event)185     public void handleEvent(EventInfo event) {
186         eventsChanged();
187     }
188 
189     @Override
onCalendarColorsLoaded()190     public void onCalendarColorsLoaded() {
191         if (mAdapter != null) {
192             mAdapter.notifyDataSetChanged();
193         }
194     }
195 }
196