Merge lp:~tomdroid-dev/tomdroid/search-interface into lp:~tomdroid-maintainers/tomdroid/main

Proposed by Stefan Hammer
Status: Merged
Merged at revision: 237
Proposed branch: lp:~tomdroid-dev/tomdroid/search-interface
Merge into: lp:~tomdroid-maintainers/tomdroid/main
Diff against target: 455 lines (+272/-13)
13 files modified
AndroidManifest.xml (+15/-0)
res/layout/main.xml (+9/-3)
res/layout/search.xml (+50/-0)
res/menu/main.xml (+8/-4)
res/values/strings.xml (+10/-0)
res/xml/preferences.xml (+6/-1)
res/xml/searchable.xml (+7/-0)
src/org/tomdroid/NoteManager.java (+26/-4)
src/org/tomdroid/ui/PreferencesActivity.java (+20/-1)
src/org/tomdroid/ui/Search.java (+104/-0)
src/org/tomdroid/ui/Tomdroid.java (+4/-0)
src/org/tomdroid/util/Preferences.java (+1/-0)
src/org/tomdroid/util/SearchSuggestionProvider.java (+12/-0)
To merge this branch: bzr merge lp:~tomdroid-dev/tomdroid/search-interface
Reviewer Review Type Date Requested Status
Olivier Bilodeau Approve
Review via email: mp+68150@code.launchpad.net

Description of the change

Search ability for Tomdroid!

 * Created standard Android Search Interface, called by clicking on Search button or Search menu
 * Search Results are shown in a Results List, clicking on the List-items opens the note.
 * Search history is saved and presented as suggestions while typing.
 * Search history can be deleted in Preferences.
 * Search is a SingleTop Activity -> clicking on back button in Results List brings you direct to Tomdroid List View.
 * Clicking on search button in Results List opens another search

I suggest to also merge usability-improvements branch, because the ability of clicking the Actionbar Tomdroid-icon to go back to List-View is really helpful here.

To post a comment you must log in.
Revision history for this message
Olivier Bilodeau (plaxx) wrote :

Started the review.

One minor thing I note is that you need to be more careful about consistency. For ex: in the new search strings there is search_hint (underscore separation), strNoResults (java-style object name) and SearchResultTitle (java-style class name). We should aim for only one notation style unless we have a pattern.

Really not a big problem, not enough to go back and fix it IMO but with new code/strings we should aim to avoid it.

