blob: fb585a618c4766fb5b913fd89b3520290ea83d7c [file] [log] [blame]
Aga Wronska8788dad2016-01-15 17:30:15 -08001/*
2 * Copyright (C) 2013 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
17package com.android.documentsui;
18
19import android.provider.DocumentsContract.Root;
20import android.text.TextUtils;
21import android.util.Log;
22import android.view.MenuItem;
23import android.view.View;
24import android.view.View.OnClickListener;
25import android.view.View.OnFocusChangeListener;
26import android.widget.SearchView;
27import android.widget.SearchView.OnQueryTextListener;
28
29import com.android.documentsui.model.RootInfo;
30
31/**
32 * Manages searching UI behavior.
33 */
34final class SearchManager implements
35 SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener {
36
37 public interface SearchManagerListener {
38 void onSearchChanged();
39
40 void onSearchQueryChanged(String query);
41 }
42
43 public static final String TAG = "SearchManger";
44
45 private SearchManagerListener mListener;
46 private String currentSearch;
47 private boolean mSearchExpanded;
48 private boolean mIgnoreNextClose;
49
50 private DocumentsToolBar mActionBar;
51 private MenuItem mMenu;
52 private SearchView mView;
53
54 public SearchManager(SearchManagerListener listener) {
55 mListener = listener;
56 }
57
58 public void setSearchMangerListener(SearchManagerListener listener) {
59 mListener = listener;
60 }
61
62 public void install(DocumentsToolBar actionBar) {
63 assert (mActionBar == null);
64 mActionBar = actionBar;
65 mMenu = actionBar.getSearchMenu();
66 mView = (SearchView) mMenu.getActionView();
67
68 mView.setOnQueryTextListener(this);
69 mView.setOnCloseListener(this);
70 mView.setOnSearchClickListener(this);
71 mView.setOnQueryTextFocusChangeListener(this);
72 }
73
74 /**
75 * @param root Info about the current directory.
76 */
77 void update(RootInfo root) {
78 if (mMenu == null) {
79 Log.d(TAG, "update called before Search MenuItem installed.");
80 return;
81 }
82
83 if (currentSearch != null) {
84 mMenu.expandActionView();
85
86 mView.setIconified(false);
87 mView.clearFocus();
88 mView.setQuery(currentSearch, false);
89 } else {
90 mView.clearFocus();
91 if (!mView.isIconified()) {
92 mIgnoreNextClose = true;
93 mView.setIconified(true);
94 }
95
96 if (mMenu.isActionViewExpanded()) {
97 mMenu.collapseActionView();
98 }
99 }
100
101 showMenu(root != null
102 && ((root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0));
103 }
104
105 void showMenu(boolean visible) {
106 if (mMenu == null) {
107 Log.d(TAG, "showMenu called before Search MenuItem installed.");
108 return;
109 }
110
111 mMenu.setVisible(visible);
112 if (!visible) {
113 currentSearch = null;
114 if (mListener != null) {
115 mListener.onSearchQueryChanged(currentSearch);
116 }
117 }
118 }
119
120 /**
121 * Cancels current search operation. Triggers clearing and collapsing the SearchView.
122 *
123 * @return True if it cancels search. False if it does not operate search currently.
124 */
125 boolean cancelSearch() {
126 if (isExpanded() || isSearching()) {
127 // If the query string is not empty search view won't get iconified
128 mView.setQuery("", false);
129 // Causes calling onClose(). onClose() is triggering directory content update.
130 mView.setIconified(true);
131 return true;
132 }
133 return false;
134 }
135
136 boolean isSearching() {
137 return currentSearch != null;
138 }
139
140 boolean isExpanded() {
141 return mSearchExpanded;
142 }
143
144 /**
145 * Clears the search. Clears the SearchView background color. Triggers refreshing of the
146 * directory content.
147 * @return True if the default behavior of clearing/dismissing SearchView should be overridden.
148 * False otherwise.
149 */
150 @Override
151 public boolean onClose() {
152 mSearchExpanded = false;
153 if (mIgnoreNextClose) {
154 mIgnoreNextClose = false;
155 return false;
156 }
157
158 mView.setBackgroundColor(
159 mView.getResources().getColor(android.R.color.transparent, null));
160
161 // Refresh the directory if a search was done
162 if (currentSearch != null) {
163 currentSearch = null;
164 if (mListener != null) {
165 mListener.onSearchQueryChanged(currentSearch);
166 mListener.onSearchChanged();
167 }
168 }
169 return false;
170 }
171
172 /**
173 * Sets mSearchExpanded. Called when search icon is clicked to start search. Used to detect when
174 * the view expanded instead of onMenuItemActionExpand, because SearchView has showAsAction set
175 * to always and onMenuItemAction* methods are not called.
176 */
177 @Override
178 public void onClick(View v) {
179 mSearchExpanded = true;
180 mView.setBackgroundColor(
181 mView.getResources().getColor(R.color.menu_search_background, null));
182 }
183
184 @Override
185 public boolean onQueryTextSubmit(String query) {
186 currentSearch = query;
187 mView.clearFocus();
188 if (mListener != null) {
189 mListener.onSearchQueryChanged(currentSearch);
190 mListener.onSearchChanged();
191 }
192 return true;
193 }
194
195 @Override
196 public void onFocusChange(View v, boolean hasFocus) {
197 if (!hasFocus) {
198 if (currentSearch == null) {
199 mView.setIconified(true);
200 } else if (TextUtils.isEmpty(mView.getQuery())) {
201 cancelSearch();
202 }
203 }
204 }
205
206 @Override
207 public boolean onQueryTextChange(String newText) {
208 return false;
209 }
210}