19138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang/*
29138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * Copyright (C) 2010 The Android Open Source Project
39138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang *
49138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * Licensed under the Apache License, Version 2.0 (the "License");
59138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * you may not use this file except in compliance with the License.
69138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * You may obtain a copy of the License at
79138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang *
89138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang *      http://www.apache.org/licenses/LICENSE-2.0
99138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang *
109138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * Unless required by applicable law or agreed to in writing, software
119138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * distributed under the License is distributed on an "AS IS" BASIS,
129138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * See the License for the specific language governing permissions and
149138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang * limitations under the License.
159138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang */
169138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangpackage com.android.calendar;
179138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
18a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport static android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME;
19a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport static android.provider.CalendarContract.EXTRA_EVENT_END_TIME;
204003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
21e584a7df962b8e643224bcbce022c9bea19fe221Erikimport android.app.ActionBar;
229138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.app.Activity;
234003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tangimport android.app.FragmentManager;
244003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tangimport android.app.FragmentTransaction;
259138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.app.SearchManager;
26c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelsonimport android.content.BroadcastReceiver;
279138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.content.ContentResolver;
284003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tangimport android.content.ContentUris;
299138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.content.Intent;
309138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.database.ContentObserver;
31c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelsonimport android.graphics.drawable.LayerDrawable;
324003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tangimport android.net.Uri;
339138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.os.Bundle;
349138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.os.Handler;
35a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Events;
363a0e67b1d81a6170a844bb6f9e294efa3a42650aMason Tangimport android.provider.SearchRecentSuggestions;
379138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.text.format.Time;
389138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.util.Log;
391df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tangimport android.view.Menu;
401df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tangimport android.view.MenuItem;
4150f10944eddba97e6730bbdc7545672d0eeec08cRoboErikimport android.view.MenuItem.OnActionExpandListener;
426d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawaimport android.widget.SearchView;
439138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
44c250e2eae5156fdc5233b7f1d319ee81dfc1cbd9Michael Chanimport com.android.calendar.CalendarController.EventInfo;
45c250e2eae5156fdc5233b7f1d319ee81dfc1cbd9Michael Chanimport com.android.calendar.CalendarController.EventType;
46c250e2eae5156fdc5233b7f1d319ee81dfc1cbd9Michael Chanimport com.android.calendar.CalendarController.ViewType;
47c250e2eae5156fdc5233b7f1d319ee81dfc1cbd9Michael Chanimport com.android.calendar.agenda.AgendaFragment;
48c250e2eae5156fdc5233b7f1d319ee81dfc1cbd9Michael Chan
4950f10944eddba97e6730bbdc7545672d0eeec08cRoboErikpublic class SearchActivity extends Activity implements CalendarController.EventHandler,
50a095494586efca8db57e495dc7d87034ce57c9e8RoboErik        SearchView.OnQueryTextListener, OnActionExpandListener {
519138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
529138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    private static final String TAG = SearchActivity.class.getSimpleName();
539138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
544003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private static final boolean DEBUG = false;
554003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
564003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private static final int HANDLER_KEY = 0;
579138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
589138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    protected static final String BUNDLE_KEY_RESTORE_TIME = "key_restore_time";
599138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
609138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    protected static final String BUNDLE_KEY_RESTORE_SEARCH_QUERY =
619138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        "key_restore_search_query";
629138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
63ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson    // display event details to the side of the event list
64ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson   private boolean mShowEventDetailsWithAgenda;
65ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson   private static boolean mIsMultipane;
669138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
674003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private CalendarController mController;
689138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
69eedc9fc0631f3c8727df3c0e73474ebcdecd89feRoboErik    private EventInfoFragment mEventInfoFragment;
709138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
714003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private long mCurrentEventId = -1;
72b9b34ea19f7b74f6d9dceccc19cc110d68291c74Michael Chan
73cb83031d2025eded6d2594ea3f864f404a3673e0Erik    private String mQuery;
742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7509bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik    private SearchView mSearchView;
7609bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik
774003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private DeleteEventHelper mDeleteEventHelper;
784003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
79c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson    private Handler mHandler;
80c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson    private BroadcastReceiver mTimeChangesReceiver;
814003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private ContentResolver mContentResolver;
829138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
836bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    private final ContentObserver mObserver = new ContentObserver(new Handler()) {
849138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        @Override
859138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        public boolean deliverSelfNotifications() {
869138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang            return true;
879138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        }
889138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
899138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        @Override
909138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        public void onChange(boolean selfChange) {
914003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            eventsChanged();
929138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        }
939138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    };
949138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
95c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson    // runs when a timezone was changed and updates the today icon
96c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson    private final Runnable mTimeChangesUpdater = new Runnable() {
97c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        @Override
98c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        public void run() {
99c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson            Utils.setMidnightUpdater(mHandler, mTimeChangesUpdater,
100c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson                    Utils.getTimeZone(SearchActivity.this, mTimeChangesUpdater));
101c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson            SearchActivity.this.invalidateOptionsMenu();
102c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        }
103c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson    };
104c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson
1059138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    @Override
1069138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    protected void onCreate(Bundle icicle) {
1079138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        super.onCreate(icicle);
1084003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        // This needs to be created before setContentView
1094003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mController = CalendarController.getInstance(this);
110c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        mHandler = new Handler();
1114003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
1127ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        mIsMultipane = Utils.getConfigBool(this, R.bool.multiple_pane_config);
113ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson        mShowEventDetailsWithAgenda =
114ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            Utils.getConfigBool(this, R.bool.show_event_details_with_agenda);
115ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson
1164003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        setContentView(R.layout.search);
1179138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
1189138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
1199138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
1209138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        mContentResolver = getContentResolver();
1219138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
1220b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson        if (mIsMultipane) {
1230b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson            getActionBar().setDisplayOptions(
1240b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson                    ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
1250b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson        } else {
1260b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson            getActionBar().setDisplayOptions(0,
1270b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson                    ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME);
1280b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson        }
129e584a7df962b8e643224bcbce022c9bea19fe221Erik
1304003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        // Must be the first to register because this activity can modify the
1314003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        // list of event handlers in it's handle method. This affects who the
1324003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        // rest of the handlers the controller dispatches to are.
1334003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mController.registerEventHandler(HANDLER_KEY, this);
1344003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
1354003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mDeleteEventHelper = new DeleteEventHelper(this, this,
1364003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                false /* don't exit when done */);
1379138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
1389138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        long millis = 0;
1399138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        if (icicle != null) {
1409138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang            // Returns 0 if key not found
1419138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang            millis = icicle.getLong(BUNDLE_KEY_RESTORE_TIME);
1429138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang            if (DEBUG) {
1439138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang                Log.v(TAG, "Restore value from icicle: " + millis);
1449138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang            }
1459138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        }
1469138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        if (millis == 0) {
1479138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang            // Didn't find a time in the bundle, look in intent or current time
1489138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang            millis = Utils.timeFromIntentInMillis(getIntent());
1499138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        }
1504003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
1519138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        Intent intent = getIntent();
1529138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
153cb83031d2025eded6d2594ea3f864f404a3673e0Erik            String query;
154cb83031d2025eded6d2594ea3f864f404a3673e0Erik            if (icicle != null && icicle.containsKey(BUNDLE_KEY_RESTORE_SEARCH_QUERY)) {
155cb83031d2025eded6d2594ea3f864f404a3673e0Erik                query = icicle.getString(BUNDLE_KEY_RESTORE_SEARCH_QUERY);
156cb83031d2025eded6d2594ea3f864f404a3673e0Erik            } else {
157cb83031d2025eded6d2594ea3f864f404a3673e0Erik                query = intent.getStringExtra(SearchManager.QUERY);
158cb83031d2025eded6d2594ea3f864f404a3673e0Erik            }
1594003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            initFragments(millis, query);
1604003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        }
1614003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
1624003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
1634003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    @Override
1644003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    protected void onDestroy() {
1654003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        super.onDestroy();
16661310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook        mController.deregisterAllEventHandlers();
1674003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        CalendarController.removeInstance(this);
1684003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
1694003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
1704003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private void initFragments(long timeMillis, String query) {
1714003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        FragmentManager fragmentManager = getFragmentManager();
17212b33308221db42aff24310f2617f4471886daabDianne Hackborn        FragmentTransaction ft = fragmentManager.beginTransaction();
1734003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
174ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson        AgendaFragment searchResultsFragment = new AgendaFragment(timeMillis, true);
1754003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        ft.replace(R.id.search_results, searchResultsFragment);
1764003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mController.registerEventHandler(R.id.search_results, searchResultsFragment);
1774003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
1784003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        ft.commit();
1794003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        Time t = new Time();
1804003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        t.set(timeMillis);
1814003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        search(query, t);
1824003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
1834003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
184a7694eead7cbb293990bc89c3906e17bad36194cErik    private void showEventInfo(EventInfo event) {
185ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson        if (mShowEventDetailsWithAgenda) {
1864003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            FragmentManager fragmentManager = getFragmentManager();
18712b33308221db42aff24310f2617f4471886daabDianne Hackborn            FragmentTransaction ft = fragmentManager.beginTransaction();
1884003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
189eedc9fc0631f3c8727df3c0e73474ebcdecd89feRoboErik            mEventInfoFragment = new EventInfoFragment(this, event.id,
190eedc9fc0631f3c8727df3c0e73474ebcdecd89feRoboErik                    event.startTime.toMillis(false), event.endTime.toMillis(false),
1916bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    event.getResponse(), false, EventInfoFragment.DIALOG_WINDOW_STYLE);
192ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            ft.replace(R.id.agenda_event_info, mEventInfoFragment);
1934003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            ft.commit();
194ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            mController.registerEventHandler(R.id.agenda_event_info, mEventInfoFragment);
1954003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        } else {
1961202678f3eac9f6d1ad7b4a2700e9be6e38e3e75RoboErik            Intent intent = new Intent(Intent.ACTION_VIEW);
197a7694eead7cbb293990bc89c3906e17bad36194cErik            Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, event.id);
1984003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            intent.setData(eventUri);
1991202678f3eac9f6d1ad7b4a2700e9be6e38e3e75RoboErik            intent.setClass(this, EventInfoActivity.class);
200a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            intent.putExtra(EXTRA_EVENT_BEGIN_TIME,
201a7694eead7cbb293990bc89c3906e17bad36194cErik                    event.startTime != null ? event.startTime.toMillis(true) : -1);
202a7694eead7cbb293990bc89c3906e17bad36194cErik            intent.putExtra(
203a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik                    EXTRA_EVENT_END_TIME, event.endTime != null ? event.endTime.toMillis(true) : -1);
2044003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            startActivity(intent);
2054003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        }
206a7694eead7cbb293990bc89c3906e17bad36194cErik        mCurrentEventId = event.id;
2074003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
2084003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
2094003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private void search(String searchQuery, Time goToTime) {
2103a0e67b1d81a6170a844bb6f9e294efa3a42650aMason Tang        // save query in recent queries
2113a0e67b1d81a6170a844bb6f9e294efa3a42650aMason Tang        SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
212064beb957ae443760118023a40fd7001eb11c1a1RoboErik                Utils.getSearchAuthority(this),
2133a0e67b1d81a6170a844bb6f9e294efa3a42650aMason Tang                CalendarRecentSuggestionsProvider.MODE);
2143a0e67b1d81a6170a844bb6f9e294efa3a42650aMason Tang        suggestions.saveRecentQuery(searchQuery, null);
2153a0e67b1d81a6170a844bb6f9e294efa3a42650aMason Tang
2163a0e67b1d81a6170a844bb6f9e294efa3a42650aMason Tang
2174003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        EventInfo searchEventInfo = new EventInfo();
2184003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        searchEventInfo.eventType = EventType.SEARCH;
2194003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        searchEventInfo.query = searchQuery;
2204003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        searchEventInfo.viewType = ViewType.AGENDA;
2214003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        if (goToTime != null) {
2224003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            searchEventInfo.startTime = goToTime;
2234003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        }
2244003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mController.sendEvent(this, searchEventInfo);
225cb83031d2025eded6d2594ea3f864f404a3673e0Erik        mQuery = searchQuery;
22609bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik        if (mSearchView != null) {
22709bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik            mSearchView.setQuery(mQuery, false);
22809bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik            mSearchView.clearFocus();
22909bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik        }
2304003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
2314003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
2324003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private void deleteEvent(long eventId, long startMillis, long endMillis) {
2334003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mDeleteEventHelper.delete(startMillis, endMillis, eventId, -1);
2344003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        if (mIsMultipane && mEventInfoFragment != null
2354003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                && eventId == mCurrentEventId) {
2364003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            FragmentManager fragmentManager = getFragmentManager();
23712b33308221db42aff24310f2617f4471886daabDianne Hackborn            FragmentTransaction ft = fragmentManager.beginTransaction();
2384003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            ft.remove(mEventInfoFragment);
2394003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            ft.commit();
2404003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mEventInfoFragment = null;
241ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            mController.deregisterEventHandler(R.id.agenda_event_info);
2424003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mCurrentEventId = -1;
2439138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        }
2449138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    }
2459138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
2469138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    @Override
2471df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang    public boolean onCreateOptionsMenu(Menu menu) {
2481df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang        super.onCreateOptionsMenu(menu);
2491df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang        getMenuInflater().inflate(R.menu.search_title_bar, menu);
250c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson
251c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        // replace the default top layer drawable of the today icon with a custom drawable
252c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        // that shows the day of the month of today
25344961ee254c374c71060fb641a8d50f4c3b4869bIsaac Katzenelson        MenuItem menuItem = menu.findItem(R.id.action_today);
25444961ee254c374c71060fb641a8d50f4c3b4869bIsaac Katzenelson        if (Utils.isJellybeanOrLater()) {
25544961ee254c374c71060fb641a8d50f4c3b4869bIsaac Katzenelson            LayerDrawable icon = (LayerDrawable) menuItem.getIcon();
25644961ee254c374c71060fb641a8d50f4c3b4869bIsaac Katzenelson            Utils.setTodayIcon(
25744961ee254c374c71060fb641a8d50f4c3b4869bIsaac Katzenelson                    icon, this, Utils.getTimeZone(SearchActivity.this, mTimeChangesUpdater));
25844961ee254c374c71060fb641a8d50f4c3b4869bIsaac Katzenelson        } else {
25944961ee254c374c71060fb641a8d50f4c3b4869bIsaac Katzenelson            menuItem.setIcon(R.drawable.ic_menu_today_no_date_holo_light);
26044961ee254c374c71060fb641a8d50f4c3b4869bIsaac Katzenelson        }
261c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson
26250f10944eddba97e6730bbdc7545672d0eeec08cRoboErik        MenuItem item = menu.findItem(R.id.action_search);
263a095494586efca8db57e495dc7d87034ce57c9e8RoboErik        item.expandActionView();
264a095494586efca8db57e495dc7d87034ce57c9e8RoboErik        item.setOnActionExpandListener(this);
26509bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik        mSearchView = (SearchView) item.getActionView();
26609bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik        Utils.setUpSearchView(mSearchView, this);
26709bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik        mSearchView.setQuery(mQuery, false);
26809bf38ae2ef172c249dbb9aad81badee6f982f92RoboErik        mSearchView.clearFocus();
269c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson
2701df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang        return true;
2711df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang    }
2721df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang
2731df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang    @Override
2741df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang    public boolean onOptionsItemSelected(MenuItem item) {
2751df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang        Time t = null;
276bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan        final int itemId = item.getItemId();
277bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan        if (itemId == R.id.action_today) {
278bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            t = new Time();
279bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            t.setToNow();
280bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            mController.sendEvent(this, EventType.GO_TO, t, null, -1, ViewType.CURRENT);
281bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            return true;
282bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan        } else if (itemId == R.id.action_search) {
283bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            return false;
284bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan        } else if (itemId == R.id.action_settings) {
285bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            mController.sendEvent(this, EventType.LAUNCH_SETTINGS, null, null, 0, 0);
286bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            return true;
287bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan        } else if (itemId == android.R.id.home) {
288bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            Utils.returnToCalendarHome(this);
289bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            return true;
290bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan        } else {
291bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan            return false;
2921df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang        }
2931df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang    }
2941df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang
2951df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang    @Override
2969138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    protected void onNewIntent(Intent intent) {
2979138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        // From the Android Dev Guide: "It's important to note that when
2989138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        // onNewIntent(Intent) is called, the Activity has not been restarted,
2999138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        // so the getIntent() method will still return the Intent that was first
3009138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        // received with onCreate(). This is why setIntent(Intent) is called
3019138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        // inside onNewIntent(Intent) (just in case you call getIntent() at a
3029138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        // later time)."
3039138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        setIntent(intent);
3049138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        handleIntent(intent);
3059138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    }
3069138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
3079138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    private void handleIntent(Intent intent) {
3089138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
3099138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang            String query = intent.getStringExtra(SearchManager.QUERY);
3104003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            search(query, null);
3119138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        }
3129138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    }
3139138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
3149138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    @Override
3154003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public void onSaveInstanceState(Bundle outState) {
3169138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        super.onSaveInstanceState(outState);
3174003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        outState.putLong(BUNDLE_KEY_RESTORE_TIME, mController.getTime());
318cb83031d2025eded6d2594ea3f864f404a3673e0Erik        outState.putString(BUNDLE_KEY_RESTORE_SEARCH_QUERY, mQuery);
3199138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    }
3209138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
3219138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    @Override
3229138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    protected void onResume() {
3239138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        super.onResume();
324c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson
325c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        Utils.setMidnightUpdater(
326c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson                mHandler, mTimeChangesUpdater, Utils.getTimeZone(this, mTimeChangesUpdater));
327c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        // Make sure the today icon is up to date
328c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        invalidateOptionsMenu();
329c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        mTimeChangesReceiver = Utils.setTimeChangesReceiver(this, mTimeChangesUpdater);
3309138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        mContentResolver.registerContentObserver(Events.CONTENT_URI, true, mObserver);
331cb81189e4868769ea016253eca104e46df2f033aErik        // We call this in case the user changed the time zone
332cb81189e4868769ea016253eca104e46df2f033aErik        eventsChanged();
3339138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    }
3349138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
3359138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    @Override
3369138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    protected void onPause() {
3379138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        super.onPause();
338c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        Utils.resetMidnightUpdater(mHandler, mTimeChangesUpdater);
339c999316fd5a6a8c6291a885e0e239cedf86b59b2Isaac Katzenelson        Utils.clearTimeChangesReceiver(this, mTimeChangesReceiver);
3409138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang        mContentResolver.unregisterContentObserver(mObserver);
3419138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang    }
3429138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang
3434003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    @Override
3444003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public void eventsChanged() {
3454003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mController.sendEvent(this, EventType.EVENTS_CHANGED, null, null, -1, ViewType.CURRENT);
3464003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
3474003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
3484003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    @Override
3494003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public long getSupportedEventTypes() {
3504003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        return EventType.VIEW_EVENT | EventType.DELETE_EVENT;
3514003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
3524003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
3534003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    @Override
3544003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public void handleEvent(EventInfo event) {
3554003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        long endTime = (event.endTime == null) ? -1 : event.endTime.toMillis(false);
3564003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        if (event.eventType == EventType.VIEW_EVENT) {
357a7694eead7cbb293990bc89c3906e17bad36194cErik            showEventInfo(event);
3584003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        } else if (event.eventType == EventType.DELETE_EVENT) {
3594003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            deleteEvent(event.id, event.startTime.toMillis(false), endTime);
3604003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        }
3614003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
3624003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
3636d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    @Override
36428f9b35401fdc5660087479796780a012656099dAdam Powell    public boolean onQueryTextChange(String newText) {
3656d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        return false;
3666d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    }
3676d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa
3686d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    @Override
36928f9b35401fdc5660087479796780a012656099dAdam Powell    public boolean onQueryTextSubmit(String query) {
370cb83031d2025eded6d2594ea3f864f404a3673e0Erik        mQuery = query;
371fb0ec227f0d4b3108438c88a6b6d234f5e40fb5cMichael Chan        mController.sendEvent(this, EventType.SEARCH, null, null, -1, ViewType.CURRENT, 0, query,
37246a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan                getComponentName());
3736d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        return false;
3746d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    }
375cb83031d2025eded6d2594ea3f864f404a3673e0Erik
376cb83031d2025eded6d2594ea3f864f404a3673e0Erik    @Override
377a095494586efca8db57e495dc7d87034ce57c9e8RoboErik    public boolean onMenuItemActionExpand(MenuItem item) {
378cb83031d2025eded6d2594ea3f864f404a3673e0Erik        return true;
379cb83031d2025eded6d2594ea3f864f404a3673e0Erik    }
380a095494586efca8db57e495dc7d87034ce57c9e8RoboErik
381a095494586efca8db57e495dc7d87034ce57c9e8RoboErik    @Override
382a095494586efca8db57e495dc7d87034ce57c9e8RoboErik    public boolean onMenuItemActionCollapse(MenuItem item) {
383a095494586efca8db57e495dc7d87034ce57c9e8RoboErik        Utils.returnToCalendarHome(this);
384a095494586efca8db57e495dc7d87034ce57c9e8RoboErik        return false;
385a095494586efca8db57e495dc7d87034ce57c9e8RoboErik    }
3869138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang}
387