Revision history for this message
Olivier Bilodeau (plaxx) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'AndroidManifest.xml'
2--- AndroidManifest.xml 2011-06-21 06:07:28 +0000
3+++ AndroidManifest.xml 2011-07-16 10:36:02 +0000
4@@ -29,6 +29,9 @@
5 <category android:name="android.intent.category.BROWSABLE" />
6 <data android:scheme="tomdroid" android:host="sync"/>
7 </intent-filter>
8+ <!-- enable the search dialog to send searches to SearchableActivity -->
9+ <meta-data android:name="android.app.default_searchable"
10+ android:value=".ui.Search" />
11 </activity>
12
13 <activity android:name=".ui.ViewNote">
14@@ -40,6 +43,18 @@
15 </intent-filter>
16 </activity>
17
18+ <activity android:name=".ui.Search"
19+ android:launchMode="singleTop">
20+ <intent-filter>
21+ <action android:name="android.intent.action.SEARCH" />
22+ </intent-filter>
23+ <meta-data android:name="android.app.searchable"
24+ android:resource="@xml/searchable"/>
25+ </activity>
26+ <provider android:name=".util.SearchSuggestionProvider"
27+ android:authorities="org.tomdroid.util.SearchSuggestionProvider"
28+ />
29+
30 <provider android:name="NoteProvider"
31 android:authorities="org.tomdroid.notes"
32 />
33
34=== modified file 'res/layout/main.xml'
35--- res/layout/main.xml 2011-06-21 05:50:40 +0000
36+++ res/layout/main.xml 2011-07-16 10:36:02 +0000
37@@ -37,8 +37,14 @@
38 />
39
40 <TextView android:id="@+id/list_empty"
41- android:layout_width="wrap_content"
42- android:layout_height="wrap_content"
43- android:text="@string/strListEmptyNoNotes"
44+ android:text="@string/strListEmptyNoNotes"
45+ android:layout_width="fill_parent"
46+ android:layout_height="fill_parent"
47+ android:singleLine="false"
48+ android:textSize="25dip"
49+ android:textStyle="bold"
50+ android:ellipsize="marquee"
51+ android:padding="30dip"
52+ android:textColor="#FF555555"
53 />
54 </LinearLayout>
55\ No newline at end of file
56
57=== added file 'res/layout/search.xml'
58--- res/layout/search.xml 1970-01-01 00:00:00 +0000
59+++ res/layout/search.xml 2011-07-16 10:36:02 +0000
60@@ -0,0 +1,50 @@
61+<?xml version="1.0" encoding="utf-8"?>
62+<!--
63+ Tomdroid
64+ Tomboy on Android
65+ http://www.launchpad.net/tomdroid
66+
67+ Copyright 2008, 2009 Olivier Bilodeau <olivier@bottomlesspit.org>
68+
69+ This file is part of Tomdroid.
70+
71+ Tomdroid is free software: you can redistribute it and/or modify
72+ it under the terms of the GNU General Public License as published by
73+ the Free Software Foundation, either version 3 of the License, or
74+ (at your option) any later version.
75+
76+ Tomdroid is distributed in the hope that it will be useful,
77+ but WITHOUT ANY WARRANTY; without even the implied warranty of
78+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
79+ GNU General Public License for more details.
80+
81+ You should have received a copy of the GNU General Public License
82+ along with Tomdroid. If not, see <http://www.gnu.org/licenses/>.
83+-->
84+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
85+ android:layout_width="fill_parent"
86+ android:layout_height="fill_parent"
87+ android:orientation="vertical"
88+ >
89+
90+ <include android:id="@+id/actionbar" layout="@layout/actionbar" />
91+
92+ <ListView android:id="@android:id/android:list"
93+ android:layout_width="fill_parent"
94+ android:layout_height="fill_parent"
95+ android:divider="#FFCCCCCC"
96+ android:dividerHeight="1px"
97+ />
98+
99+ <TextView android:id="@+id/no_results"
100+ android:text="@string/strNoResults"
101+ android:layout_width="fill_parent"
102+ android:layout_height="fill_parent"
103+ android:singleLine="false"
104+ android:textSize="25dip"
105+ android:textStyle="bold"
106+ android:ellipsize="marquee"
107+ android:padding="30dip"
108+ android:textColor="#FF555555"
109+ />
110+</LinearLayout>
111\ No newline at end of file
112
113=== modified file 'res/menu/main.xml'
114--- res/menu/main.xml 2011-06-18 12:59:36 +0000
115+++ res/menu/main.xml 2011-07-16 10:36:02 +0000
116@@ -24,13 +24,17 @@
117 <menu xmlns:android="http://schemas.android.com/apk/res/android">
118
119 <item
120+ android:icon="@android:drawable/ic_menu_info_details"
121 android:title="@string/menuAbout"
122- android:id="@+id/menuAbout"
123- android:icon="@android:drawable/ic_menu_info_details"/>
124-
125-
126+ android:id="@+id/menuAbout"/>
127+
128 <item
129 android:icon="@android:drawable/ic_menu_preferences"
130 android:title="@string/menuPrefs"
131 android:id="@+id/menuPrefs"/>
132+
133+ <item
134+ android:icon="@android:drawable/ic_menu_search"
135+ android:title="@string/menuSearch"
136+ android:id="@+id/menuSearch"/>
137 </menu>
138
139=== modified file 'res/values/strings.xml'
140--- res/values/strings.xml 2011-01-15 22:25:39 +0000
141+++ res/values/strings.xml 2011-07-16 10:36:02 +0000
142@@ -89,6 +89,16 @@
143 <string name="menuFilterNotebook">Filter</string>
144 <string name="strListEmptyNoNotebooks">There are no notebooks in the database.</string>
145 <string name="allNotebooksFilter">All notebooks</string>
146+
147+ <!-- Search -->
148+ <string name="search_hint">Search notes</string>
149+ <string name="strNoResults">No notes found for \"%s\"</string>
150+ <string name="menuSearch">Search</string>
151+ <string name="SearchResultTitle">Search Results:</string>
152+ <string name="clearSearchHistoryTitle">Clear search history</string>
153+ <string name="clearSearchHistory">Remove all the searches you have performed</string>
154+ <string name="deletedSearchHistory">Search history has been cleared.</string>
155+
156
157 <!-- Date -->
158 <string name="textModified">Modified: </string>
159
160=== modified file 'res/xml/preferences.xml'
161--- res/xml/preferences.xml 2010-10-17 20:19:18 +0000
162+++ res/xml/preferences.xml 2011-07-16 10:36:02 +0000
163@@ -12,7 +12,12 @@
164 android:title="@string/prefSyncServer"
165 android:positiveButtonText="@string/prefAuthenticate"
166 android:shouldDisableView="true"/>
167-
168+ </PreferenceCategory>
169+ <PreferenceCategory android:title="@string/menuSearch">
170+ <Preference
171+ android:title="@string/clearSearchHistoryTitle"
172+ android:summary="@string/clearSearchHistory"
173+ android:key="clearSearchHistory" />
174 </PreferenceCategory>
175
176 </PreferenceScreen>
177\ No newline at end of file
178
179=== added file 'res/xml/searchable.xml'
180--- res/xml/searchable.xml 1970-01-01 00:00:00 +0000
181+++ res/xml/searchable.xml 2011-07-16 10:36:02 +0000
182@@ -0,0 +1,7 @@
183+<?xml version="1.0" encoding="utf-8"?>
184+<searchable xmlns:android="http://schemas.android.com/apk/res/android"
185+ android:label="@string/app_name"
186+ android:hint="@string/search_hint"
187+ android:searchSuggestAuthority="org.tomdroid.util.SearchSuggestionProvider"
188+ android:searchSuggestSelection=" ?">
189+</searchable>
190\ No newline at end of file
191
192=== modified file 'src/org/tomdroid/NoteManager.java'
193--- src/org/tomdroid/NoteManager.java 2010-10-09 19:48:21 +0000
194+++ src/org/tomdroid/NoteManager.java 2011-07-16 10:36:02 +0000
195@@ -142,15 +142,37 @@
196 }
197
198
199- public static ListAdapter getListAdapter(Activity activity) {
200+ public static ListAdapter getListAdapter(Activity activity, String querys) {
201+
202+ String where;
203+ if (querys==null) {
204+ where=null;
205+ } else {
206+ // sql statements to search notes
207+ String[] query = querys.split(" ");
208+ where="";
209+ int count=0;
210+ for (String string : query) {
211+ if (count>0) where = where + " AND ";
212+ where = where + "("+Note.TITLE+" LIKE '%"+string+"%' OR "+Note.NOTE_CONTENT+" LIKE '%"+string+"%')";
213+ count++;
214+ }
215+ }
216
217- Cursor notesCursor = getAllNotes(activity, false);
218+ // get a cursor representing all notes from the NoteProvider
219+ Uri notes = Tomdroid.CONTENT_URI;
220+ Cursor notesCursor = activity.managedQuery(notes, LIST_PROJECTION, where, null, null);
221
222 // set up an adapter binding the TITLE field of the cursor to the list item
223- String[] from = new String[] { Note.TITLE, Note.MODIFIED_DATE };
224- int[] to = new int[] { R.id.note_title, R.id.note_date };
225+ String[] from = new String[] { Note.TITLE };
226+ int[] to = new int[] { R.id.note_title };
227 return new NoteListCursorAdapter(activity, R.layout.main_list_item, notesCursor, from, to);
228 }
229+
230+ public static ListAdapter getListAdapter(Activity activity) {
231+
232+ return getListAdapter(activity, null);
233+ }
234
235 // gets the titles of the notes present in the db, used in ViewNote.buildLinkifyPattern()
236 public static Cursor getTitles(Activity activity) {
237
238=== modified file 'src/org/tomdroid/ui/PreferencesActivity.java'
239--- src/org/tomdroid/ui/PreferencesActivity.java 2010-10-09 19:58:11 +0000
240+++ src/org/tomdroid/ui/PreferencesActivity.java 2011-07-16 10:36:02 +0000
241@@ -32,6 +32,7 @@
242 import org.tomdroid.sync.SyncService;
243 import org.tomdroid.util.FirstNote;
244 import org.tomdroid.util.Preferences;
245+import org.tomdroid.util.SearchSuggestionProvider;
246
247 import android.app.AlertDialog;
248 import android.app.ProgressDialog;
249@@ -47,6 +48,8 @@
250 import android.preference.Preference;
251 import android.preference.PreferenceActivity;
252 import android.preference.Preference.OnPreferenceChangeListener;
253+import android.preference.Preference.OnPreferenceClickListener;
254+import android.provider.SearchRecentSuggestions;
255 import android.util.Log;
256 import android.widget.Toast;
257
258@@ -57,6 +60,7 @@
259 // TODO: put the various preferences in fields and figure out what to do on activity suspend/resume
260 private EditTextPreference syncServer = null;
261 private ListPreference syncService = null;
262+ private Preference clearSearchHistory = null;
263
264 @Override
265 protected void onCreate(Bundle savedInstanceState) {
266@@ -67,6 +71,7 @@
267 // Fill the Preferences fields
268 syncServer = (EditTextPreference)findPreference(Preferences.Key.SYNC_SERVER.getName());
269 syncService = (ListPreference)findPreference(Preferences.Key.SYNC_SERVICE.getName());
270+ clearSearchHistory = (Preference)findPreference(Preferences.Key.CLEAR_SEARCH_HISTORY.getName());
271
272 // Set the default values if nothing exists
273 this.setDefaults();
274@@ -111,6 +116,21 @@
275
276 });
277
278+ //delete Search History
279+ clearSearchHistory.setOnPreferenceClickListener(new OnPreferenceClickListener() {
280+ public boolean onPreferenceClick(Preference preference) {
281+ SearchRecentSuggestions suggestions = new SearchRecentSuggestions(PreferencesActivity.this,
282+ SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);
283+ suggestions.clearHistory();
284+
285+ Toast.makeText(getBaseContext(),
286+ getString(R.string.deletedSearchHistory),
287+ Toast.LENGTH_LONG).show();
288+ Log.d(TAG, "Deleted search history.");
289+
290+ return true;
291+ }
292+ });
293 }
294
295 private void authenticate(String serverUri) {
296@@ -243,5 +263,4 @@
297 resetLocalDatabase();
298 }
299 }
300-
301 }
302
303=== added file 'src/org/tomdroid/ui/Search.java'
304--- src/org/tomdroid/ui/Search.java 1970-01-01 00:00:00 +0000
305+++ src/org/tomdroid/ui/Search.java 2011-07-16 10:36:02 +0000
306@@ -0,0 +1,104 @@
307+package org.tomdroid.ui;
308+
309+import org.tomdroid.Note;
310+import org.tomdroid.NoteManager;
311+import org.tomdroid.R;
312+import org.tomdroid.sync.SyncManager;
313+import org.tomdroid.util.SearchSuggestionProvider;
314+
315+import android.app.ListActivity;
316+import android.app.SearchManager;
317+import android.content.Intent;
318+import android.database.Cursor;
319+import android.graphics.Color;
320+import android.net.Uri;
321+import android.os.Bundle;
322+import android.os.Handler;
323+import android.provider.SearchRecentSuggestions;
324+import android.util.Log;
325+import android.view.View;
326+import android.widget.ListAdapter;
327+import android.widget.ListView;
328+import android.widget.TextView;
329+
330+public class Search extends ListActivity {
331+
332+ // Logging info
333+ private static final String TAG = "Tomdroid Search";
334+ // UI elements
335+ private TextView title;
336+ // UI to data model glue
337+ private TextView listEmptyView;
338+ // UI feedback handler
339+ private Handler syncMessageHandler = new SyncMessageHandler(this);
340+
341+ private ListAdapter adapter;
342+
343+
344+ @Override
345+ public void onCreate(Bundle savedInstanceState) {
346+ super.onCreate(savedInstanceState);
347+ setContentView(R.layout.search);
348+
349+ title = (TextView) findViewById(R.id.title);
350+ title.setTextColor(Color.DKGRAY);
351+ title.setTextSize(18.0f);
352+ title.setText((CharSequence) getString(R.string.SearchResultTitle));
353+
354+ handleIntent(getIntent());
355+ }
356+
357+ @Override
358+ protected void onNewIntent(Intent intent) {
359+ setIntent(intent);
360+ handleIntent(intent);
361+ }
362+
363+ private void handleIntent(Intent intent) {
364+ //handles a search query
365+ if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
366+ String query = intent.getStringExtra(SearchManager.QUERY);
367+ showResults(query);
368+ }
369+
370+ //adds query to search history suggestions
371+ if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
372+ String query = intent.getStringExtra(SearchManager.QUERY);
373+ SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
374+ SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);
375+ suggestions.saveRecentQuery(query, null);
376+ }
377+ }
378+
379+ public void showResults(String query) {
380+ if (Tomdroid.LOGGING_ENABLED) Log.d(TAG,"Start searching for: "+query);
381+
382+
383+ // adapter that binds the ListView UI to the notes in the note manager
384+ adapter = NoteManager.getListAdapter(this, query);
385+ setListAdapter(adapter);
386+
387+ // set the view shown when query not found
388+ listEmptyView = (TextView) findViewById(R.id.no_results);
389+ listEmptyView.setText(getString(R.string.strNoResults, new Object[] {query}));
390+ getListView().setEmptyView(listEmptyView);
391+ }
392+
393+ @Override
394+ protected void onListItemClick(ListView l, View v, int position, long id) {
395+
396+ Cursor item = (Cursor) adapter.getItem(position);
397+ int noteId = item.getInt(item.getColumnIndexOrThrow(Note.ID));
398+
399+ Uri intentUri = Uri.parse(Tomdroid.CONTENT_URI + "/" + noteId);
400+ Intent i = new Intent(Intent.ACTION_VIEW, intentUri, this, ViewNote.class);
401+ startActivity(i);
402+ }
403+
404+ @Override
405+ public void onResume(){
406+ super.onResume();
407+ SyncManager.setActivity(this);
408+ SyncManager.setHandler(this.syncMessageHandler);
409+ }
410+}
411
412=== modified file 'src/org/tomdroid/ui/Tomdroid.java'
413--- src/org/tomdroid/ui/Tomdroid.java 2011-01-15 22:25:39 +0000
414+++ src/org/tomdroid/ui/Tomdroid.java 2011-07-16 10:36:02 +0000
415@@ -146,6 +146,10 @@
416 case R.id.menuPrefs:
417 startActivity(new Intent(this, PreferencesActivity.class));
418 return true;
419+
420+ case R.id.menuSearch:
421+ startSearch(null, false, null, false);
422+ return true;
423 }
424
425 return super.onOptionsItemSelected(item);
426
427=== modified file 'src/org/tomdroid/util/Preferences.java'
428--- src/org/tomdroid/util/Preferences.java 2010-09-26 19:57:31 +0000
429+++ src/org/tomdroid/util/Preferences.java 2011-07-16 10:36:02 +0000
430@@ -33,6 +33,7 @@
431 SYNC_SERVER_ROOT_API ("sync_server_root_api", ""),
432 SYNC_SERVER_USER_API ("sync_server_user_api", ""),
433 SYNC_SERVER ("sync_server", "https://one.ubuntu.com/notes"),
434+ CLEAR_SEARCH_HISTORY ("clearSearchHistory", ""),
435 ACCESS_TOKEN ("access_token", ""),
436 ACCESS_TOKEN_SECRET ("access_token_secret", ""),
437 REQUEST_TOKEN ("request_token", ""),
438
439=== added file 'src/org/tomdroid/util/SearchSuggestionProvider.java'
440--- src/org/tomdroid/util/SearchSuggestionProvider.java 1970-01-01 00:00:00 +0000
441+++ src/org/tomdroid/util/SearchSuggestionProvider.java 2011-07-16 10:36:02 +0000
442@@ -0,0 +1,12 @@
443+package org.tomdroid.util;
444+
445+import android.content.SearchRecentSuggestionsProvider;
446+
447+public class SearchSuggestionProvider extends SearchRecentSuggestionsProvider {
448+ public final static String AUTHORITY = "org.tomdroid.util.SearchSuggestionProvider";
449+ public final static int MODE = DATABASE_MODE_QUERIES;
450+
451+ public SearchSuggestionProvider() {
452+ setupSuggestions(AUTHORITY, MODE);
453+ }
454+}
455\ No newline at end of file

Subscribers

People subscribed via source and target branches