1e5a8f94f935248dea9e515199151472eebe5ca4cErik/*
2e5a8f94f935248dea9e515199151472eebe5ca4cErik * Copyright (C) 2010 The Android Open Source Project
3e5a8f94f935248dea9e515199151472eebe5ca4cErik *
4e5a8f94f935248dea9e515199151472eebe5ca4cErik * Licensed under the Apache License, Version 2.0 (the "License");
5e5a8f94f935248dea9e515199151472eebe5ca4cErik * you may not use this file except in compliance with the License.
6e5a8f94f935248dea9e515199151472eebe5ca4cErik * You may obtain a copy of the License at
7e5a8f94f935248dea9e515199151472eebe5ca4cErik *
8e5a8f94f935248dea9e515199151472eebe5ca4cErik *      http://www.apache.org/licenses/LICENSE-2.0
9e5a8f94f935248dea9e515199151472eebe5ca4cErik *
10e5a8f94f935248dea9e515199151472eebe5ca4cErik * Unless required by applicable law or agreed to in writing, software
11e5a8f94f935248dea9e515199151472eebe5ca4cErik * distributed under the License is distributed on an "AS IS" BASIS,
12e5a8f94f935248dea9e515199151472eebe5ca4cErik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5a8f94f935248dea9e515199151472eebe5ca4cErik * See the License for the specific language governing permissions and
14e5a8f94f935248dea9e515199151472eebe5ca4cErik * limitations under the License.
15e5a8f94f935248dea9e515199151472eebe5ca4cErik */
16e5a8f94f935248dea9e515199151472eebe5ca4cErik
179a3cb14e28536e4133dddbe952f47189fe344ec1Mason Tangpackage com.android.calendar.selectcalendars;
18e5a8f94f935248dea9e515199151472eebe5ca4cErik
19975940b44da39c68805df6d08012374f3fa35969Erikimport com.android.calendar.AsyncQueryService;
208d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErikimport com.android.calendar.CalendarController.EventInfo;
218d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErikimport com.android.calendar.CalendarController.EventType;
22e5a8f94f935248dea9e515199151472eebe5ca4cErikimport com.android.calendar.R;
238d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErikimport com.android.calendar.CalendarController;
24bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chanimport com.android.calendar.Utils;
25e5a8f94f935248dea9e515199151472eebe5ca4cErik
26e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.app.Activity;
27e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.app.Fragment;
28975940b44da39c68805df6d08012374f3fa35969Erikimport android.content.ContentUris;
29975940b44da39c68805df6d08012374f3fa35969Erikimport android.content.ContentValues;
30e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.database.Cursor;
31975940b44da39c68805df6d08012374f3fa35969Erikimport android.net.Uri;
32e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.os.Bundle;
33a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars;
34975940b44da39c68805df6d08012374f3fa35969Erikimport android.util.Log;
35e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.view.LayoutInflater;
36e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.view.View;
37e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.view.ViewGroup;
38e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.widget.AdapterView;
39e5a8f94f935248dea9e515199151472eebe5ca4cErikimport android.widget.ListView;
40e5a8f94f935248dea9e515199151472eebe5ca4cErik
412aeb8d988aa4b65d3402374832613ab977e009dcMichael Chanpublic class SelectVisibleCalendarsFragment extends Fragment
428d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik        implements AdapterView.OnItemClickListener, CalendarController.EventHandler {
43e5a8f94f935248dea9e515199151472eebe5ca4cErik
44e5a8f94f935248dea9e515199151472eebe5ca4cErik    private static final String TAG = "Calendar";
45e5a8f94f935248dea9e515199151472eebe5ca4cErik    private static final String IS_PRIMARY = "\"primary\"";
46975940b44da39c68805df6d08012374f3fa35969Erik    private static final String SELECTION = Calendars.SYNC_EVENTS + "=?";
47975940b44da39c68805df6d08012374f3fa35969Erik    private static final String[] SELECTION_ARGS = new String[] {"1"};
48e5a8f94f935248dea9e515199151472eebe5ca4cErik
49e5a8f94f935248dea9e515199151472eebe5ca4cErik    private static final String[] PROJECTION = new String[] {
50e5a8f94f935248dea9e515199151472eebe5ca4cErik        Calendars._ID,
510e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik        Calendars.ACCOUNT_NAME,
52e5a8f94f935248dea9e515199151472eebe5ca4cErik        Calendars.OWNER_ACCOUNT,
53ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik        Calendars.CALENDAR_DISPLAY_NAME,
540e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik        Calendars.CALENDAR_COLOR,
55950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden        Calendars.VISIBLE,
56e5a8f94f935248dea9e515199151472eebe5ca4cErik        Calendars.SYNC_EVENTS,
570e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik        "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + IS_PRIMARY,
58e5a8f94f935248dea9e515199151472eebe5ca4cErik      };
59975940b44da39c68805df6d08012374f3fa35969Erik    private static int mUpdateToken;
60975940b44da39c68805df6d08012374f3fa35969Erik    private static int mQueryToken;
612aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan    private static int mCalendarItemLayout = R.layout.mini_calendar_item;
62975940b44da39c68805df6d08012374f3fa35969Erik
63975940b44da39c68805df6d08012374f3fa35969Erik    private View mView = null;
64975940b44da39c68805df6d08012374f3fa35969Erik    private ListView mList;
65975940b44da39c68805df6d08012374f3fa35969Erik    private SelectCalendarsSimpleAdapter mAdapter;
66975940b44da39c68805df6d08012374f3fa35969Erik    private Activity mContext;
67975940b44da39c68805df6d08012374f3fa35969Erik    private AsyncQueryService mService;
68ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan    private Cursor mCursor;
69e5a8f94f935248dea9e515199151472eebe5ca4cErik
702aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan    public SelectVisibleCalendarsFragment() {
712aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan    }
722aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan
732aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan    public SelectVisibleCalendarsFragment(int itemLayout) {
742aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan        mCalendarItemLayout = itemLayout;
752aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan    }
762aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan
77e5a8f94f935248dea9e515199151472eebe5ca4cErik    @Override
78e5a8f94f935248dea9e515199151472eebe5ca4cErik    public void onAttach(Activity activity) {
79e5a8f94f935248dea9e515199151472eebe5ca4cErik        super.onAttach(activity);
80e5a8f94f935248dea9e515199151472eebe5ca4cErik        mContext = activity;
81975940b44da39c68805df6d08012374f3fa35969Erik        mService = new AsyncQueryService(activity) {
82975940b44da39c68805df6d08012374f3fa35969Erik            @Override
83975940b44da39c68805df6d08012374f3fa35969Erik            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
84975940b44da39c68805df6d08012374f3fa35969Erik                mAdapter.changeCursor(cursor);
85ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan                mCursor = cursor;
86975940b44da39c68805df6d08012374f3fa35969Erik            }
87975940b44da39c68805df6d08012374f3fa35969Erik        };
88e5a8f94f935248dea9e515199151472eebe5ca4cErik    }
89e5a8f94f935248dea9e515199151472eebe5ca4cErik
90e5a8f94f935248dea9e515199151472eebe5ca4cErik    @Override
91ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan    public void onDetach() {
92ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan        super.onDetach();
93ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan        if (mCursor != null) {
94ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan            mAdapter.changeCursor(null);
95ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan            mCursor.close();
96ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan            mCursor = null;
97ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan        }
98ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan    }
99ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan
100ecdf3ae3d740fa12628b4abd8931dd7e1db350eeMichael Chan    @Override
101e5a8f94f935248dea9e515199151472eebe5ca4cErik    public void onCreate(Bundle icicle) {
102e5a8f94f935248dea9e515199151472eebe5ca4cErik        super.onCreate(icicle);
103e5a8f94f935248dea9e515199151472eebe5ca4cErik    }
104e5a8f94f935248dea9e515199151472eebe5ca4cErik
105e5a8f94f935248dea9e515199151472eebe5ca4cErik    @Override
106e5a8f94f935248dea9e515199151472eebe5ca4cErik    public View onCreateView(LayoutInflater inflater, ViewGroup container,
107e5a8f94f935248dea9e515199151472eebe5ca4cErik            Bundle savedInstanceState) {
108975940b44da39c68805df6d08012374f3fa35969Erik        super.onCreateView(inflater, container, savedInstanceState);
1093458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        mView = inflater.inflate(R.layout.select_calendars_fragment, null);
110975940b44da39c68805df6d08012374f3fa35969Erik        mList = (ListView)mView.findViewById(R.id.list);
111bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chan
112bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chan        // Hide the Calendars to Sync button on tablets for now.
113bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chan        // Long terms stick it in the list of calendars
1147ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        if (Utils.getConfigBool(getActivity(), R.bool.multiple_pane_config)) {
115407a8fa63fee1d39bea38f001977a3dec744cb3dRoboErik            // Don't show dividers on tablets
116407a8fa63fee1d39bea38f001977a3dec744cb3dRoboErik            mList.setDivider(null);
117bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chan            View v = mView.findViewById(R.id.manage_sync_set);
118bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chan            if (v != null) {
119bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chan                v.setVisibility(View.GONE);
120bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chan            }
121bd0bd53b8808dd54ce51b9fc0f371f635f9d4a26Michael Chan        }
122975940b44da39c68805df6d08012374f3fa35969Erik        return mView;
123975940b44da39c68805df6d08012374f3fa35969Erik    }
124e5a8f94f935248dea9e515199151472eebe5ca4cErik
125975940b44da39c68805df6d08012374f3fa35969Erik    @Override
126975940b44da39c68805df6d08012374f3fa35969Erik    public void onActivityCreated(Bundle savedInstanceState) {
127975940b44da39c68805df6d08012374f3fa35969Erik        super.onActivityCreated(savedInstanceState);
1282aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan        mAdapter = new SelectCalendarsSimpleAdapter(mContext, mCalendarItemLayout, null);
129e5a8f94f935248dea9e515199151472eebe5ca4cErik        mList.setAdapter(mAdapter);
130e5a8f94f935248dea9e515199151472eebe5ca4cErik        mList.setOnItemClickListener(this);
131e5a8f94f935248dea9e515199151472eebe5ca4cErik    }
132e5a8f94f935248dea9e515199151472eebe5ca4cErik
133975940b44da39c68805df6d08012374f3fa35969Erik    public void onItemClick(AdapterView<?> parent, View view, int position, long id)  {
134975940b44da39c68805df6d08012374f3fa35969Erik        if (mAdapter == null || mAdapter.getCount() <= position) {
135975940b44da39c68805df6d08012374f3fa35969Erik            return;
136975940b44da39c68805df6d08012374f3fa35969Erik        }
137975940b44da39c68805df6d08012374f3fa35969Erik        toggleVisibility(position);
138975940b44da39c68805df6d08012374f3fa35969Erik    }
139e5a8f94f935248dea9e515199151472eebe5ca4cErik
140975940b44da39c68805df6d08012374f3fa35969Erik    @Override
141975940b44da39c68805df6d08012374f3fa35969Erik    public void onResume() {
142975940b44da39c68805df6d08012374f3fa35969Erik        super.onResume();
143975940b44da39c68805df6d08012374f3fa35969Erik        mQueryToken = mService.getNextToken();
144975940b44da39c68805df6d08012374f3fa35969Erik        mService.startQuery(mQueryToken, null, Calendars.CONTENT_URI, PROJECTION, SELECTION,
1450e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik                SELECTION_ARGS, Calendars.ACCOUNT_NAME);
146e5a8f94f935248dea9e515199151472eebe5ca4cErik    }
147e5a8f94f935248dea9e515199151472eebe5ca4cErik
148e5a8f94f935248dea9e515199151472eebe5ca4cErik    /*
149975940b44da39c68805df6d08012374f3fa35969Erik     * Write back the changes that have been made.
150e5a8f94f935248dea9e515199151472eebe5ca4cErik     */
151975940b44da39c68805df6d08012374f3fa35969Erik    public void toggleVisibility(int position) {
152975940b44da39c68805df6d08012374f3fa35969Erik        Log.d(TAG, "Toggling calendar at " + position);
153975940b44da39c68805df6d08012374f3fa35969Erik        mUpdateToken = mService.getNextToken();
154975940b44da39c68805df6d08012374f3fa35969Erik        Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, mAdapter.getItemId(position));
155975940b44da39c68805df6d08012374f3fa35969Erik        ContentValues values = new ContentValues();
156975940b44da39c68805df6d08012374f3fa35969Erik        // Toggle the current setting
157975940b44da39c68805df6d08012374f3fa35969Erik        int visibility = mAdapter.getVisible(position)^1;
158950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden        values.put(Calendars.VISIBLE, visibility);
159975940b44da39c68805df6d08012374f3fa35969Erik        mService.startUpdate(mUpdateToken, null, uri, values, null, null, 0);
160975940b44da39c68805df6d08012374f3fa35969Erik        mAdapter.setVisible(position, visibility);
161e5a8f94f935248dea9e515199151472eebe5ca4cErik    }
1628d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik
1638d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    @Override
1648d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    public void eventsChanged() {
1658d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik        if (mService != null) {
1668d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik            mService.cancelOperation(mQueryToken);
1678d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik            mQueryToken = mService.getNextToken();
1688d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik            mService.startQuery(mQueryToken, null, Calendars.CONTENT_URI, PROJECTION, SELECTION,
1690e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik                    SELECTION_ARGS, Calendars.ACCOUNT_NAME);
1708d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik        }
1718d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    }
1728d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik
1738d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    @Override
1748d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    public long getSupportedEventTypes() {
1758d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik        return EventType.EVENTS_CHANGED;
1768d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    }
1778d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik
1788d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    @Override
1798d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    public void handleEvent(EventInfo event) {
1808d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik        if (event.eventType == EventType.EVENTS_CHANGED) {
1818d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik            eventsChanged();
1828d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik        }
1838d1b2fd416920c5462189ad38c2b4da96ac26b87RoboErik    }
1843458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan}
185