Merge lp://staging/~pjv/tomdroid/fix-tomdroid-Android-lifecycle into lp://staging/~tomdroid-maintainers/tomdroid/main
- fix-tomdroid-Android-lifecycle
- Merge into main
Status: | Rejected |
---|---|
Rejected by: | Benoit Garret |
Proposed branch: | lp://staging/~pjv/tomdroid/fix-tomdroid-Android-lifecycle |
Merge into: | lp://staging/~tomdroid-maintainers/tomdroid/main |
Diff against target: | None lines |
To merge this branch: | bzr merge lp://staging/~pjv/tomdroid/fix-tomdroid-Android-lifecycle |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Benoit Garret | Disapprove | ||
Olivier Bilodeau | Needs Information | ||
Review via email: mp+7982@code.staging.launchpad.net |
Commit message
Description of the change
Olivier Bilodeau (plaxx) wrote : | # |
Sorry for the long delay. I just merged Benoit's storage-redesign branch and it took me way longer than it should have.
My comments on your branch:
A lot of different things here that should not be related in one branch.
- The close item was dealt with.
- I'm not convinced with OI About.. I mean you have to install an app to get an about dialog..? Why isn't OI About a LGPL jar file instead of a full and seperate APK?
- What's the advantage of using a Service vs the sqlite db and provider?
If you don't reply and just don't want to hear about tomdroid anymore I would understand. I've been terribly slow.
I don't have much time right now. Tomdroid's code changed a lot, you should not merge anything this old.
> - I'm not convinced with OI About.. I mean you have to install an app to get
> an about dialog..? Why isn't OI About a LGPL jar file instead of a full and
> seperate APK?
Phone memory is not abundant. One app like that can take detailed information about authors, open source license, etc, and handle/show it well (the reuse principle). Besides, what's a quick one-time install from the market? Gnome/gtk also has a universal about box.
> - What's the advantage of using a Service vs the sqlite db and provider?
The service was for searching the notes on the fs, right? If so then it was not vs. the db or provider but vs the class that searched the notes (on Tomdroid startup?). Services are dedicated to running in the background, and can be run seperately from the program. For instance, on insert of another sd card, or on bootup.
Shall I get back to you on this?
Benoit Garret (benoit.garret) wrote : | # |
Can I close this merge request? It's nearly been a year and I'm guessing it would be quicker to create a new branch on top of the current main.
Benoit Garret (benoit.garret) wrote : | # |
Age of the merge request and one big patch means it's basically unmergeable. I'm closing this.
What a waste ;-) but yeah it has become unmergeable. The ContentProvider idea still seems like a good idea to me. Not sure what Tomdroid is using now. OI About also is still in use.
Benoit Garret (benoit.garret) wrote : | # |
We're plugging the NoteProvider through a subclass of SimpleCursorAda
I'm with Olivier on the about dialog, a full app to handle a dumb dialog seems overkill to me.
I believe what really killed this merge was the fact that you put everything in one commit, preventing us from merging the parts of the work that everyone agreed upon. That, and less work for the maintainer means a greater chance of inclusion (after all, we're as lazy as the next developer ;-) ).
Preview Diff
1 | === modified file '.classpath' |
2 | --- .classpath 2009-06-21 15:58:01 +0000 |
3 | +++ .classpath 2009-06-27 21:04:05 +0000 |
4 | @@ -4,5 +4,6 @@ |
5 | <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> |
6 | <classpathentry kind="lib" path="lib/joda-time/joda-time-1.6.jar"/> |
7 | <classpathentry kind="src" path="gen"/> |
8 | + <classpathentry combineaccessrules="false" kind="src" path="/OI About"/> |
9 | <classpathentry kind="output" path="bin"/> |
10 | </classpath> |
11 | |
12 | === modified file '.project' |
13 | --- .project 2008-11-19 07:01:14 +0000 |
14 | +++ .project 2009-06-27 21:04:05 +0000 |
15 | @@ -1,6 +1,6 @@ |
16 | <?xml version="1.0" encoding="UTF-8"?> |
17 | <projectDescription> |
18 | - <name>tomdroid</name> |
19 | + <name>tomdroid-fix-Android-lifecycle</name> |
20 | <comment></comment> |
21 | <projects> |
22 | </projects> |
23 | |
24 | === modified file 'AndroidManifest.xml' |
25 | --- AndroidManifest.xml 2009-06-24 19:50:22 +0000 |
26 | +++ AndroidManifest.xml 2009-06-27 21:04:05 +0000 |
27 | @@ -6,7 +6,27 @@ |
28 | <uses-sdk android:minSdkVersion="1" /> |
29 | |
30 | <application android:icon="@drawable/icon" android:label="@string/app_name"> |
31 | - |
32 | + <meta-data android:name="org.openintents.metadata.COMMENTS" |
33 | + android:value="@string/about_comments" /> |
34 | + <meta-data android:name="org.openintents.metadata.COPYRIGHT" |
35 | + android:value="@string/about_copyright" /> |
36 | + <meta-data android:name="org.openintents.metadata.AUTHORS" |
37 | + android:resource="@array/about_authors" /> |
38 | + <meta-data android:name="org.openintents.metadata.DOCUMENTERS" |
39 | + android:resource="@array/about_documenters" /> |
40 | + <meta-data android:name="org.openintents.metadata.TRANSLATORS" |
41 | + android:resource="@string/about_translators" /> |
42 | + <meta-data android:name="org.openintents.metadata.ARTISTS" |
43 | + android:resource="@array/about_artists" /> |
44 | + <meta-data android:name="org.openintents.metadata.WEBSITE_LABEL" |
45 | + android:value="@string/about_website_label" /> |
46 | + <meta-data android:name="org.openintents.metadata.WEBSITE_URL" |
47 | + android:value="@string/about_website_url" /> |
48 | + <meta-data android:name="org.openintents.metadata.EMAIL" |
49 | + android:value="@string/about_email" /> |
50 | + <meta-data android:name="org.openintents.metadata.LICENSE" |
51 | + android:resource="@raw/license_short" /> |
52 | + |
53 | <activity android:label="@string/app_name" |
54 | android:name=".ui.Tomdroid" |
55 | android:launchMode="singleTop" |
56 | @@ -31,6 +51,8 @@ |
57 | <provider android:name="NoteProvider" |
58 | android:authorities="org.tomdroid.notes" |
59 | /> |
60 | + |
61 | + <service android:name="NoteCollectingService"></service> |
62 | </application> |
63 | <uses-permission android:name="android.permission.INTERNET" /> |
64 | </manifest> |
65 | \ No newline at end of file |
66 | |
67 | === modified file 'res/layout/main_list_item.xml' |
68 | --- res/layout/main_list_item.xml 2009-06-23 02:51:17 +0000 |
69 | +++ res/layout/main_list_item.xml 2009-06-27 21:04:05 +0000 |
70 | @@ -21,9 +21,10 @@ |
71 | You should have received a copy of the GNU General Public License |
72 | along with Tomdroid. If not, see <http://www.gnu.org/licenses/>. |
73 | --> |
74 | -<TextView android:id="@+id/note_title" xmlns:android="http://schemas.android.com/apk/res/android" |
75 | +<TextView android:id="@android:id/text1" xmlns:android="http://schemas.android.com/apk/res/android" |
76 | android:layout_width="fill_parent" |
77 | - android:layout_height="fill_parent" |
78 | - android:textSize="24dp" |
79 | - android:padding="10dip" |
80 | - /> |
81 | + android:layout_height="wrap_content" |
82 | + android:minHeight="?android:attr/listPreferredItemHeight" |
83 | + android:textAppearance="?android:attr/textAppearanceLarge" |
84 | + android:gravity="center_vertical" |
85 | + android:paddingLeft="5dip"/> |
86 | |
87 | === modified file 'res/menu/main.xml' |
88 | --- res/menu/main.xml 2009-04-06 01:07:32 +0000 |
89 | +++ res/menu/main.xml 2009-06-27 21:04:05 +0000 |
90 | @@ -28,11 +28,11 @@ |
91 | android:title="@string/menuLoadWebNote" |
92 | android:id="@+id/menuLoadWebNote" |
93 | /> |
94 | - <item |
95 | + <!-- <item |
96 | android:icon="@drawable/icon_close" |
97 | android:title="@string/menuClose" |
98 | android:id="@+id/menuClose" |
99 | - /> |
100 | + /> --> |
101 | <item |
102 | android:icon="@drawable/icon_about" |
103 | android:title="@string/menuAbout" |
104 | |
105 | === added directory 'res/raw' |
106 | === added file 'res/raw/license_short' |
107 | --- res/raw/license_short 1970-01-01 00:00:00 +0000 |
108 | +++ res/raw/license_short 2009-06-27 21:04:05 +0000 |
109 | @@ -0,0 +1,12 @@ |
110 | +Tomdroid is free software: you can redistribute it and/or modify |
111 | +it under the terms of the GNU General Public License as published by |
112 | +the Free Software Foundation, either version 3 of the License, or |
113 | +(at your option) any later version. |
114 | + |
115 | +Tomdroid is distributed in the hope that it will be useful, |
116 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
117 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
118 | +GNU General Public License for more details. |
119 | + |
120 | +You should have received a copy of the GNU General Public License |
121 | +along with Tomdroid. If not, see <http://www.gnu.org/licenses/>. |
122 | \ No newline at end of file |
123 | |
124 | === added file 'res/values/arrays.xml' |
125 | --- res/values/arrays.xml 1970-01-01 00:00:00 +0000 |
126 | +++ res/values/arrays.xml 2009-06-27 21:04:05 +0000 |
127 | @@ -0,0 +1,21 @@ |
128 | +<?xml version="1.0" encoding="utf-8"?> |
129 | +<resources> |
130 | + <string-array name="about_authors"> |
131 | + <item>Olivier Bilodeau olivier@bottomlesspit.org</item> |
132 | + <item>pjv https://launchpad.net/~pjv</item> |
133 | + <item>This app reuses several system / typical components.</item> |
134 | + </string-array> |
135 | + |
136 | + <string-array name="about_documenters"> |
137 | + <item>Olivier Bilodeau olivier@bottomlesspit.org</item> |
138 | + <item>pjv https://launchpad.net/~pjv</item> |
139 | + </string-array> |
140 | + |
141 | + <string-array name="about_translators"> |
142 | + <item>Olivier Bilodeau olivier@bottomlesspit.org</item> |
143 | + </string-array> |
144 | + |
145 | + <string-array name="about_artists"> |
146 | + <item>Olivier Bilodeau olivier@bottomlesspit.org</item> |
147 | + </string-array> |
148 | +</resources> |
149 | \ No newline at end of file |
150 | |
151 | === modified file 'res/values/strings.xml' |
152 | --- res/values/strings.xml 2009-06-21 22:50:37 +0000 |
153 | +++ res/values/strings.xml 2009-06-27 21:04:05 +0000 |
154 | @@ -23,9 +23,7 @@ |
155 | --> |
156 | <resources> |
157 | <string name="app_name">Tomdroid</string> |
158 | - <string name="app_desc">Tomboy compatible wikiwiki note-taking application that can\'t take notes yet.</string> |
159 | - <string name="author">Olivier Bilodeau</string> |
160 | - |
161 | + |
162 | <!-- main.xml --> |
163 | <string name="strListEmptyWaiting">Please wait while the notes load..</string> |
164 | <string name="strListEmptyNoNotes"> |
165 | @@ -46,12 +44,20 @@ |
166 | \n\nIf you would like to contribute, help at all levels would be appreciated. |
167 | Hop on board on launchpad.net/tomdroid and contact us!\n |
168 | </string> |
169 | - <string name="strAbout"> |
170 | - %1$s |
171 | - \n\nAuthor: %2$s |
172 | - \nVersion: %3$s |
173 | - \nLicensed under the GPLv3 |
174 | - </string> |
175 | + |
176 | + <!-- About --> |
177 | + |
178 | + <string name="about_comments">Tomboy compatible wikiwiki note-taking application that can\'t take notes yet.</string> |
179 | + <string name="about_copyright">Copyright © 2009 Olivier Bilodeau</string><!-- Add your name here, separated with comma's, if you helped out --> |
180 | + <string name="about_website_label">Project page</string> |
181 | + <string name="about_website_url">http://www.launchpad.net/tomdroid/</string> |
182 | + <string name="about_email">olivier@bottomlesspit.org</string> |
183 | + <string name="about_feedback">tomdroid-dev@lists.launchpad.net</string> |
184 | + <string name="about_translators">translator-credits</string> |
185 | + <string name="about_backup">To view information about this app you need to install OI About. See http://www.openintents.org/ or the Market.</string> |
186 | + <string name="link_about_dialog">market://search?q=pname:org.openintents.about</string> |
187 | + <string name="market_backup">You do not seem to have the Android Market app installed. Ignoring.</string> |
188 | + |
189 | |
190 | <!-- load_web_note_dialog.xml --> |
191 | <string name="strLoadFromWebTitle">Note from the Web</string> |
192 | |
193 | === modified file 'src/org/tomdroid/Note.java' |
194 | --- src/org/tomdroid/Note.java 2009-06-21 20:25:16 +0000 |
195 | +++ src/org/tomdroid/Note.java 2009-06-27 21:04:05 +0000 |
196 | @@ -25,6 +25,7 @@ |
197 | import org.joda.time.DateTime; |
198 | import org.joda.time.format.DateTimeFormatter; |
199 | import org.joda.time.format.ISODateTimeFormat; |
200 | +import org.tomdroid.ui.Tomdroid; |
201 | |
202 | import android.text.Spannable; |
203 | import android.text.SpannableStringBuilder; |
204 | @@ -45,7 +46,7 @@ |
205 | public static final String[] PROJECTION = { Note.ID, Note.TITLE, Note.FILE, Note.MODIFIED_DATE }; |
206 | |
207 | // Logging info |
208 | - private static final String TAG = "Note"; |
209 | + private static final String TAG = Tomdroid.TAG;//"Note"; |
210 | |
211 | // Notes constants |
212 | // TODO this is a weird yellow that was usable for the android emulator, I must confirm this for real usage |
213 | |
214 | === added file 'src/org/tomdroid/NoteCollectingService.java' |
215 | --- src/org/tomdroid/NoteCollectingService.java 1970-01-01 00:00:00 +0000 |
216 | +++ src/org/tomdroid/NoteCollectingService.java 2009-06-27 21:04:05 +0000 |
217 | @@ -0,0 +1,183 @@ |
218 | +package org.tomdroid; |
219 | + |
220 | +import java.io.BufferedReader; |
221 | +import java.io.File; |
222 | +import java.io.FileInputStream; |
223 | +import java.io.FileNotFoundException; |
224 | +import java.io.FilenameFilter; |
225 | +import java.io.IOException; |
226 | +import java.io.InputStreamReader; |
227 | + |
228 | +import javax.xml.parsers.ParserConfigurationException; |
229 | +import javax.xml.parsers.SAXParser; |
230 | +import javax.xml.parsers.SAXParserFactory; |
231 | + |
232 | +import org.tomdroid.ui.Tomdroid; |
233 | +import org.tomdroid.xml.NoteHandler; |
234 | +import org.xml.sax.InputSource; |
235 | +import org.xml.sax.SAXException; |
236 | +import org.xml.sax.XMLReader; |
237 | + |
238 | +import android.app.Service; |
239 | +import android.content.ContentValues; |
240 | +import android.content.Intent; |
241 | +import android.database.Cursor; |
242 | +import android.net.Uri; |
243 | +import android.os.IBinder; |
244 | +import android.util.Log; |
245 | + |
246 | +public class NoteCollectingService extends Service { |
247 | + private File notesRoot; |
248 | + |
249 | + // domain elements |
250 | + private NoteCollection noteCollection; |
251 | + |
252 | + // Logging info |
253 | + private static final String TAG = Tomdroid.TAG;//"NoteCollectingService"; |
254 | + |
255 | + /* (non-Javadoc) |
256 | + * @see android.app.Service#onStart(android.content.Intent, int) |
257 | + */ |
258 | + @Override |
259 | + public void onStart(Intent intent, int startId) { |
260 | + // TODO Auto-generated method stub |
261 | + super.onStart(intent, startId); |
262 | + |
263 | + noteCollection = NoteCollection.getInstance(); |
264 | + notesRoot = new File(Tomdroid.NOTES_PATH); |
265 | + try { |
266 | + if (!notesRoot.exists()) { |
267 | + throw new FileNotFoundException("Tomdroid notes folder doesn't exist. It is configured to be at: "+Tomdroid.NOTES_PATH); |
268 | + }//TODO: FNFE not catched anymore |
269 | + } catch (FileNotFoundException e) { |
270 | + e.printStackTrace(); |
271 | + } |
272 | + new Thread(new Runnable() { |
273 | + public void run() { |
274 | + readAndParseNotes(); |
275 | + stopSelf(); |
276 | + } |
277 | + }).start(); |
278 | + } |
279 | + |
280 | + |
281 | + public void readAndParseNotes() { |
282 | + File[] fileList = notesRoot.listFiles(new NotesFilter()); |
283 | + |
284 | + // If there are no notes, warn the UI through an empty message |
285 | + if (fileList.length == 0) { |
286 | + //TODO: also remove notes from ContentProvider |
287 | + } |
288 | + |
289 | + for (File file : fileList) { |
290 | + |
291 | + // give a filename to a thread and ask to parse it when nothing's left to do its over |
292 | + parseFile(file); |
293 | + } |
294 | + } |
295 | + |
296 | + /** |
297 | + * Simple filename filter that grabs files ending with .note |
298 | + * TODO move into its own static class in a util package |
299 | + */ |
300 | + class NotesFilter implements FilenameFilter { |
301 | + public boolean accept(File dir, String name) { |
302 | + return (name.endsWith(".note")); |
303 | + } |
304 | + } |
305 | + |
306 | + |
307 | + public void parseFile(File file) { |
308 | + Note note = new Note(); |
309 | + |
310 | + note.setFileName(file.getAbsolutePath()); |
311 | + |
312 | + try { |
313 | + // Parsing |
314 | + // XML |
315 | + // Get a SAXParser from the SAXPArserFactory |
316 | + SAXParserFactory spf = SAXParserFactory.newInstance(); |
317 | + SAXParser sp = spf.newSAXParser(); |
318 | + |
319 | + // Get the XMLReader of the SAXParser we created |
320 | + XMLReader xr = sp.getXMLReader(); |
321 | + |
322 | + // Create a new ContentHandler, send it this note to fill and apply it to the XML-Reader |
323 | + NoteHandler xmlHandler = new NoteHandler(note); |
324 | + xr.setContentHandler(xmlHandler); |
325 | + |
326 | + |
327 | + // Create the proper input source based on if its a local note or a web note |
328 | + FileInputStream fin = new FileInputStream(file); |
329 | + BufferedReader in = new BufferedReader(new InputStreamReader(fin), 8192); |
330 | + InputSource is = new InputSource(in); |
331 | + |
332 | + if (Tomdroid.LOGGING_ENABLED) Log.v(TAG, "parsing note"); |
333 | + xr.parse(is); |
334 | + |
335 | + // TODO wrap and throw a new exception here |
336 | + } catch (ParserConfigurationException e) { |
337 | + e.printStackTrace(); |
338 | + } catch (SAXException e) { |
339 | + e.printStackTrace(); |
340 | + } catch (IOException e) { |
341 | + e.printStackTrace(); |
342 | + } |
343 | + |
344 | + synchronized (noteCollection) { |
345 | + noteCollection.addNote(note); |
346 | + } |
347 | + |
348 | + // notify UI that we are done here and send result |
349 | + updateNoteListWith(note.getTitle()); |
350 | + } |
351 | + |
352 | + private void updateNoteListWith(String noteTitle) { |
353 | + |
354 | + // get the note instance we will work with that instead from now on |
355 | + Note note = NoteCollection.getInstance().findNoteFromTitle(noteTitle); |
356 | + |
357 | + // verify if the note is already in the content provider |
358 | + |
359 | + // TODO I could see a problem where someone delete a note and recreate one with the same title. |
360 | + // It would been seen as not new although it is (it will have a new filename) |
361 | + // TODO make the query prettier (use querybuilder) |
362 | + Uri notes = Tomdroid.CONTENT_URI; |
363 | + String[] whereArgs = new String[1]; |
364 | + whereArgs[0] = noteTitle; |
365 | + Cursor managedCursor = getContentResolver().query( notes, |
366 | + NoteProvider.PROJECTION, |
367 | + Note.TITLE + "= ?", |
368 | + whereArgs, |
369 | + Note.TITLE + " ASC"); |
370 | + if (managedCursor.getCount() == 0) { |
371 | + |
372 | + // This note is not in the database yet we need to insert it |
373 | + if (Tomdroid.LOGGING_ENABLED) Log.v(TAG,"A new note has been detected (not yet in db)"); |
374 | + |
375 | + // This add the note to the content Provider |
376 | + // TODO PoC code that should be removed in next iteration's refactoring (no notecollection, everything should come from the provider I guess?) |
377 | + ContentValues values = new ContentValues(); |
378 | + values.put(Note.TITLE, note.getTitle()); |
379 | + values.put(Note.FILE, note.getFileName()); |
380 | + Uri uri = getContentResolver().insert(Tomdroid.CONTENT_URI, values); |
381 | + // now that we inserted the note put its ID in the note itself |
382 | + note.setDbId(Integer.parseInt(uri.getLastPathSegment())); |
383 | + |
384 | + if (Tomdroid.LOGGING_ENABLED) Log.v(TAG,"Note inserted in content provider. ID: "+uri+" TITLE:"+noteTitle+" ID:"+note.getDbId()); |
385 | + } else { |
386 | + |
387 | + // find out the note's id and put it in the note |
388 | + if (managedCursor.moveToFirst()) { |
389 | + int idColumn = managedCursor.getColumnIndex(Note.ID); |
390 | + note.setDbId(managedCursor.getInt(idColumn)); |
391 | + } |
392 | + } |
393 | + } |
394 | + |
395 | + |
396 | + @Override |
397 | + public IBinder onBind(Intent intent) { |
398 | + throw new RuntimeException("onBind not supported for NoteCollectingService"); |
399 | + } |
400 | +} |
401 | |
402 | === modified file 'src/org/tomdroid/NoteCollection.java' |
403 | --- src/org/tomdroid/NoteCollection.java 2009-06-21 22:20:10 +0000 |
404 | +++ src/org/tomdroid/NoteCollection.java 2009-06-27 21:04:05 +0000 |
405 | @@ -22,17 +22,13 @@ |
406 | */ |
407 | package org.tomdroid; |
408 | |
409 | -import java.io.File; |
410 | -import java.io.FileNotFoundException; |
411 | import java.util.ArrayList; |
412 | import java.util.Iterator; |
413 | import java.util.List; |
414 | import java.util.regex.Pattern; |
415 | |
416 | import org.tomdroid.ui.Tomdroid; |
417 | -import org.tomdroid.util.AsyncNoteLoaderAndParser; |
418 | |
419 | -import android.os.Handler; |
420 | import android.util.Log; |
421 | |
422 | // TODO Transform the NoteCollection into a Provider (see .../android-sdk-linux_x86-1.0_r1/docs/devel/data/contentproviders.html#creatingacontentprovider) |
423 | @@ -44,7 +40,7 @@ |
424 | private List<Note> notes = new ArrayList<Note>(); |
425 | |
426 | // Logging info |
427 | - private static final String TAG = "NoteCollection"; |
428 | + private static final String TAG = Tomdroid.TAG;//"NoteCollection"; |
429 | |
430 | public List<Note> getNotes() { |
431 | return notes; |
432 | @@ -76,6 +72,18 @@ |
433 | return null; |
434 | } |
435 | |
436 | + public synchronized Note findNoteFromDbId(long id) { |
437 | + if (Tomdroid.LOGGING_ENABLED) Log.d(TAG,"searching for note with db id: "+id); |
438 | + Iterator<Note> i = notes.iterator(); |
439 | + while(i.hasNext()) { |
440 | + Note curNote = i.next(); |
441 | + if (curNote.getDbId()==id) { |
442 | + return curNote; |
443 | + } |
444 | + } |
445 | + return null; |
446 | + } |
447 | + |
448 | // TODO there is most likely a better way to do this |
449 | public Note findNoteFromFilename(String filename) { |
450 | if (Tomdroid.LOGGING_ENABLED) Log.d(TAG,"searching for note with filename: "+filename); |
451 | @@ -88,18 +96,6 @@ |
452 | } |
453 | return null; |
454 | } |
455 | - |
456 | - // TODO also throw a empty exception that we will catch in tomdroid and display the empty notelist msg |
457 | - public void loadNotes(Handler hndl) throws FileNotFoundException { |
458 | - File notesRoot = new File(Tomdroid.NOTES_PATH); |
459 | - |
460 | - if (!notesRoot.exists()) { |
461 | - throw new FileNotFoundException("Tomdroid notes folder doesn't exist. It is configured to be at: "+Tomdroid.NOTES_PATH); |
462 | - } |
463 | - |
464 | - AsyncNoteLoaderAndParser asyncLoader = new AsyncNoteLoaderAndParser(notesRoot, this, hndl); |
465 | - asyncLoader.readAndParseNotes(); |
466 | - } |
467 | |
468 | /** |
469 | * Builds a regular expression pattern that will match any of the note title currently in the collection. |
470 | |
471 | === modified file 'src/org/tomdroid/NoteProvider.java' |
472 | --- src/org/tomdroid/NoteProvider.java 2009-04-06 22:30:41 +0000 |
473 | +++ src/org/tomdroid/NoteProvider.java 2009-06-27 21:04:05 +0000 |
474 | @@ -67,20 +67,25 @@ |
475 | // -- |
476 | private static final String DATABASE_NAME = "tomdroid-notes.db"; |
477 | private static final String DB_TABLE_NOTES = "notes"; |
478 | - private static final int DB_VERSION = 1; |
479 | + private static final int DB_VERSION = 2; |
480 | // TODO once properly implemented, sort by: KEY_MODIFIED_DATE + " DESC" |
481 | - private static final String DEFAULT_SORT_ORDER = Note.ID; |
482 | + public static final String DEFAULT_SORT_ORDER = Note.ID; |
483 | |
484 | private static HashMap<String, String> notesProjectionMap; |
485 | |
486 | private static final int NOTES = 1; |
487 | private static final int NOTE_ID = 2; |
488 | private static final int NOTE_TITLE = 3; |
489 | + |
490 | + public static final String[] PROJECTION = new String[] { |
491 | + Note.ID, |
492 | + Note.TITLE, |
493 | + }; |
494 | |
495 | private static final UriMatcher uriMatcher; |
496 | |
497 | // Logging info |
498 | - private static final String TAG = "NoteProvider"; |
499 | + private static final String TAG = Tomdroid.TAG;//"NoteProvider"; |
500 | |
501 | /** |
502 | * This class helps open, create, and upgrade the database file. |
503 | |
504 | === modified file 'src/org/tomdroid/ui/Tomdroid.java' |
505 | --- src/org/tomdroid/ui/Tomdroid.java 2009-06-24 19:50:22 +0000 |
506 | +++ src/org/tomdroid/ui/Tomdroid.java 2009-06-27 21:04:05 +0000 |
507 | @@ -22,24 +22,24 @@ |
508 | */ |
509 | package org.tomdroid.ui; |
510 | |
511 | -import java.io.FileNotFoundException; |
512 | +import java.io.File; |
513 | |
514 | +import org.openintents.intents.AboutIntents; |
515 | import org.tomdroid.Note; |
516 | +import org.tomdroid.NoteCollectingService; |
517 | import org.tomdroid.NoteCollection; |
518 | +import org.tomdroid.NoteProvider; |
519 | import org.tomdroid.R; |
520 | |
521 | import android.app.AlertDialog; |
522 | import android.app.ListActivity; |
523 | -import android.content.ContentValues; |
524 | +import android.content.ActivityNotFoundException; |
525 | import android.content.DialogInterface; |
526 | import android.content.Intent; |
527 | import android.content.DialogInterface.OnClickListener; |
528 | -import android.content.pm.PackageManager.NameNotFoundException; |
529 | import android.database.Cursor; |
530 | import android.net.Uri; |
531 | import android.os.Bundle; |
532 | -import android.os.Handler; |
533 | -import android.os.Message; |
534 | import android.util.Log; |
535 | import android.view.Menu; |
536 | import android.view.MenuInflater; |
537 | @@ -47,7 +47,9 @@ |
538 | import android.view.View; |
539 | import android.widget.ArrayAdapter; |
540 | import android.widget.ListView; |
541 | +import android.widget.SimpleCursorAdapter; |
542 | import android.widget.TextView; |
543 | +import android.widget.Toast; |
544 | |
545 | public class Tomdroid extends ListActivity { |
546 | |
547 | @@ -56,16 +58,15 @@ |
548 | public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes"); |
549 | public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.tomdroid.note"; |
550 | public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.tomdroid.note"; |
551 | - public static final String PROJECT_HOMEPAGE = "http://www.launchpad.net/tomdroid/"; |
552 | - |
553 | + |
554 | // config parameters |
555 | // TODO hardcoded for now |
556 | public static final String NOTES_PATH = "/sdcard/tomdroid/"; |
557 | // Logging should be disabled for release builds |
558 | - public static final boolean LOGGING_ENABLED = false; |
559 | + public static final boolean LOGGING_ENABLED = true; |
560 | |
561 | // Logging info |
562 | - private static final String TAG = "Tomdroid"; |
563 | + public static final String TAG = "Tomdroid"; |
564 | |
565 | // data keys |
566 | public static final String RESULT_URL_TO_LOAD = "urlToLoad"; |
567 | @@ -78,7 +79,6 @@ |
568 | private NoteCollection localNotes; |
569 | |
570 | // UI to data model glue |
571 | - private ArrayAdapter<String> notesListAdapter; |
572 | private TextView listEmptyView; |
573 | |
574 | // Bundle keys for saving state |
575 | @@ -111,9 +111,23 @@ |
576 | .show(); |
577 | } |
578 | |
579 | - // listAdapter that binds the UI to the notes names |
580 | - notesListAdapter = new ArrayAdapter<String>(this, R.layout.main_list_item); |
581 | - setListAdapter(notesListAdapter); |
582 | + // If no data was given in the intent (because we were started |
583 | + // as a MAIN activity), then use our default content provider. |
584 | + Intent intent = getIntent(); |
585 | + if (intent.getData() == null) { |
586 | + intent.setData(CONTENT_URI); |
587 | + } |
588 | + |
589 | + |
590 | + // Perform a managed query. The Activity will handle closing and requerying the cursor |
591 | + // when needed. |
592 | + Cursor cursor = managedQuery(getIntent().getData(), NoteProvider.PROJECTION, null, null, |
593 | + NoteProvider.DEFAULT_SORT_ORDER); |
594 | + |
595 | + // Used to map notes entries from the database to views |
596 | + SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.main_list_item, cursor, |
597 | + new String[] { Note.TITLE }, new int[] { android.R.id.text1 }); |
598 | + setListAdapter(adapter); |
599 | |
600 | // set the view shown when the list is empty |
601 | listEmptyView = (TextView)findViewById(R.id.list_empty); |
602 | @@ -121,24 +135,19 @@ |
603 | |
604 | // start loading local notes |
605 | if (LOGGING_ENABLED) Log.v(TAG, "Loading local notes"); |
606 | - |
607 | + File notesRoot = new File(Tomdroid.NOTES_PATH); |
608 | + if (!notesRoot.exists()) { |
609 | + new AlertDialog.Builder(this) |
610 | + .setMessage("Tomdroid notes folder doesn't exist. It is configured to be at: "+Tomdroid.NOTES_PATH) |
611 | + .setTitle("Error") |
612 | + .setNeutralButton("Ok", new OnClickListener() { |
613 | + public void onClick(DialogInterface dialog, int which) { |
614 | + dialog.dismiss(); |
615 | + }}) |
616 | + .show(); |
617 | + } |
618 | + startService(new Intent(this, NoteCollectingService.class)); |
619 | localNotes = NoteCollection.getInstance(); |
620 | - try { |
621 | - localNotes.loadNotes(handler); |
622 | - } catch (FileNotFoundException e) { |
623 | - //TODO put strings in ressource |
624 | - listEmptyView.setText(R.string.strListEmptyNoNotes); |
625 | - new AlertDialog.Builder(this) |
626 | - .setMessage(e.getMessage()) |
627 | - .setTitle("Error") |
628 | - .setNeutralButton("Ok", new OnClickListener() { |
629 | - public void onClick(DialogInterface dialog, int which) { |
630 | - dialog.dismiss(); |
631 | - }}) |
632 | - .show(); |
633 | - e.printStackTrace(); |
634 | - } |
635 | - |
636 | } |
637 | |
638 | @Override |
639 | @@ -156,12 +165,12 @@ |
640 | case R.id.menuLoadWebNote: |
641 | showLoadWebNoteDialog(); |
642 | return true; |
643 | - |
644 | +/* |
645 | case R.id.menuClose: |
646 | // closing everything then closing itself |
647 | finishActivity(ACTIVITY_VIEW); |
648 | finish(); |
649 | - return true; |
650 | + return true;*/ |
651 | |
652 | case R.id.menuAbout: |
653 | showAboutDialog(); |
654 | @@ -180,41 +189,29 @@ |
655 | outState.putBoolean(WARNING_SHOWN, true); |
656 | } |
657 | } |
658 | - |
659 | - private void showAboutDialog() { |
660 | + |
661 | + /** |
662 | + * Show an about dialog for this application. |
663 | + */ |
664 | + protected void showAboutDialog() { |
665 | + Intent intent = new Intent(AboutIntents.ACTION_SHOW_ABOUT_DIALOG); |
666 | |
667 | - // grab version info |
668 | - String ver; |
669 | - try { |
670 | - ver = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; |
671 | - } catch (NameNotFoundException e) { |
672 | - e.printStackTrace(); |
673 | - ver = "Not found!"; |
674 | + // Start about activity. Needs to be "forResult" with requestCode>=0 |
675 | + // so that the package name is passed properly. |
676 | + // |
677 | + // The details are obtained from the Manifest through |
678 | + // default tags and metadata. |
679 | + try{ |
680 | + startActivityForResult(intent, 0); |
681 | + }catch(ActivityNotFoundException e){ |
682 | + try{ |
683 | + //FlurryAgent.onError("LCA:showAboutDialog1", getString(R.string.about_backup), "Toast"); |
684 | + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.link_about_dialog)))); |
685 | + }catch(ActivityNotFoundException e2){ |
686 | + //FlurryAgent.onError("LCA:showAboutDialog2", getString(R.string.about_backup), "Toast"); |
687 | + Toast.makeText(this, getString(R.string.market_backup), Toast.LENGTH_LONG).show(); |
688 | + } |
689 | } |
690 | - |
691 | - // format the string |
692 | - String aboutDialogFormat = getString(R.string.strAbout); |
693 | - String aboutDialogStr = String.format(aboutDialogFormat, |
694 | - getString(R.string.app_desc), // App description |
695 | - getString(R.string.author), // Author name |
696 | - ver // Version |
697 | - ); |
698 | - |
699 | - // build and show the dialog |
700 | - new AlertDialog.Builder(this) |
701 | - .setMessage(aboutDialogStr) |
702 | - .setTitle("About Tomdroid") |
703 | - .setIcon(R.drawable.icon) |
704 | - .setNegativeButton("Project page", new OnClickListener() { |
705 | - public void onClick(DialogInterface dialog, int which) { |
706 | - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Tomdroid.PROJECT_HOMEPAGE))); |
707 | - dialog.dismiss(); |
708 | - }}) |
709 | - .setPositiveButton("Ok", new OnClickListener() { |
710 | - public void onClick(DialogInterface dialog, int which) { |
711 | - dialog.dismiss(); |
712 | - }}) |
713 | - .show(); |
714 | } |
715 | |
716 | @Override |
717 | @@ -229,31 +226,12 @@ |
718 | } |
719 | } |
720 | } |
721 | - |
722 | - private Handler handler = new Handler() { |
723 | - |
724 | - @Override |
725 | - public void handleMessage(Message msg) { |
726 | - |
727 | - // thread is done fetching a note and parsing went well |
728 | - if (msg.what == Note.NOTE_RECEIVED_AND_VALID) { |
729 | - |
730 | - // update the note list with this newly parsed note |
731 | - updateNoteListWith(msg.getData().getString(Note.TITLE)); |
732 | - |
733 | - } else if (msg.what == Note.NO_NOTES) { |
734 | - |
735 | - // if there are no notes, say so in the list_empty message |
736 | - listEmptyView.setText(R.string.strListEmptyNoNotes); |
737 | - } |
738 | - } |
739 | - }; |
740 | |
741 | @Override |
742 | protected void onListItemClick(ListView l, View v, int position, long id) { |
743 | |
744 | // get the clicked note |
745 | - Note n = localNotes.findNoteFromTitle(notesListAdapter.getItem(position)); |
746 | + Note n = localNotes.findNoteFromDbId(id); |
747 | |
748 | Intent i = new Intent(Tomdroid.this, ViewNote.class); |
749 | i.putExtra(Note.FILE, n.getFileName()); |
750 | @@ -273,54 +251,4 @@ |
751 | i.putExtra(Note.URL, url); |
752 | startActivity(i); |
753 | } |
754 | - |
755 | - private void updateNoteListWith(String noteTitle) { |
756 | - |
757 | - // add note to the note list |
758 | - notesListAdapter.add(noteTitle); |
759 | - |
760 | - // get the note instance we will work with that instead from now on |
761 | - Note note = localNotes.findNoteFromTitle(noteTitle); |
762 | - |
763 | - // verify if the note is already in the content provider |
764 | - String[] projection = new String[] { |
765 | - Note.ID, |
766 | - Note.TITLE, |
767 | - }; |
768 | - |
769 | - // TODO I could see a problem where someone delete a note and recreate one with the same title. |
770 | - // It would been seen as not new although it is (it will have a new filename) |
771 | - // TODO make the query prettier (use querybuilder) |
772 | - Uri notes = Tomdroid.CONTENT_URI; |
773 | - String[] whereArgs = new String[1]; |
774 | - whereArgs[0] = noteTitle; |
775 | - Cursor managedCursor = managedQuery( notes, |
776 | - projection, |
777 | - Note.TITLE + "= ?", |
778 | - whereArgs, |
779 | - Note.TITLE + " ASC"); |
780 | - if (managedCursor.getCount() == 0) { |
781 | - |
782 | - // This note is not in the database yet we need to insert it |
783 | - if (LOGGING_ENABLED) Log.v(TAG,"A new note has been detected (not yet in db)"); |
784 | - |
785 | - // This add the note to the content Provider |
786 | - // TODO PoC code that should be removed in next iteration's refactoring (no notecollection, everything should come from the provider I guess?) |
787 | - ContentValues values = new ContentValues(); |
788 | - values.put(Note.TITLE, note.getTitle()); |
789 | - values.put(Note.FILE, note.getFileName()); |
790 | - Uri uri = getContentResolver().insert(CONTENT_URI, values); |
791 | - // now that we inserted the note put its ID in the note itself |
792 | - note.setDbId(Integer.parseInt(uri.getLastPathSegment())); |
793 | - |
794 | - if (LOGGING_ENABLED) Log.v(TAG,"Note inserted in content provider. ID: "+uri+" TITLE:"+noteTitle+" ID:"+note.getDbId()); |
795 | - } else { |
796 | - |
797 | - // find out the note's id and put it in the note |
798 | - if (managedCursor.moveToFirst()) { |
799 | - int idColumn = managedCursor.getColumnIndex(Note.ID); |
800 | - note.setDbId(managedCursor.getInt(idColumn)); |
801 | - } |
802 | - } |
803 | - } |
804 | } |
805 | |
806 | === modified file 'src/org/tomdroid/ui/ViewNote.java' |
807 | --- src/org/tomdroid/ui/ViewNote.java 2009-06-21 20:25:16 +0000 |
808 | +++ src/org/tomdroid/ui/ViewNote.java 2009-06-27 21:04:05 +0000 |
809 | @@ -60,7 +60,7 @@ |
810 | private Note note; |
811 | |
812 | // Logging info |
813 | - private static final String TAG = "ViewNote"; |
814 | + private static final String TAG = Tomdroid.TAG;//"ViewNote"; |
815 | |
816 | // TODO extract methods in here |
817 | @Override |
818 | |
819 | === removed file 'src/org/tomdroid/util/AsyncNoteLoaderAndParser.java' |
820 | --- src/org/tomdroid/util/AsyncNoteLoaderAndParser.java 2009-06-21 21:28:14 +0000 |
821 | +++ src/org/tomdroid/util/AsyncNoteLoaderAndParser.java 1970-01-01 00:00:00 +0000 |
822 | @@ -1,163 +0,0 @@ |
823 | -/* |
824 | - * Tomdroid |
825 | - * Tomboy on Android |
826 | - * http://www.launchpad.net/tomdroid |
827 | - * |
828 | - * Copyright 2009 Olivier Bilodeau <olivier@bottomlesspit.org> |
829 | - * |
830 | - * This file is part of Tomdroid. |
831 | - * |
832 | - * Tomdroid is free software: you can redistribute it and/or modify |
833 | - * it under the terms of the GNU General Public License as published by |
834 | - * the Free Software Foundation, either version 3 of the License, or |
835 | - * (at your option) any later version. |
836 | - * |
837 | - * Tomdroid is distributed in the hope that it will be useful, |
838 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
839 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
840 | - * GNU General Public License for more details. |
841 | - * |
842 | - * You should have received a copy of the GNU General Public License |
843 | - * along with Tomdroid. If not, see <http://www.gnu.org/licenses/>. |
844 | - */ |
845 | -package org.tomdroid.util; |
846 | - |
847 | -import java.io.BufferedReader; |
848 | -import java.io.File; |
849 | -import java.io.FileInputStream; |
850 | -import java.io.FilenameFilter; |
851 | -import java.io.IOException; |
852 | -import java.io.InputStreamReader; |
853 | -import java.util.concurrent.ExecutorService; |
854 | -import java.util.concurrent.Executors; |
855 | - |
856 | -import javax.xml.parsers.ParserConfigurationException; |
857 | -import javax.xml.parsers.SAXParser; |
858 | -import javax.xml.parsers.SAXParserFactory; |
859 | - |
860 | -import org.tomdroid.Note; |
861 | -import org.tomdroid.NoteCollection; |
862 | -import org.tomdroid.ui.Tomdroid; |
863 | -import org.tomdroid.xml.NoteHandler; |
864 | -import org.xml.sax.InputSource; |
865 | -import org.xml.sax.SAXException; |
866 | -import org.xml.sax.XMLReader; |
867 | - |
868 | -import android.os.Bundle; |
869 | -import android.os.Handler; |
870 | -import android.os.Message; |
871 | -import android.util.Log; |
872 | - |
873 | -public class AsyncNoteLoaderAndParser { |
874 | - private final ExecutorService pool; |
875 | - private final static int poolSize = 1; |
876 | - private File path; |
877 | - private NoteCollection noteCollection; |
878 | - private Handler parentHandler; |
879 | - |
880 | - // logging related |
881 | - private final static String TAG = "AsyncNoteLoaderAndParser"; |
882 | - |
883 | - public AsyncNoteLoaderAndParser(File path, NoteCollection nc, Handler hndl) { |
884 | - this.path = path; |
885 | - pool = Executors.newFixedThreadPool(poolSize); |
886 | - noteCollection = nc; |
887 | - parentHandler = hndl; |
888 | - } |
889 | - |
890 | - public void readAndParseNotes() { |
891 | - File[] fileList = path.listFiles(new NotesFilter()); |
892 | - |
893 | - // If there are no notes, warn the UI through an empty message |
894 | - if (fileList.length == 0) { |
895 | - parentHandler.sendEmptyMessage(Note.NO_NOTES); |
896 | - } |
897 | - |
898 | - for (File file : fileList) { |
899 | - |
900 | - // give a filename to a thread and ask to parse it when nothing's left to do its over |
901 | - pool.execute(new Worker(file)); |
902 | - } |
903 | - } |
904 | - |
905 | - /** |
906 | - * Simple filename filter that grabs files ending with .note |
907 | - * TODO move into its own static class in a util package |
908 | - */ |
909 | - class NotesFilter implements FilenameFilter { |
910 | - public boolean accept(File dir, String name) { |
911 | - return (name.endsWith(".note")); |
912 | - } |
913 | - } |
914 | - |
915 | - /** |
916 | - * The worker spawns a new note, parse the file its being given by the executor and add it to the NoteCollection |
917 | - */ |
918 | - class Worker implements Runnable { |
919 | - |
920 | - // the note to be loaded and parsed |
921 | - private Note note = new Note(); |
922 | - private File file; |
923 | - |
924 | - public Worker(File f) { |
925 | - file = f; |
926 | - } |
927 | - |
928 | - public void run() { |
929 | - |
930 | - note.setFileName(file.getAbsolutePath()); |
931 | - |
932 | - try { |
933 | - // Parsing |
934 | - // XML |
935 | - // Get a SAXParser from the SAXPArserFactory |
936 | - SAXParserFactory spf = SAXParserFactory.newInstance(); |
937 | - SAXParser sp = spf.newSAXParser(); |
938 | - |
939 | - // Get the XMLReader of the SAXParser we created |
940 | - XMLReader xr = sp.getXMLReader(); |
941 | - |
942 | - // Create a new ContentHandler, send it this note to fill and apply it to the XML-Reader |
943 | - NoteHandler xmlHandler = new NoteHandler(note); |
944 | - xr.setContentHandler(xmlHandler); |
945 | - |
946 | - |
947 | - // Create the proper input source based on if its a local note or a web note |
948 | - FileInputStream fin = new FileInputStream(file); |
949 | - BufferedReader in = new BufferedReader(new InputStreamReader(fin), 8192); |
950 | - InputSource is = new InputSource(in); |
951 | - |
952 | - if (Tomdroid.LOGGING_ENABLED) Log.v(TAG, "parsing note"); |
953 | - xr.parse(is); |
954 | - |
955 | - // TODO wrap and throw a new exception here |
956 | - } catch (ParserConfigurationException e) { |
957 | - e.printStackTrace(); |
958 | - } catch (SAXException e) { |
959 | - e.printStackTrace(); |
960 | - } catch (IOException e) { |
961 | - e.printStackTrace(); |
962 | - } |
963 | - |
964 | - synchronized (noteCollection) { |
965 | - noteCollection.addNote(note); |
966 | - } |
967 | - |
968 | - // notify UI that we are done here and send result |
969 | - warnHandler(); |
970 | - } |
971 | - |
972 | - private void warnHandler() { |
973 | - |
974 | - // notify the main UI that we are done here (sending an ok along with the note's title) |
975 | - Message msg = Message.obtain(); |
976 | - Bundle bundle = new Bundle(); |
977 | - bundle.putString(Note.TITLE, note.getTitle()); |
978 | - msg.setData(bundle); |
979 | - msg.what = Note.NOTE_RECEIVED_AND_VALID; |
980 | - |
981 | - parentHandler.sendMessage(msg); |
982 | - } |
983 | - |
984 | - } |
985 | -} |
986 | |
987 | === modified file 'src/org/tomdroid/util/NoteBuilder.java' |
988 | --- src/org/tomdroid/util/NoteBuilder.java 2009-06-21 20:25:16 +0000 |
989 | +++ src/org/tomdroid/util/NoteBuilder.java 2009-06-27 21:04:05 +0000 |
990 | @@ -60,7 +60,7 @@ |
991 | // the object being built |
992 | private Note note = new Note(); |
993 | |
994 | - private final String TAG = "NoteBuilder"; |
995 | + private final String TAG = Tomdroid.TAG;//"NoteBuilder"; |
996 | |
997 | // thread related |
998 | private Thread runner; |
- remove 'close' menu item as it is not necessary with Andro...
- remove 'close' menu item as it is not necessary with Android
- substitute OI About as about dialog
- use a Service to fill the ContentProvider (does not remove notes yet!) and let Android fill the list from the ContentProvider itself.