16b858fc6f8afad95a075595016c5c22547924886Erik/*
26b858fc6f8afad95a075595016c5c22547924886Erik * Copyright (C) 2010 The Android Open Source Project
36b858fc6f8afad95a075595016c5c22547924886Erik *
46b858fc6f8afad95a075595016c5c22547924886Erik * Licensed under the Apache License, Version 2.0 (the "License");
56b858fc6f8afad95a075595016c5c22547924886Erik * you may not use this file except in compliance with the License.
66b858fc6f8afad95a075595016c5c22547924886Erik * You may obtain a copy of the License at
76b858fc6f8afad95a075595016c5c22547924886Erik *
86b858fc6f8afad95a075595016c5c22547924886Erik *      http://www.apache.org/licenses/LICENSE-2.0
96b858fc6f8afad95a075595016c5c22547924886Erik *
106b858fc6f8afad95a075595016c5c22547924886Erik * Unless required by applicable law or agreed to in writing, software
116b858fc6f8afad95a075595016c5c22547924886Erik * distributed under the License is distributed on an "AS IS" BASIS,
126b858fc6f8afad95a075595016c5c22547924886Erik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b858fc6f8afad95a075595016c5c22547924886Erik * See the License for the specific language governing permissions and
146b858fc6f8afad95a075595016c5c22547924886Erik * limitations under the License.
156b858fc6f8afad95a075595016c5c22547924886Erik */
166b858fc6f8afad95a075595016c5c22547924886Erik
176b858fc6f8afad95a075595016c5c22547924886Erikpackage com.android.calendar.selectcalendars;
186b858fc6f8afad95a075595016c5c22547924886Erik
196b858fc6f8afad95a075595016c5c22547924886Erikimport com.android.calendar.AsyncQueryService;
206b858fc6f8afad95a075595016c5c22547924886Erikimport com.android.calendar.R;
216b858fc6f8afad95a075595016c5c22547924886Erikimport com.android.calendar.selectcalendars.SelectCalendarsSyncAdapter.CalendarRow;
226b858fc6f8afad95a075595016c5c22547924886Erik
236b858fc6f8afad95a075595016c5c22547924886Erikimport android.accounts.Account;
246b858fc6f8afad95a075595016c5c22547924886Erikimport android.app.Activity;
256b858fc6f8afad95a075595016c5c22547924886Erikimport android.app.ListFragment;
266b858fc6f8afad95a075595016c5c22547924886Erikimport android.app.LoaderManager;
276b858fc6f8afad95a075595016c5c22547924886Erikimport android.content.ContentResolver;
286b858fc6f8afad95a075595016c5c22547924886Erikimport android.content.ContentUris;
296b858fc6f8afad95a075595016c5c22547924886Erikimport android.content.ContentValues;
306b858fc6f8afad95a075595016c5c22547924886Erikimport android.content.CursorLoader;
316b858fc6f8afad95a075595016c5c22547924886Erikimport android.content.Intent;
326b858fc6f8afad95a075595016c5c22547924886Erikimport android.content.Loader;
336b858fc6f8afad95a075595016c5c22547924886Erikimport android.content.res.Resources;
346b858fc6f8afad95a075595016c5c22547924886Erikimport android.database.Cursor;
356b858fc6f8afad95a075595016c5c22547924886Erikimport android.net.Uri;
366b858fc6f8afad95a075595016c5c22547924886Erikimport android.os.Bundle;
37a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract;
38a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars;
396b858fc6f8afad95a075595016c5c22547924886Erikimport android.view.LayoutInflater;
406b858fc6f8afad95a075595016c5c22547924886Erikimport android.view.View;
416b858fc6f8afad95a075595016c5c22547924886Erikimport android.view.ViewGroup;
426b858fc6f8afad95a075595016c5c22547924886Erikimport android.widget.Button;
43c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chanimport android.widget.ListAdapter;
446b858fc6f8afad95a075595016c5c22547924886Erikimport android.widget.TextView;
456b858fc6f8afad95a075595016c5c22547924886Erik
466b858fc6f8afad95a075595016c5c22547924886Erikimport java.util.HashMap;
476b858fc6f8afad95a075595016c5c22547924886Erik
486b858fc6f8afad95a075595016c5c22547924886Erikpublic class SelectCalendarsSyncFragment extends ListFragment
496b858fc6f8afad95a075595016c5c22547924886Erik        implements View.OnClickListener, LoaderManager.LoaderCallbacks<Cursor> {
506b858fc6f8afad95a075595016c5c22547924886Erik    private static final String TAG = "SelectCalendarSync";
516b858fc6f8afad95a075595016c5c22547924886Erik
526b858fc6f8afad95a075595016c5c22547924886Erik    private static final String COLLATE_NOCASE = " COLLATE NOCASE";
530e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik    private static final String SELECTION = Calendars.ACCOUNT_NAME + "=? AND "
540e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik            + Calendars.ACCOUNT_TYPE + "=?";
556b858fc6f8afad95a075595016c5c22547924886Erik    // is primary lets us sort the user's main calendar to the top of the list
566b858fc6f8afad95a075595016c5c22547924886Erik    private static final String IS_PRIMARY = "\"primary\"";
57ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik    private static final String SORT_ORDER = IS_PRIMARY + " DESC," + Calendars.CALENDAR_DISPLAY_NAME
586b858fc6f8afad95a075595016c5c22547924886Erik            + COLLATE_NOCASE;
596b858fc6f8afad95a075595016c5c22547924886Erik
60cf7fd2b6d1b5af26c4ac422dde1778e2fd6c7ef6Michael Chan    private static final String[] PROJECTION = new String[] {
61cf7fd2b6d1b5af26c4ac422dde1778e2fd6c7ef6Michael Chan        Calendars._ID,
62cf7fd2b6d1b5af26c4ac422dde1778e2fd6c7ef6Michael Chan        Calendars.CALENDAR_DISPLAY_NAME,
63cf7fd2b6d1b5af26c4ac422dde1778e2fd6c7ef6Michael Chan        Calendars.CALENDAR_COLOR,
64cf7fd2b6d1b5af26c4ac422dde1778e2fd6c7ef6Michael Chan        Calendars.SYNC_EVENTS,
65cf7fd2b6d1b5af26c4ac422dde1778e2fd6c7ef6Michael Chan        "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + IS_PRIMARY, };
666b858fc6f8afad95a075595016c5c22547924886Erik
676b858fc6f8afad95a075595016c5c22547924886Erik    private TextView mSyncStatus;
686b858fc6f8afad95a075595016c5c22547924886Erik    private Button mAccountsButton;
696b858fc6f8afad95a075595016c5c22547924886Erik    private Account mAccount;
706b858fc6f8afad95a075595016c5c22547924886Erik    private String[] mArgs = new String[2];
716b858fc6f8afad95a075595016c5c22547924886Erik    private AsyncQueryService mService;
726b858fc6f8afad95a075595016c5c22547924886Erik
736b858fc6f8afad95a075595016c5c22547924886Erik    public SelectCalendarsSyncFragment() {
746b858fc6f8afad95a075595016c5c22547924886Erik    }
756b858fc6f8afad95a075595016c5c22547924886Erik
766b858fc6f8afad95a075595016c5c22547924886Erik    public SelectCalendarsSyncFragment(Bundle bundle) {
770e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik        mAccount = new Account(bundle.getString(Calendars.ACCOUNT_NAME),
780e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik                bundle.getString(Calendars.ACCOUNT_TYPE));
796b858fc6f8afad95a075595016c5c22547924886Erik    }
806b858fc6f8afad95a075595016c5c22547924886Erik
816b858fc6f8afad95a075595016c5c22547924886Erik    @Override
826b858fc6f8afad95a075595016c5c22547924886Erik    public View onCreateView(
836b858fc6f8afad95a075595016c5c22547924886Erik            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
846b858fc6f8afad95a075595016c5c22547924886Erik        View v = inflater.inflate(R.layout.account_calendars, null);
856b858fc6f8afad95a075595016c5c22547924886Erik        mSyncStatus = (TextView) v.findViewById(R.id.account_status);
866b858fc6f8afad95a075595016c5c22547924886Erik        mSyncStatus.setVisibility(View.GONE);
876b858fc6f8afad95a075595016c5c22547924886Erik
886b858fc6f8afad95a075595016c5c22547924886Erik        mAccountsButton = (Button) v.findViewById(R.id.sync_settings);
896b858fc6f8afad95a075595016c5c22547924886Erik        mAccountsButton.setVisibility(View.GONE);
906b858fc6f8afad95a075595016c5c22547924886Erik        mAccountsButton.setOnClickListener(this);
916b858fc6f8afad95a075595016c5c22547924886Erik
926b858fc6f8afad95a075595016c5c22547924886Erik        return v;
936b858fc6f8afad95a075595016c5c22547924886Erik    }
946b858fc6f8afad95a075595016c5c22547924886Erik
956b858fc6f8afad95a075595016c5c22547924886Erik    @Override
966b858fc6f8afad95a075595016c5c22547924886Erik    public void onActivityCreated(Bundle savedInstanceState) {
976b858fc6f8afad95a075595016c5c22547924886Erik        super.onActivityCreated(savedInstanceState);
986b858fc6f8afad95a075595016c5c22547924886Erik        // Give some text to display if there is no data. In a real
996b858fc6f8afad95a075595016c5c22547924886Erik        // application this would come from a resource.
1006b858fc6f8afad95a075595016c5c22547924886Erik        setEmptyText(getActivity().getText(R.string.no_syncable_calendars));
1016b858fc6f8afad95a075595016c5c22547924886Erik        // Prepare the loader. Either re-connect with an existing one,
1026b858fc6f8afad95a075595016c5c22547924886Erik        // or start a new one.
1036b858fc6f8afad95a075595016c5c22547924886Erik        getLoaderManager().initLoader(0, null, this);
1046b858fc6f8afad95a075595016c5c22547924886Erik    }
1056b858fc6f8afad95a075595016c5c22547924886Erik
1066b858fc6f8afad95a075595016c5c22547924886Erik    @Override
1076b858fc6f8afad95a075595016c5c22547924886Erik    public void onResume() {
1086b858fc6f8afad95a075595016c5c22547924886Erik        super.onResume();
1096b858fc6f8afad95a075595016c5c22547924886Erik        if (!ContentResolver.getMasterSyncAutomatically()
110a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik                || !ContentResolver.getSyncAutomatically(mAccount, CalendarContract.AUTHORITY)) {
1116b858fc6f8afad95a075595016c5c22547924886Erik            Resources res = getActivity().getResources();
1126b858fc6f8afad95a075595016c5c22547924886Erik            mSyncStatus.setText(res.getString(R.string.acct_not_synced));
1136b858fc6f8afad95a075595016c5c22547924886Erik            mSyncStatus.setVisibility(View.VISIBLE);
1146b858fc6f8afad95a075595016c5c22547924886Erik            mAccountsButton.setText(res.getString(R.string.accounts));
1156b858fc6f8afad95a075595016c5c22547924886Erik            mAccountsButton.setVisibility(View.VISIBLE);
1166b858fc6f8afad95a075595016c5c22547924886Erik        } else {
1176b858fc6f8afad95a075595016c5c22547924886Erik            mSyncStatus.setVisibility(View.GONE);
1186b858fc6f8afad95a075595016c5c22547924886Erik            mAccountsButton.setVisibility(View.GONE);
1196b858fc6f8afad95a075595016c5c22547924886Erik        }
1206b858fc6f8afad95a075595016c5c22547924886Erik    }
1216b858fc6f8afad95a075595016c5c22547924886Erik
1226b858fc6f8afad95a075595016c5c22547924886Erik    @Override
1236b858fc6f8afad95a075595016c5c22547924886Erik    public void onAttach(Activity activity) {
1246b858fc6f8afad95a075595016c5c22547924886Erik        super.onAttach(activity);
1256b858fc6f8afad95a075595016c5c22547924886Erik        mService = new AsyncQueryService(activity);
1266b858fc6f8afad95a075595016c5c22547924886Erik
1276b858fc6f8afad95a075595016c5c22547924886Erik        Bundle bundle = getArguments();
1286b858fc6f8afad95a075595016c5c22547924886Erik        if (bundle != null && bundle.containsKey(Calendars.ACCOUNT_NAME)
1296b858fc6f8afad95a075595016c5c22547924886Erik                && bundle.containsKey(Calendars.ACCOUNT_TYPE)) {
1306b858fc6f8afad95a075595016c5c22547924886Erik            mAccount = new Account(bundle.getString(Calendars.ACCOUNT_NAME),
1316b858fc6f8afad95a075595016c5c22547924886Erik                    bundle.getString(Calendars.ACCOUNT_TYPE));
1326b858fc6f8afad95a075595016c5c22547924886Erik        }
1336b858fc6f8afad95a075595016c5c22547924886Erik    }
1346b858fc6f8afad95a075595016c5c22547924886Erik
1356b858fc6f8afad95a075595016c5c22547924886Erik    @Override
1366b858fc6f8afad95a075595016c5c22547924886Erik    public void onPause() {
137c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan        final ListAdapter listAdapter = getListAdapter();
138c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan        if (listAdapter != null) {
139d17780987a421477ae57fe88e48cb2d81c42f517Erik            HashMap<Long, CalendarRow> changes = ((SelectCalendarsSyncAdapter) listAdapter)
140c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                    .getChanges();
141c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan            if (changes != null && changes.size() > 0) {
142c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                for (CalendarRow row : changes.values()) {
143b331a8217f09c2d48960bc192fc1cda1e6a35faeErik                    if (row.synced == row.originalSynced) {
144b331a8217f09c2d48960bc192fc1cda1e6a35faeErik                        continue;
145b331a8217f09c2d48960bc192fc1cda1e6a35faeErik                    }
146d17780987a421477ae57fe88e48cb2d81c42f517Erik                    long id = row.id;
147d17780987a421477ae57fe88e48cb2d81c42f517Erik                    mService.cancelOperation((int) id);
148c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                    // Use the full long id in case it makes a difference
149c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                    Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, row.id);
150c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                    ContentValues values = new ContentValues();
151c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                    // Toggle the current setting
152c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                    int synced = row.synced ? 1 : 0;
153c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                    values.put(Calendars.SYNC_EVENTS, synced);
154950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden                    values.put(Calendars.VISIBLE, synced);
155d17780987a421477ae57fe88e48cb2d81c42f517Erik                    mService.startUpdate((int) id, null, uri, values, null, null, 0);
156c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                }
157c68cc55b8aaa92f0cc8452ef02b2d015bf8a16feMichael Chan                changes.clear();
1586b858fc6f8afad95a075595016c5c22547924886Erik            }
1596b858fc6f8afad95a075595016c5c22547924886Erik        }
1606b858fc6f8afad95a075595016c5c22547924886Erik        super.onPause();
1616b858fc6f8afad95a075595016c5c22547924886Erik    }
1626b858fc6f8afad95a075595016c5c22547924886Erik
1636b858fc6f8afad95a075595016c5c22547924886Erik    @Override
1646b858fc6f8afad95a075595016c5c22547924886Erik    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
1656b858fc6f8afad95a075595016c5c22547924886Erik        mArgs[0] = mAccount.name;
1666b858fc6f8afad95a075595016c5c22547924886Erik        mArgs[1] = mAccount.type;
1676b858fc6f8afad95a075595016c5c22547924886Erik        return new CursorLoader(
1686b858fc6f8afad95a075595016c5c22547924886Erik                getActivity(), Calendars.CONTENT_URI, PROJECTION, SELECTION, mArgs, SORT_ORDER);
1696b858fc6f8afad95a075595016c5c22547924886Erik    }
1706b858fc6f8afad95a075595016c5c22547924886Erik
1716b858fc6f8afad95a075595016c5c22547924886Erik    @Override
1726b858fc6f8afad95a075595016c5c22547924886Erik    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
1736b858fc6f8afad95a075595016c5c22547924886Erik        SelectCalendarsSyncAdapter adapter = (SelectCalendarsSyncAdapter) getListAdapter();
1746b858fc6f8afad95a075595016c5c22547924886Erik        if (adapter == null) {
1756b858fc6f8afad95a075595016c5c22547924886Erik            adapter = new SelectCalendarsSyncAdapter(getActivity(), data);
1766b858fc6f8afad95a075595016c5c22547924886Erik        } else {
1776b858fc6f8afad95a075595016c5c22547924886Erik            adapter.changeCursor(data);
1786b858fc6f8afad95a075595016c5c22547924886Erik        }
1796b858fc6f8afad95a075595016c5c22547924886Erik        setListAdapter(adapter);
180cf7fd2b6d1b5af26c4ac422dde1778e2fd6c7ef6Michael Chan        getListView().setOnItemClickListener(adapter);
1816b858fc6f8afad95a075595016c5c22547924886Erik    }
1826b858fc6f8afad95a075595016c5c22547924886Erik
1831d6d7c6fee68b1641ce8664caf5d6832bf6bb618Dianne Hackborn    public void onLoaderReset(Loader<Cursor> loader) {
1841d6d7c6fee68b1641ce8664caf5d6832bf6bb618Dianne Hackborn        setListAdapter(null);
1851d6d7c6fee68b1641ce8664caf5d6832bf6bb618Dianne Hackborn    }
1861d6d7c6fee68b1641ce8664caf5d6832bf6bb618Dianne Hackborn
1876b858fc6f8afad95a075595016c5c22547924886Erik    // Called when the Accounts button is pressed. Takes the user to the
1886b858fc6f8afad95a075595016c5c22547924886Erik    // Accounts and Sync settings page.
1896b858fc6f8afad95a075595016c5c22547924886Erik    @Override
1906b858fc6f8afad95a075595016c5c22547924886Erik    public void onClick(View v) {
1916b858fc6f8afad95a075595016c5c22547924886Erik        Intent intent = new Intent();
1926b858fc6f8afad95a075595016c5c22547924886Erik        intent.setAction("android.settings.SYNC_SETTINGS");
1936b858fc6f8afad95a075595016c5c22547924886Erik        getActivity().startActivity(intent);
1946b858fc6f8afad95a075595016c5c22547924886Erik    }
1956b858fc6f8afad95a075595016c5c22547924886Erik}
196