1 | /* |
2 | * Tomdroid |
3 | * Tomboy on Android |
4 | * http://www.launchpad.net/tomdroid |
5 | * |
6 | * Copyright 2008, 2009, 2010, 2011 Olivier Bilodeau <olivier@bottomlesspit.org> |
7 | * Copyright 2009, Benoit Garret <benoit.garret_launchpad@gadz.org> |
8 | * |
9 | * This file is part of Tomdroid. |
10 | * |
11 | * Tomdroid is free software: you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation, either version 3 of the License, or |
14 | * (at your option) any later version. |
15 | * |
16 | * Tomdroid is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. |
20 | * |
21 | * You should have received a copy of the GNU General Public License |
22 | * along with Tomdroid. If not, see <http://www.gnu.org/licenses/>. |
23 | */ |
24 | package org.tomdroid; |
25 | |
26 | import java.util.regex.Matcher; |
27 | import java.util.regex.Pattern; |
28 | |
29 | import org.json.JSONArray; |
30 | import org.json.JSONObject; |
31 | import org.tomdroid.util.NoteContentBuilder; |
32 | import org.tomdroid.util.XmlUtils; |
33 | |
34 | import android.os.Handler; |
35 | import android.text.SpannableStringBuilder; |
36 | import android.text.format.Time; |
37 | import android.util.Log; |
38 | import android.util.TimeFormatException; |
39 | |
40 | public class Note { |
41 | |
42 | // Static references to fields (used in Bundles, ContentResolvers, etc.) |
43 | public static final String ID = "_id"; |
44 | public static final String GUID = "guid"; |
45 | public static final String TITLE = "title"; |
46 | public static final String MODIFIED_DATE = "modified_date"; |
47 | public static final String URL = "url"; |
48 | public static final String FILE = "file"; |
49 | public static final String TAGS = "tags"; |
50 | public static final String NOTE_CONTENT = "content"; |
51 | |
52 | // Logging info |
53 | private static final String TAG = "Note"; |
54 | |
55 | // Notes constants |
56 | // TODO this is a weird yellow that was usable for the android emulator, I must confirm this for real usage |
57 | public static final int NOTE_HIGHLIGHT_COLOR = 0xFFFFFF77; |
58 | public static final String NOTE_MONOSPACE_TYPEFACE = "monospace"; |
59 | public static final float NOTE_SIZE_SMALL_FACTOR = 1.0f; |
60 | public static final float NOTE_SIZE_LARGE_FACTOR = 1.5f; |
61 | public static final float NOTE_SIZE_HUGE_FACTOR = 1.8f; |
62 | |
63 | // Members |
64 | private SpannableStringBuilder noteContent; |
65 | private String xmlContent; |
66 | private String url; |
67 | private String fileName; |
68 | private String title; |
69 | private String tags; |
70 | private Time lastChangeDate; |
71 | private int dbId; |
72 | // TODO before guid were of the UUID object type, now they are simple strings |
73 | // but at some point we probably need to validate their uniqueness (per note collection or universe-wide?) |
74 | private String guid; |
75 | |
76 | // Date converter pattern (remove extra sub milliseconds from datetime string) |
77 | // ex: will strip 3020 in 2010-01-23T12:07:38.7743020-05:00 |
78 | private static final Pattern dateCleaner = Pattern.compile( |
79 | "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3})" + // matches: 2010-01-23T12:07:38.774 |
80 | ".+" + // matches what we are getting rid of |
81 | "([-\\+]\\d{2}:\\d{2})"); // matches timezone (-xx:xx or +xx:xx) |
82 | |
83 | public Note() { |
84 | tags = new String(); |
85 | } |
86 | |
87 | public Note(JSONObject json) { |
88 | |
89 | // These methods return an empty string if the key is not found |
90 | setTitle(XmlUtils.unescape(json.optString("title"))); |
91 | setGuid(json.optString("guid")); |
92 | setLastChangeDate(json.optString("last-change-date")); |
93 | setXmlContent(json.optString("note-content")); |
94 | JSONArray jtags = json.optJSONArray("tags"); |
95 | String tag; |
96 | tags = new String(); |
97 | if (jtags != null) { |
98 | for (int i = 0; i < jtags.length(); i++ ) { |
99 | tag = jtags.optString(i); |
100 | tags += tag + ","; |
101 | } |
102 | } |
103 | } |
104 | |
105 | public String getTags() { |
106 | return tags; |
107 | } |
108 | |
109 | public String getUrl() { |
110 | return url; |
111 | } |
112 | |
113 | public void setUrl(String url) { |
114 | this.url = url; |
115 | } |
116 | |
117 | public String getFileName() { |
118 | return fileName; |
119 | } |
120 | |
121 | public void setFileName(String fileName) { |
122 | this.fileName = fileName; |
123 | } |
124 | |
125 | public String getTitle() { |
126 | return title; |
127 | } |
128 | |
129 | public void setTitle(String title) { |
130 | this.title = title; |
131 | } |
132 | |
133 | public Time getLastChangeDate() { |
134 | return lastChangeDate; |
135 | } |
136 | |
137 | public void setLastChangeDate(Time lastChangeDate) { |
138 | this.lastChangeDate = lastChangeDate; |
139 | } |
140 | |
141 | public void setLastChangeDate(String lastChangeDateStr) throws TimeFormatException { |
142 | |
143 | // regexp out the sub-milliseconds from tomboy's datetime format |
144 | // Normal RFC 3339 format: 2008-10-13T16:00:00.000-07:00 |
145 | // Tomboy's (C# library) format: 2010-01-23T12:07:38.7743020-05:00 |
146 | Matcher m = dateCleaner.matcher(lastChangeDateStr); |
147 | if (m.find()) { |
148 | Log.d(TAG, "I had to clean out extra sub-milliseconds from the date"); |
149 | lastChangeDateStr = m.group(1)+m.group(2); |
150 | Log.v(TAG, "new date: "+lastChangeDateStr); |
151 | } |
152 | |
153 | lastChangeDate = new Time(); |
154 | lastChangeDate.parse3339(lastChangeDateStr); |
155 | } |
156 | |
157 | public int getDbId() { |
158 | return dbId; |
159 | } |
160 | |
161 | public void setDbId(int id) { |
162 | this.dbId = id; |
163 | } |
164 | |
165 | public String getGuid() { |
166 | return guid; |
167 | } |
168 | |
169 | public void setGuid(String guid) { |
170 | this.guid = guid; |
171 | } |
172 | |
173 | // TODO: should this handler passed around evolve into an observer pattern? |
174 | public SpannableStringBuilder getNoteContent(Handler handler) { |
175 | |
176 | // TODO not sure this is the right place to do this |
177 | noteContent = new NoteContentBuilder().setCaller(handler).setInputSource(xmlContent).build(); |
178 | return noteContent; |
179 | } |
180 | |
181 | public String getXmlContent() { |
182 | return xmlContent; |
183 | } |
184 | |
185 | public void setXmlContent(String xmlContent) { |
186 | this.xmlContent = xmlContent; |
187 | } |
188 | |
189 | @Override |
190 | public String toString() { |
191 | |
192 | return new String("Note: "+ getTitle() + " (" + getLastChangeDate() + ")"); |
193 | } |
194 | |
195 | } |