Merge lp:~tomdroid-dev/tomdroid/shortcuts into lp:~tomdroid-maintainers/tomdroid/main

Proposed by Piotr Adamski
Status: Merged
Merged at revision: 277
Proposed branch: lp:~tomdroid-dev/tomdroid/shortcuts
Merge into: lp:~tomdroid-maintainers/tomdroid/main
Diff against target: 1125 lines (+696/-109)
12 files modified
AndroidManifest.xml (+11/-2)
NEWS (+2/-0)
data/tomdroid-singlenote.svg (+310/-0)
res/layout/shortcuts_list.xml (+72/-0)
res/menu/main_longclick.xml (+4/-8)
res/values-pl/strings.xml (+4/-0)
res/values/strings.xml (+9/-0)
src/org/tomdroid/ui/Search.java (+1/-1)
src/org/tomdroid/ui/ShortcutActivity.java (+69/-0)
src/org/tomdroid/ui/Tomdroid.java (+27/-9)
src/org/tomdroid/ui/ViewNote.java (+98/-89)
src/org/tomdroid/util/NoteViewShortcutsHelper.java (+89/-0)
To merge this branch: bzr merge lp:~tomdroid-dev/tomdroid/shortcuts
Reviewer Review Type Date Requested Status
Olivier Bilodeau Approve
Review via email: mp+80607@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Stefan Hammer (j-4-deactivatedaccount) wrote :

Hi!

I already did a tomdroid icon therefore in all resolutions with an svg.
Maybe you can move the branch to tomdroid-dev, so that i can participate?

I just tried it - looks just great!

lp:~tomdroid-dev/tomdroid/shortcuts updated
261. By Piotr Adamski

turned off logging

Revision history for this message
Piotr Adamski (mcveat) wrote :

On Thu, Oct 27, 2011 at 8:05 PM, Stefan Hammer <email address hidden> wrote:
> I already did a tomdroid icon therefore in all resolutions with an svg.
> Maybe you can move the branch to tomdroid-dev, so that i can participate?

Done.

> I just tried it - looks just great!

I'm glad you liked it :)

Regards
Piotr

lp:~tomdroid-dev/tomdroid/shortcuts updated
262. By Stefan Hammer

Added new shortcut icon for all required screen resolutions. Also added new folder and icons for xhdpi, used in android 4.0

Revision history for this message
Stefan Hammer (j-4-deactivatedaccount) wrote :

I realized, there is still one issue. We don't have any design for the case, the note is deleted/not present any more.
At the moment a error message shows up, telling the user to file a bug if he can replicate this.

Is there a simple way to delete shortcuts when the note is not present any more? We could also delete the shortcut, when a removed note is called with it the first time. This is probably easier.

Revision history for this message
Piotr Adamski (mcveat) wrote :

On Thu, Oct 27, 2011 at 11:13 PM, Stefan Hammer <email address hidden> wrote:
> Is there a simple way to delete shortcuts when the note is not present any more? We could also delete the shortcut, when a removed note is called with it the first time. This is probably easier.

Those two shows that it is possible:
http://stackoverflow.com/questions/3480287/trying-to-uninstall-shortcut-but-shortcut-wont-go-away
http://chdorner.com/2011/01/31/android-home-screen-shortcuts-part-iii-remove-shortcuts/#respond

Though, I won't be able to check it before next week.

--
Pozdrawiam
Piotr Adamski
skype: piotr.adamski.

Revision history for this message
Stefan Hammer (j-4-deactivatedaccount) wrote :

I was looking, how other Android application are facing this problem:

The contact app just tells you in a toast message, that the contact could not be found any more.
The Bookmarks shortcut opens the browser and does not load a webpage.
Also the music app just tells you that the selected playlist is empty.

Therefore it is probably not necessary to delete the shortcut. If the note was actively deleted, then the user will know it and will also remove the shortcut by himself (at least after he is reminded by the error message.)

I will just change the error message, telling that the note was removed, but without the "bug report" part.

lp:~tomdroid-dev/tomdroid/shortcuts updated
263. By Stefan Hammer

Changed the error message, and made strings translateable.

Revision history for this message
Piotr Adamski (mcveat) wrote :

On Fri, Oct 28, 2011 at 12:30 PM, Stefan Hammer <email address hidden> wrote:
> I was looking, how other Android application are facing this problem:
>
> The contact app just tells you in a toast message, that the contact could not be found any more.
> The Bookmarks shortcut opens the browser and does not load a webpage.
> Also the music app just tells you that the selected playlist is empty.
>
> Therefore it is probably not necessary to delete the shortcut. If the note was actively deleted, then the user will know it and will also remove the shortcut by himself (at least after he is reminded by the error message.)
>
> I will just change the error message, telling that the note was removed, but without the "bug report" part.

I was thinking about something like activity that intercepts intents
from shortcuts and forwarding them to NoteView if note exists.
Otherwise it shows view/dialog saying something like "We couldn't find
that note, probably you removed it. If you want to remove the shortcut
press 'Remove'. If you believe that note should be here, please fill
bug report by clicking 'Report bug'".

What do you think?

--
Pozdrawiam
Piotr Adamski
skype: piotr.adamski.

Revision history for this message
Stefan Hammer (j-4-deactivatedaccount) wrote :

Sounds good to me.
If it is not too much work, you are welcomed to implement it.

I also saw a longpress menu entry "Add shortcut to Home" in the browser
bookmarks. Do you think, you can also do this for the longpress menu in
ListView? This way, the feature would be easier to find...

On 28/10/11 12:44, Piotr Adamski wrote:
> On Fri, Oct 28, 2011 at 12:30 PM, Stefan Hammer <email address hidden> wrote:
>> I was looking, how other Android application are facing this problem:
>>
>> The contact app just tells you in a toast message, that the contact could not be found any more.
>> The Bookmarks shortcut opens the browser and does not load a webpage.
>> Also the music app just tells you that the selected playlist is empty.
>>
>> Therefore it is probably not necessary to delete the shortcut. If the note was actively deleted, then the user will know it and will also remove the shortcut by himself (at least after he is reminded by the error message.)
>>
>> I will just change the error message, telling that the note was removed, but without the "bug report" part.
> I was thinking about something like activity that intercepts intents
> from shortcuts and forwarding them to NoteView if note exists.
> Otherwise it shows view/dialog saying something like "We couldn't find
> that note, probably you removed it. If you want to remove the shortcut
> press 'Remove'. If you believe that note should be here, please fill
> bug report by clicking 'Report bug'".
>
> What do you think?
>

Revision history for this message
Piotr Adamski (mcveat) wrote :

On Fri, Oct 28, 2011 at 12:55 PM, Stefan Hammer <email address hidden> wrote:
> Sounds good to me.
> If it is not too much work, you are welcomed to implement it.

> I also saw a longpress menu entry "Add shortcut to Home" in the browser
> bookmarks. Do you think, you can also do this for the longpress menu in
> ListView? This way, the feature would be easier to find...

I'll do both things on Tuesday.

Regards
Piotr

lp:~tomdroid-dev/tomdroid/shortcuts updated
264. By Piotr Adamski

shortcut removal logic

265. By Piotr Adamski

long click menu option to create a shortcut

Revision history for this message
Piotr Adamski (mcveat) wrote :

I've implemented both things (creating shortcut from context menu and removing it if it is not found) like agreed previously. Have a look.

Revision history for this message
Olivier Bilodeau (plaxx) wrote :

Please, in the future, don't change whitespace or re-organize imports. This is making patches, merging and searching history more complex for little value.

lp:~tomdroid-dev/tomdroid/shortcuts updated
266. By Olivier Bilodeau

merged lp:tomdroid

267. By Olivier Bilodeau

migrated logging to new TLog utility

268. By Olivier Bilodeau

NEWS entry for user-visible feature

Revision history for this message
Olivier Bilodeau (plaxx) wrote :

It's going in.

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-09-05 21:45:57 +0000
3+++ AndroidManifest.xml 2012-03-31 19:28:19 +0000
4@@ -63,11 +63,20 @@
5
6 </activity>
7
8+ <activity android:name=".ui.ShortcutActivity" android:label="@string/shortcut_menu_item_caption">
9+ <intent-filter>
10+ <action android:name="android.intent.action.CREATE_SHORTCUT"/>
11+ <category android:name="android.intent.category.DEFAULT"/>
12+ </intent-filter>
13+ </activity>
14+
15 <uses-library android:name="android.test.runner" />
16 </application>
17
18- <uses-permission android:name="android.permission.INTERNET" />
19- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
20+ <uses-permission android:name="android.permission.INTERNET" />
21+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
22+ <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
23+ <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
24
25 <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="org.tomdroid"></instrumentation>
26
27
28=== modified file 'NEWS'
29--- NEWS 2012-03-05 12:44:17 +0000
30+++ NEWS 2012-03-31 19:28:19 +0000
31@@ -13,6 +13,8 @@
32
33 -------------------------------------------------------------------------------
34 Versoin 0.?? released on ??
35+* Creating home-screen shortcuts to notes is now possible (Piotr Adamski,
36+ lp:882703)
37 * Tons of new translations by the awesome Translators on Launchpad
38 * Switched to the Launchpad Translation Platform (Stefan Hammer)
39 * New Japanese translation (Koichi Akabe)
40
41=== removed file 'data/icon-14.png'
42Binary files data/icon-14.png 2010-12-12 23:05:20 +0000 and data/icon-14.png 1970-01-01 00:00:00 +0000 differ
43=== removed file 'data/icon-192.png'
44Binary files data/icon-192.png 2011-06-18 15:32:28 +0000 and data/icon-192.png 1970-01-01 00:00:00 +0000 differ
45=== removed file 'data/icon-36.png'
46Binary files data/icon-36.png 2011-06-19 02:51:26 +0000 and data/icon-36.png 1970-01-01 00:00:00 +0000 differ
47=== removed file 'data/icon-48.png'
48Binary files data/icon-48.png 2011-06-19 02:51:26 +0000 and data/icon-48.png 1970-01-01 00:00:00 +0000 differ
49=== removed file 'data/icon-512.png'
50Binary files data/icon-512.png 2011-06-18 15:32:28 +0000 and data/icon-512.png 1970-01-01 00:00:00 +0000 differ
51=== removed file 'data/icon-64.png'
52Binary files data/icon-64.png 2011-06-18 12:59:36 +0000 and data/icon-64.png 1970-01-01 00:00:00 +0000 differ
53=== removed file 'data/icon-72.png'
54Binary files data/icon-72.png 2011-06-19 02:51:26 +0000 and data/icon-72.png 1970-01-01 00:00:00 +0000 differ
55=== added directory 'data/icon-launcher'
56=== added file 'data/icon-launcher/icon-14.png'
57Binary files data/icon-launcher/icon-14.png 1970-01-01 00:00:00 +0000 and data/icon-launcher/icon-14.png 2012-03-31 19:28:19 +0000 differ
58=== added file 'data/icon-launcher/icon-192.png'
59Binary files data/icon-launcher/icon-192.png 1970-01-01 00:00:00 +0000 and data/icon-launcher/icon-192.png 2012-03-31 19:28:19 +0000 differ
60=== added file 'data/icon-launcher/icon-36.png'
61Binary files data/icon-launcher/icon-36.png 1970-01-01 00:00:00 +0000 and data/icon-launcher/icon-36.png 2012-03-31 19:28:19 +0000 differ
62=== added file 'data/icon-launcher/icon-48.png'
63Binary files data/icon-launcher/icon-48.png 1970-01-01 00:00:00 +0000 and data/icon-launcher/icon-48.png 2012-03-31 19:28:19 +0000 differ
64=== added file 'data/icon-launcher/icon-512.png'
65Binary files data/icon-launcher/icon-512.png 1970-01-01 00:00:00 +0000 and data/icon-launcher/icon-512.png 2012-03-31 19:28:19 +0000 differ
66=== added file 'data/icon-launcher/icon-64.png'
67Binary files data/icon-launcher/icon-64.png 1970-01-01 00:00:00 +0000 and data/icon-launcher/icon-64.png 2012-03-31 19:28:19 +0000 differ
68=== added file 'data/icon-launcher/icon-72.png'
69Binary files data/icon-launcher/icon-72.png 1970-01-01 00:00:00 +0000 and data/icon-launcher/icon-72.png 2012-03-31 19:28:19 +0000 differ
70=== added file 'data/icon-launcher/icon-96.png'
71Binary files data/icon-launcher/icon-96.png 1970-01-01 00:00:00 +0000 and data/icon-launcher/icon-96.png 2012-03-31 19:28:19 +0000 differ
72=== added directory 'data/icon-shortcut'
73=== added file 'data/icon-shortcut/tomdroid-singlenote-36.png'
74Binary files data/icon-shortcut/tomdroid-singlenote-36.png 1970-01-01 00:00:00 +0000 and data/icon-shortcut/tomdroid-singlenote-36.png 2012-03-31 19:28:19 +0000 differ
75=== added file 'data/icon-shortcut/tomdroid-singlenote-48.png'
76Binary files data/icon-shortcut/tomdroid-singlenote-48.png 1970-01-01 00:00:00 +0000 and data/icon-shortcut/tomdroid-singlenote-48.png 2012-03-31 19:28:19 +0000 differ
77=== added file 'data/icon-shortcut/tomdroid-singlenote-72.png'
78Binary files data/icon-shortcut/tomdroid-singlenote-72.png 1970-01-01 00:00:00 +0000 and data/icon-shortcut/tomdroid-singlenote-72.png 2012-03-31 19:28:19 +0000 differ
79=== added file 'data/icon-shortcut/tomdroid-singlenote-96.png'
80Binary files data/icon-shortcut/tomdroid-singlenote-96.png 1970-01-01 00:00:00 +0000 and data/icon-shortcut/tomdroid-singlenote-96.png 2012-03-31 19:28:19 +0000 differ
81=== added file 'data/tomdroid-singlenote.svg'
82--- data/tomdroid-singlenote.svg 1970-01-01 00:00:00 +0000
83+++ data/tomdroid-singlenote.svg 2012-03-31 19:28:19 +0000
84@@ -0,0 +1,310 @@
85+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
86+<!-- Created with Inkscape (http://www.inkscape.org/) -->
87+
88+<svg
89+ xmlns:dc="http://purl.org/dc/elements/1.1/"
90+ xmlns:cc="http://creativecommons.org/ns#"
91+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
92+ xmlns:svg="http://www.w3.org/2000/svg"
93+ xmlns="http://www.w3.org/2000/svg"
94+ xmlns:xlink="http://www.w3.org/1999/xlink"
95+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
96+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
97+ inkscape:export-ydpi="90.000000"
98+ inkscape:export-xdpi="90.000000"
99+ inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
100+ width="48px"
101+ height="48px"
102+ id="svg11300"
103+ sodipodi:version="0.32"
104+ inkscape:version="0.48.1 r9760"
105+ sodipodi:docname="tomdroid-singlenote.svg"
106+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
107+ sodipodi:modified="true"
108+ version="1.1">
109+ <defs
110+ id="defs3">
111+ <inkscape:path-effect
112+ effect="spiro"
113+ id="path-effect4244"
114+ is_visible="true" />
115+ <linearGradient
116+ id="linearGradient2994">
117+ <stop
118+ id="stop2996"
119+ offset="0"
120+ style="stop-color:#000000;stop-opacity:1;" />
121+ <stop
122+ id="stop2998"
123+ offset="1"
124+ style="stop-color:#c9c9c9;stop-opacity:1;" />
125+ </linearGradient>
126+ <linearGradient
127+ id="linearGradient2974">
128+ <stop
129+ id="stop2976"
130+ offset="0"
131+ style="stop-color:#c1c1c1;stop-opacity:1;" />
132+ <stop
133+ id="stop2978"
134+ offset="1"
135+ style="stop-color:#acacac;stop-opacity:1;" />
136+ </linearGradient>
137+ <linearGradient
138+ id="linearGradient2966">
139+ <stop
140+ id="stop2968"
141+ offset="0"
142+ style="stop-color:#ffd1d1;stop-opacity:1;" />
143+ <stop
144+ style="stop-color:#ff1d1d;stop-opacity:1;"
145+ offset="0.5"
146+ id="stop3006" />
147+ <stop
148+ id="stop2970"
149+ offset="1"
150+ style="stop-color:#6f0000;stop-opacity:1;" />
151+ </linearGradient>
152+ <linearGradient
153+ inkscape:collect="always"
154+ id="linearGradient6417">
155+ <stop
156+ style="stop-color:black;stop-opacity:1;"
157+ offset="0"
158+ id="stop6419" />
159+ <stop
160+ style="stop-color:black;stop-opacity:0;"
161+ offset="1"
162+ id="stop6421" />
163+ </linearGradient>
164+ <linearGradient
165+ inkscape:collect="always"
166+ id="linearGradient6407">
167+ <stop
168+ style="stop-color:white;stop-opacity:1;"
169+ offset="0"
170+ id="stop6409" />
171+ <stop
172+ style="stop-color:white;stop-opacity:0;"
173+ offset="1"
174+ id="stop6411" />
175+ </linearGradient>
176+ <linearGradient
177+ id="linearGradient6377">
178+ <stop
179+ style="stop-color:#fff27e;stop-opacity:1;"
180+ offset="0"
181+ id="stop6379" />
182+ <stop
183+ style="stop-color:#edd400;stop-opacity:1;"
184+ offset="1"
185+ id="stop6381" />
186+ </linearGradient>
187+ <radialGradient
188+ inkscape:collect="always"
189+ xlink:href="#linearGradient6417"
190+ id="radialGradient3232"
191+ gradientUnits="userSpaceOnUse"
192+ gradientTransform="matrix(1.3194495,-0.00765637,0.00384809,0.6631555,-18.199333,18.582531)"
193+ cx="42.141071"
194+ cy="26.217604"
195+ fx="42.141071"
196+ fy="26.217604"
197+ r="5.2591065" />
198+ <radialGradient
199+ inkscape:collect="always"
200+ xlink:href="#linearGradient6407"
201+ id="radialGradient3916"
202+ gradientUnits="userSpaceOnUse"
203+ gradientTransform="matrix(9.7241373,-1.0744104e-7,0,18.970946,-385.27052,-653.71305)"
204+ cx="43.875"
205+ cy="35.90107"
206+ fx="43.875"
207+ fy="35.90107"
208+ r="20.21875" />
209+ <radialGradient
210+ inkscape:collect="always"
211+ xlink:href="#linearGradient6377"
212+ id="radialGradient3919"
213+ gradientUnits="userSpaceOnUse"
214+ gradientTransform="matrix(1.5050109,0,1.5345205e-8,1.9614971,-25.133441,-36.408804)"
215+ cx="48.507545"
216+ cy="35.338047"
217+ fx="48.507545"
218+ fy="35.338047"
219+ r="21.626934" />
220+ <radialGradient
221+ inkscape:collect="always"
222+ xlink:href="#linearGradient6407"
223+ id="radialGradient3947"
224+ gradientUnits="userSpaceOnUse"
225+ gradientTransform="matrix(9.7241373,-1.0744104e-7,0,18.970946,-385.27052,-653.42826)"
226+ cx="43.875"
227+ cy="35.90107"
228+ fx="43.875"
229+ fy="35.90107"
230+ r="20.21875" />
231+ </defs>
232+ <sodipodi:namedview
233+ stroke="#c4a000"
234+ fill="#edd400"
235+ id="base"
236+ pagecolor="#ffffff"
237+ bordercolor="#666666"
238+ borderopacity="0.25490196"
239+ inkscape:pageopacity="0.0"
240+ inkscape:pageshadow="2"
241+ inkscape:zoom="5.7395605"
242+ inkscape:cx="33.751231"
243+ inkscape:cy="35.023961"
244+ inkscape:current-layer="g3192"
245+ showgrid="true"
246+ inkscape:grid-bbox="true"
247+ inkscape:document-units="px"
248+ inkscape:showpageshadow="false"
249+ inkscape:window-width="1440"
250+ inkscape:window-height="848"
251+ inkscape:window-x="0"
252+ inkscape:window-y="26"
253+ inkscape:window-maximized="1" />
254+ <metadata
255+ id="metadata4">
256+ <rdf:RDF>
257+ <cc:Work
258+ rdf:about="">
259+ <dc:format>image/svg+xml</dc:format>
260+ <dc:type
261+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
262+ <dc:creator>
263+ <cc:Agent>
264+ <dc:title>Jakub Steiner</dc:title>
265+ </cc:Agent>
266+ </dc:creator>
267+ <dc:source>http://jimmac.musichall.cz</dc:source>
268+ <cc:license
269+ rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
270+ <dc:title />
271+ </cc:Work>
272+ <cc:License
273+ rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
274+ <cc:permits
275+ rdf:resource="http://web.resource.org/cc/Reproduction" />
276+ <cc:permits
277+ rdf:resource="http://web.resource.org/cc/Distribution" />
278+ <cc:requires
279+ rdf:resource="http://web.resource.org/cc/Notice" />
280+ <cc:permits
281+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
282+ <cc:requires
283+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
284+ <cc:requires
285+ rdf:resource="http://web.resource.org/cc/SourceCode" />
286+ </cc:License>
287+ </rdf:RDF>
288+ </metadata>
289+ <g
290+ id="layer1"
291+ inkscape:label="Layer 1"
292+ inkscape:groupmode="layer">
293+ <g
294+ id="g3192"
295+ transform="translate(0,3.2818261)">
296+ <path
297+ inkscape:connector-curvature="0"
298+ sodipodi:nodetypes="cccc"
299+ id="path6415"
300+ d="m 43.358146,37.10667 c -1.955027,-2.577031 -2.363101,-4.996371 -2.363101,-4.996371 0,0 -3.427308,1.967628 -6.704804,5.873144 4.10326,-0.07874 7.073315,-0.539629 9.067905,-0.876773 z"
301+ style="opacity:0.46629214;color:#000000;fill:url(#radialGradient3232);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
302+ <path
303+ style="fill:url(#radialGradient3919);fill-opacity:1;fill-rule:evenodd;stroke:#c4a000;stroke-width:1.20358479px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
304+ d="M 7.0748073,3.4640545 7.09375,37.972293 c 0,0 23.569096,-0.379906 24.417702,-0.409994 7.508882,-0.266237 10.541631,-2.429155 10.541631,-2.429155 0,0 -1.727734,-2.941123 -1.924805,-7.518229 0.09304,-4.854243 -0.19845,-24.1317182 -0.225696,-24.1324758 z"
305+ id="path2524"
306+ inkscape:connector-curvature="0"
307+ sodipodi:nodetypes="ccscccc" />
308+ <path
309+ sodipodi:nodetypes="csccsccscccccscccssccccsccccccccccsscccs"
310+ inkscape:connector-curvature="0"
311+ id="rect5365-8"
312+ d="m 26.40625,18.066043 c -0.0699,-0.0027 -0.125999,0.03637 -0.1875,0.0625 -0.184503,0.07839 -0.303633,0.266016 -0.3125,0.5 l -0.125,2.96875 c -1.124246,0.118287 -2.259295,0.448489 -3.375,0.96875 -1.238378,0.577466 -2.294058,1.353548 -3.15625,2.25 l -2.4375,-1.90625 c -0.246589,-0.19148 -0.578386,-0.158503 -0.75,0.0625 -0.171613,0.221006 -0.121589,0.558521 0.125,0.75 l 2.40625,1.84375 c -1.77245,2.265013 -2.346012,5.113828 -1.21875,7.53125 0.09478,0.203263 0.229692,0.373814 0.34375,0.5625 l 16.1875,-7.5625 c -0.07123,-0.208658 -0.123967,-0.421737 -0.21875,-0.625 -1.172353,-2.514119 -3.89038,-3.912332 -6.90625,-3.90625 l 0.125,-2.875 c 0.01182,-0.311979 -0.220385,-0.614405 -0.5,-0.625 z m 10.6875,7.1875 c -0.258365,0.0118 -0.500367,0.07109 -0.75,0.1875 -0.998535,0.465624 -1.465624,1.626465 -1,2.625 1.700417,3.663271 1.988865,7.756578 4.836635,6.409375 -0.392039,-0.795254 -1.476419,-3.812698 -1.466943,-6.636774 l -0.04522,-1.629953 C 38.257409,25.582989 37.868845,25.218143 37.09375,25.253543 z m -3.09375,1.5 -15.90625,7.40625 0.5,1.0625 0.125,0.3125 0.685699,0.761139 c 5.406993,0.0226 6.857349,-0.132806 9.585293,-0.114762 2.997479,0.03137 7.93409,-0.393167 9.971171,-1.245799 L 35.25,29.409793 l -0.75,-1.625 z m -17.75,8.0625 c -0.256948,0.0079 -0.531616,0.07109 -0.78125,0.1875 -0.644887,0.300715 -0.73318,0.749126 -0.817004,1.408501 0.262591,-0.01956 2.545204,-0.0582 3.772997,-0.07301 L 18.063401,35.695096 C 17.621784,35.192592 17.020844,34.792323 16.25,34.816043 z"
313+ style="fill:#d40000;fill-opacity:1;stroke:#ffffff;stroke-width:1.70000005;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
314+ <path
315+ sodipodi:nodetypes="ccssccccc"
316+ inkscape:connector-curvature="0"
317+ id="path6403"
318+ d="M 8.2909654,4.6548527 8.276419,36.767213 c 1.5140685,0.01637 13.549334,-0.276225 17.936687,-0.292207 6.657813,-0.02425 7.880729,-0.187611 10.265264,-0.749691 0.991388,-0.233689 3.406853,-0.980695 4.004516,-1.18784 -0.6232,-1.468795 -1.102231,-2.956253 -1.490862,-5.269428 -0.203285,-1.425146 -0.07204,-3.09413 -0.0647,-5.333435 0.0921,-2.139589 -0.186589,-19.2342051 -0.186589,-19.2342051 z"
319+ style="opacity:0.46600001;fill:none;stroke:url(#radialGradient3947);stroke-width:1.2195574px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
320+ <g
321+ id="g4229"
322+ transform="translate(0,0.2847933)">
323+ <path
324+ sodipodi:nodetypes="cccccscccc"
325+ style="fill:#97c024;fill-opacity:1;stroke:none"
326+ d="M 34.154899,26.376351 18.125,33.90625 l 0.5,1.03125 0.15625,0.3125 0.438851,1.053282 c 4.9051,-0.07007 9.545242,-0.07098 12.602306,-0.171077 2.821883,-0.0924 3.992221,-0.35808 6.409554,-0.957402 l -0.869085,-1.304336 c -1.471749,-2.509796 -1.990441,-3.575564 -2.893225,-6.185219 z"
327+ id="rect5365"
328+ inkscape:connector-curvature="0" />
329+ <path
330+ sodipodi:nodetypes="ccccccc"
331+ style="fill:#97c024;fill-opacity:1;stroke:none"
332+ d="m 16.31205,34.470101 c -0.2582,0.0097 -0.531616,0.07109 -0.78125,0.1875 -0.634414,0.295832 -0.892515,1.111882 -0.983761,1.754321 1.771234,-0.08119 1.977148,-0.04534 3.939753,-0.0911 L 18.18705,35.626319 c -0.349218,-0.748901 -1.1004,-1.185217 -1.875,-1.15625 z"
333+ id="rect5394"
334+ inkscape:connector-curvature="0" />
335+ <path
336+ sodipodi:nodetypes="cccccccc"
337+ style="fill:#97c024;fill-opacity:1;stroke:none"
338+ d="m 37.125,25 c -0.2582,0.0097 -0.500366,0.07109 -0.75,0.1875 -0.998535,0.465624 -1.557573,1.256869 -1.245947,2.347803 0,0 0.710827,3.26144 3.790796,7.480998 0.526502,-0.152989 0.928663,-0.267618 1.699658,-0.677415 -1.116286,-2.362942 -1.655744,-5.229672 -1.646269,-7.992148 l -0.0476,-0.201056 C 38.605678,25.431317 37.8996,24.971033 37.125,25 z"
339+ id="rect5394-2"
340+ inkscape:connector-curvature="0" />
341+ <g
342+ style="stroke:none"
343+ id="g5481"
344+ transform="matrix(0.90630778,-0.42261826,0.42261826,0.90630778,-1.2035996,29.947087)">
345+ <path
346+ id="path5418"
347+ d="m 24.65625,3.0625 c -4.968725,0 -9,3.3092317 -9,7.40625 0,0.224276 0.03887,0.43704 0.0625,0.65625 l 17.875,0 c 0.02363,-0.21921 0.0625,-0.431974 0.0625,-0.65625 0,-4.0970183 -4.031275,-7.40625 -9,-7.40625 z"
348+ style="fill:#97c024;fill-opacity:1;stroke:none"
349+ inkscape:connector-curvature="0" />
350+ <path
351+ transform="matrix(1.0212245,0,0,1.0212245,-1.4154165,-1.4231952)"
352+ d="m 22.160222,8.3357286 c 0,0.427136 -0.353329,0.7733981 -0.789182,0.7733981 -0.435853,0 -0.789181,-0.3462621 -0.789181,-0.7733981 0,-0.4271359 0.353328,-0.773398 0.789181,-0.773398 0.435853,0 0.789182,0.3462621 0.789182,0.773398 z"
353+ sodipodi:ry="0.77339804"
354+ sodipodi:rx="0.78918165"
355+ sodipodi:cy="8.3357286"
356+ sodipodi:cx="21.37104"
357+ id="path5449"
358+ style="fill:#ffffff;fill-opacity:1;stroke:none"
359+ sodipodi:type="arc" />
360+ <path
361+ transform="matrix(1.0212245,0,0,1.0212245,6.7121839,-1.4238284)"
362+ d="m 22.160222,8.3357286 c 0,0.427136 -0.353329,0.7733981 -0.789182,0.7733981 -0.435853,0 -0.789181,-0.3462621 -0.789181,-0.7733981 0,-0.4271359 0.353328,-0.773398 0.789181,-0.773398 0.435853,0 0.789182,0.3462621 0.789182,0.773398 z"
363+ sodipodi:ry="0.77339804"
364+ sodipodi:rx="0.78918165"
365+ sodipodi:cy="8.3357286"
366+ sodipodi:cx="21.37104"
367+ id="path5449-6"
368+ style="fill:#ffffff;fill-opacity:1;stroke:none"
369+ sodipodi:type="arc" />
370+ <rect
371+ ry="0.56354231"
372+ transform="matrix(0.88965349,-0.45663625,0.45663625,0.88965349,0,0)"
373+ rx="0.50507671"
374+ y="9.2116003"
375+ x="15.824705"
376+ height="5.0507627"
377+ width="1.0101534"
378+ id="rect5423"
379+ style="fill:#97c024;fill-opacity:1;stroke:none" />
380+ <rect
381+ ry="0.56354231"
382+ transform="matrix(-0.88965349,-0.45663625,-0.45663625,0.88965349,0,0)"
383+ rx="0.50507671"
384+ y="-13.159358"
385+ x="-27.690969"
386+ height="5.0507627"
387+ width="1.0101534"
388+ id="rect5423-6"
389+ style="fill:#97c024;fill-opacity:1;stroke:none" />
390+ </g>
391+ </g>
392+ </g>
393+ </g>
394+</svg>
395
396=== added file 'res/drawable-hdpi/ic_shortcut.png'
397Binary files res/drawable-hdpi/ic_shortcut.png 1970-01-01 00:00:00 +0000 and res/drawable-hdpi/ic_shortcut.png 2012-03-31 19:28:19 +0000 differ
398=== modified file 'res/drawable-ldpi/ic_launcher.png'
399Binary files res/drawable-ldpi/ic_launcher.png 2011-06-19 02:51:26 +0000 and res/drawable-ldpi/ic_launcher.png 2012-03-31 19:28:19 +0000 differ
400=== added file 'res/drawable-ldpi/ic_shortcut.png'
401Binary files res/drawable-ldpi/ic_shortcut.png 1970-01-01 00:00:00 +0000 and res/drawable-ldpi/ic_shortcut.png 2012-03-31 19:28:19 +0000 differ
402=== added file 'res/drawable-mdpi/ic_shortcut.png'
403Binary files res/drawable-mdpi/ic_shortcut.png 1970-01-01 00:00:00 +0000 and res/drawable-mdpi/ic_shortcut.png 2012-03-31 19:28:19 +0000 differ
404=== added directory 'res/drawable-xhdpi'
405=== added file 'res/drawable-xhdpi/ic_launcher.png'
406Binary files res/drawable-xhdpi/ic_launcher.png 1970-01-01 00:00:00 +0000 and res/drawable-xhdpi/ic_launcher.png 2012-03-31 19:28:19 +0000 differ
407=== added file 'res/drawable-xhdpi/ic_shortcut.png'
408Binary files res/drawable-xhdpi/ic_shortcut.png 1970-01-01 00:00:00 +0000 and res/drawable-xhdpi/ic_shortcut.png 2012-03-31 19:28:19 +0000 differ
409=== added file 'res/drawable-xhdpi/icon_actionbar_dot.png'
410Binary files res/drawable-xhdpi/icon_actionbar_dot.png 1970-01-01 00:00:00 +0000 and res/drawable-xhdpi/icon_actionbar_dot.png 2012-03-31 19:28:19 +0000 differ
411=== added file 'res/drawable-xhdpi/icon_actionbar_sync.png'
412Binary files res/drawable-xhdpi/icon_actionbar_sync.png 1970-01-01 00:00:00 +0000 and res/drawable-xhdpi/icon_actionbar_sync.png 2012-03-31 19:28:19 +0000 differ
413=== added file 'res/drawable-xhdpi/icon_actionbar_sync_background.png'
414Binary files res/drawable-xhdpi/icon_actionbar_sync_background.png 1970-01-01 00:00:00 +0000 and res/drawable-xhdpi/icon_actionbar_sync_background.png 2012-03-31 19:28:19 +0000 differ
415=== added file 'res/layout/shortcuts_list.xml'
416--- res/layout/shortcuts_list.xml 1970-01-01 00:00:00 +0000
417+++ res/layout/shortcuts_list.xml 2012-03-31 19:28:19 +0000
418@@ -0,0 +1,72 @@
419+<?xml version="1.0" encoding="utf-8"?>
420+<!--
421+ Tomdroid
422+ Tomboy on Android
423+ http://www.launchpad.net/tomdroid
424+
425+ Copyright 2011 Piotr Adamski <mcveat@gmail.com>
426+
427+ This file is part of Tomdroid.
428+
429+ Tomdroid is free software: you can redistribute it and/or modify
430+ it under the terms of the GNU General Public License as published by
431+ the Free Software Foundation, either version 3 of the License, or
432+ (at your option) any later version.
433+
434+ Tomdroid is distributed in the hope that it will be useful,
435+ but WITHOUT ANY WARRANTY; without even the implied warranty of
436+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
437+ GNU General Public License for more details.
438+
439+ You should have received a copy of the GNU General Public License
440+ along with Tomdroid. If not, see <http://www.gnu.org/licenses/>.
441+-->
442+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
443+ android:layout_width="fill_parent"
444+ android:layout_height="fill_parent"
445+ android:orientation="vertical"
446+ >
447+
448+ <LinearLayout android:layout_width="fill_parent"
449+ android:orientation="horizontal"
450+ android:layout_height="40dip"
451+ android:background="@drawable/actionbar_background">
452+ <ImageView
453+ android:id="@+id/action_icon"
454+ android:layout_width="40dip"
455+ android:layout_height="fill_parent"
456+ android:scaleType="fitStart"
457+ android:padding="0dip"
458+ android:src="@drawable/actionbar_icon"
459+ android:clickable="true"
460+ />
461+ <TextView android:id="@+id/shortcuts_view_caption"
462+ android:text="@string/shortcuts_view_caption"
463+ android:layout_width="fill_parent"
464+ android:layout_height="fill_parent"
465+ android:gravity="center"
466+ android:orientation="horizontal"
467+ android:textSize="18dip"
468+ android:textStyle="bold"
469+ android:paddingRight="42dip"/>
470+ </LinearLayout>
471+
472+
473+ <ListView android:id="@android:id/android:list"
474+ android:layout_width="fill_parent"
475+ android:layout_height="fill_parent"
476+ android:divider="#FFCCCCCC"
477+ android:dividerHeight="1px"
478+ />
479+
480+ <TextView android:id="@+id/list_empty"
481+ android:text="@string/strListEmptyNoNotes"
482+ android:layout_width="fill_parent"
483+ android:layout_height="fill_parent"
484+ android:singleLine="false"
485+ android:textSize="25dip"
486+ android:textStyle="bold"
487+ android:padding="30dip"
488+ android:textColor="#FF555555"
489+ />
490+</LinearLayout>
491
492=== modified file 'res/menu/main_longclick.xml'
493--- res/menu/main_longclick.xml 2011-07-14 03:22:02 +0000
494+++ res/menu/main_longclick.xml 2012-03-31 19:28:19 +0000
495@@ -1,10 +1,6 @@
496 <?xml version="1.0" encoding="utf-8"?>
497-<menu
498- xmlns:android="http://schemas.android.com/apk/res/android">
499- <item android:title="@string/view" android:id="@+id/view">
500-</item>
501-<item android:title="@string/send" android:id="@+id/menu_send">
502-</item>
503-
504-
505+<menu xmlns:android="http://schemas.android.com/apk/res/android">
506+ <item android:title="@string/view" android:id="@+id/view"/>
507+ <item android:title="@string/send" android:id="@+id/menu_send"/>
508+ <item android:title="@string/createShortcut" android:id="@+id/create_shortcut"/>
509 </menu>
510
511=== modified file 'res/values-pl/strings.xml'
512--- res/values-pl/strings.xml 2012-03-05 12:44:17 +0000
513+++ res/values-pl/strings.xml 2012-03-31 19:28:19 +0000
514@@ -98,6 +98,10 @@
515 <string name="textModified">Data modyfikacji:</string>
516 <string name="textToday">DziÅ›</string>
517 <string name="textYexterday">Wczoraj</string>
518+
519+ <!-- Shortcuts handling -->
520+ <string name="shortcuts_view_caption">Wybierz notatkÄ™</string>
521+ <string name="shortcut_menu_item_caption">Notatka Tomdroid</string>
522
523 <!--
524 Information that goes into the Android Market Application Listing.
525
526=== modified file 'res/values/strings.xml'
527--- res/values/strings.xml 2011-12-06 21:55:30 +0000
528+++ res/values/strings.xml 2012-03-31 19:28:19 +0000
529@@ -67,6 +67,9 @@
530 <string name="messageSyncAlreadyInProgress">Sync already in progress</string>
531 <string name="messageSyncError">There was an error trying to parse your note collection. If you are able to replicate the problem, please contact us!</string>
532 <string name="error">Error</string>
533+ <string name="titleNoteNotFound">No Such Note</string>
534+ <string name="messageNoteNotFound">The requested note could not be found. Maybe it was deleted or removed throug
535+ h synchronization.</string>
536
537 <!-- NoteSorting -->
538 <string name="menuSort">change sort</string>
539@@ -98,6 +101,12 @@
540 <string name="textModified">Modified:</string>
541 <string name="textToday">Today</string>
542 <string name="textYexterday">Yesterday</string>
543+
544+ <!-- Shortcuts handling -->
545+ <string name="shortcuts_view_caption">Choose Note</string>
546+ <string name="shortcut_menu_item_caption">Tomdroid Note</string>
547+ <string name="btnRemoveShortcut">Remove shortcut</string>
548+ <string name="createShortcut">Create shortcut</string>
549
550 <!--
551 Information that goes into the Android Market Application Listing.
552
553=== modified file 'src/org/tomdroid/ui/Search.java'
554--- src/org/tomdroid/ui/Search.java 2011-10-27 16:33:12 +0000
555+++ src/org/tomdroid/ui/Search.java 2012-03-31 19:28:19 +0000
556@@ -112,7 +112,7 @@
557 Cursor item = (Cursor) adapter.getItem(position);
558 int noteId = item.getInt(item.getColumnIndexOrThrow(Note.ID));
559
560- Uri intentUri = Uri.parse(Tomdroid.CONTENT_URI + "/" + noteId);
561+ Uri intentUri = Tomdroid.getNoteIntentUri(noteId);
562 Intent i = new Intent(Intent.ACTION_VIEW, intentUri, this, ViewNote.class);
563 startActivity(i);
564 }
565
566=== added file 'src/org/tomdroid/ui/ShortcutActivity.java'
567--- src/org/tomdroid/ui/ShortcutActivity.java 1970-01-01 00:00:00 +0000
568+++ src/org/tomdroid/ui/ShortcutActivity.java 2012-03-31 19:28:19 +0000
569@@ -0,0 +1,69 @@
570+/**
571+ Tomdroid
572+ Tomboy on Android
573+ http://www.launchpad.net/tomdroid
574+
575+ Copyright 2011 Piotr Adamski <mcveat@gmail.com>
576+
577+ This file is part of Tomdroid.
578+
579+ Tomdroid is free software: you can redistribute it and/or modify
580+ it under the terms of the GNU General Public License as published by
581+ the Free Software Foundation, either version 3 of the License, or
582+ (at your option) any later version.
583+
584+ Tomdroid is distributed in the hope that it will be useful,
585+ but WITHOUT ANY WARRANTY; without even the implied warranty of
586+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
587+ GNU General Public License for more details.
588+
589+ You should have received a copy of the GNU General Public License
590+ along with Tomdroid. If not, see <http://www.gnu.org/licenses/>.
591+ */
592+package org.tomdroid.ui;
593+
594+import android.app.ListActivity;
595+import android.database.Cursor;
596+import android.os.Bundle;
597+import android.util.Log;
598+import android.view.View;
599+import android.widget.ListAdapter;
600+import android.widget.ListView;
601+import org.tomdroid.NoteManager;
602+import org.tomdroid.R;
603+import org.tomdroid.util.NoteViewShortcutsHelper;
604+import org.tomdroid.util.TLog;
605+
606+/**
607+ * @author Piotr Adamski <mcveat@gmail.com>
608+ */
609+public class ShortcutActivity extends ListActivity {
610+ private final String TAG = ShortcutActivity.class.getName();
611+ private ListAdapter adapter;
612+
613+ @Override
614+ protected void onCreate(final Bundle savedInstanceState) {
615+ super.onCreate(savedInstanceState);
616+
617+ TLog.d(TAG, "creating shortcut...");
618+ setContentView(R.layout.shortcuts_list);
619+
620+ adapter = NoteManager.getListAdapter(this);
621+ setListAdapter(adapter);
622+ getListView().setEmptyView(findViewById(R.id.list_empty));
623+
624+ findViewById(R.id.action_icon).setOnClickListener(new View.OnClickListener() {
625+ public void onClick(final View view) {
626+ Tomdroid.ViewList(ShortcutActivity.this);
627+ }
628+ });
629+ }
630+
631+ @Override
632+ protected void onListItemClick(final ListView l, final View v, final int position, final long id) {
633+ final Cursor item = (Cursor) adapter.getItem(position);
634+ final NoteViewShortcutsHelper helper = new NoteViewShortcutsHelper(this);
635+ setResult(RESULT_OK, helper.getCreateShortcutIntent(item));
636+ finish();
637+ }
638+}
639
640=== modified file 'src/org/tomdroid/ui/Tomdroid.java'
641--- src/org/tomdroid/ui/Tomdroid.java 2011-10-27 17:15:13 +0000
642+++ src/org/tomdroid/ui/Tomdroid.java 2012-03-31 19:28:19 +0000
643@@ -24,6 +24,17 @@
644 */
645 package org.tomdroid.ui;
646
647+import org.tomdroid.Note;
648+import org.tomdroid.NoteManager;
649+import org.tomdroid.R;
650+import org.tomdroid.sync.ServiceAuth;
651+import org.tomdroid.sync.SyncManager;
652+import org.tomdroid.sync.SyncService;
653+import org.tomdroid.util.FirstNote;
654+import org.tomdroid.util.NoteViewShortcutsHelper;
655+import org.tomdroid.util.Preferences;
656+import org.tomdroid.util.Send;
657+
658 import android.app.AlertDialog;
659 import android.app.ListActivity;
660 import android.app.ProgressDialog;
661@@ -76,6 +87,10 @@
662 // Logging info
663 private static final String TAG = "Tomdroid";
664
665+ public static Uri getNoteIntentUri(long noteId) {
666+ return Uri.parse(CONTENT_URI + "/" + noteId);
667+ }
668+
669 // UI to data model glue
670 private TextView listEmptyView;
671 private ListAdapter adapter;
672@@ -117,7 +132,7 @@
673 listEmptyView = (TextView) findViewById(R.id.list_empty);
674 getListView().setEmptyView(listEmptyView);
675
676- registerForContextMenu((ListView)findViewById(android.R.id.list));
677+ registerForContextMenu(findViewById(android.R.id.list));
678 }
679
680 @Override
681@@ -163,17 +178,20 @@
682 AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
683 long noteId = info.id;
684 Uri intentUri = Uri.parse(Tomdroid.CONTENT_URI+"/"+noteId);
685- Note note = NoteManager.getNote(this, intentUri);
686-
687- switch (item.getItemId()) {
688- case R.id.menu_send:
689- (new Send(this, note)).send();
690+ Note note = NoteManager.getNote(this, intentUri);
691+
692+ switch (item.getItemId()) {
693+ case R.id.menu_send:
694+ (new Send(this, note)).send();
695 break;
696 case R.id.view:
697 this.ViewNote(noteId);
698 break;
699-
700- default:
701+ case R.id.create_shortcut:
702+ final NoteViewShortcutsHelper helper = new NoteViewShortcutsHelper(this);
703+ sendBroadcast(helper.getBroadcastableCreateShortcutIntent(intentUri, note.getTitle()));
704+ break;
705+ default:
706 break;
707 }
708
709@@ -254,7 +272,7 @@
710 }
711
712 public void ViewNote(long noteId) {
713- Uri intentUri = Uri.parse(Tomdroid.CONTENT_URI + "/" + noteId);
714+ Uri intentUri = getNoteIntentUri(noteId);
715 Intent i = new Intent(Intent.ACTION_VIEW, intentUri, this, ViewNote.class);
716 startActivity(i);
717 }
718
719=== modified file 'src/org/tomdroid/ui/ViewNote.java'
720--- src/org/tomdroid/ui/ViewNote.java 2011-10-27 16:33:12 +0000
721+++ src/org/tomdroid/ui/ViewNote.java 2012-03-31 19:28:19 +0000
722@@ -47,6 +47,7 @@
723 import org.tomdroid.sync.SyncManager;
724 import org.tomdroid.util.LinkifyPhone;
725 import org.tomdroid.util.NoteContentBuilder;
726+import org.tomdroid.util.NoteViewShortcutsHelper;
727 import org.tomdroid.util.Send;
728 import org.tomdroid.util.TLog;
729
730@@ -55,26 +56,28 @@
731
732 // TODO this class is starting to smell
733 public class ViewNote extends Activity {
734-
735- // UI elements
736+ public static final String CALLED_FROM_SHORTCUT_EXTRA = "org.tomdroid.CALLED_FROM_SHORTCUT";
737+ public static final String SHORTCUT_NAME = "org.tomdroid.SHORTCUT_NAME";
738+
739+ // UI elements
740 private TextView title;
741+
742 private TextView content;
743-
744- // Model objects
745+ // Model objects
746 private Note note;
747+
748 private SpannableStringBuilder noteContent;
749-
750+
751 // Logging info
752 private static final String TAG = "ViewNote";
753-
754- // UI feedback handler
755+ // UI feedback handler
756 private Handler syncMessageHandler = new SyncMessageHandler(this);
757
758 // TODO extract methods in here
759 @Override
760 protected void onCreate(Bundle savedInstanceState) {
761 super.onCreate(savedInstanceState);
762-
763+
764 setContentView(R.layout.note_view);
765 content = (TextView) findViewById(R.id.content);
766 content.setBackgroundColor(0xffffffff);
767@@ -83,68 +86,74 @@
768 title = (TextView) findViewById(R.id.title);
769 title.setTextColor(Color.DKGRAY);
770 title.setTextSize(18.0f);
771-
772- final Intent intent = getIntent();
773- Uri uri = intent.getData();
774-
775- if (uri != null) {
776-
777- // We were triggered by an Intent URI
778- TLog.d(TAG, "ViewNote started: Intent-filter triggered.");
779-
780- // TODO validate the good action?
781- // intent.getAction()
782-
783- // TODO verify that getNote is doing the proper validation
784- note = NoteManager.getNote(this, uri);
785-
786- if(note != null) {
787-
788- noteContent = note.getNoteContent(noteContentHandler);
789-
790- //Log.i(TAG, "THE NOTE IS: " + note.getXmlContent().toString());
791-
792- } else {
793-
794- TLog.d(TAG, "The note {0} doesn't exist", uri);
795-
796- // TODO put error string in a translatable resource
797- new AlertDialog.Builder(this)
798- .setMessage("The requested note could not be found. If you see this error " +
799- "and you are able to replicate it, please file a bug!")
800- .setTitle("Error")
801- .setNeutralButton("Ok", new OnClickListener() {
802- public void onClick(DialogInterface dialog, int which) {
803- dialog.dismiss();
804- finish();
805- }})
806- .show();
807- }
808- } else {
809-
810+
811+ Uri uri = getIntent().getData();
812+
813+ if (uri == null) {
814 TLog.d(TAG, "The Intent's data was null.");
815-
816- // TODO put error string in a translatable resource
817- new AlertDialog.Builder(this)
818- .setMessage("The requested note could not be found. If you see this error " +
819- " and you are able to replicate it, please file a bug!")
820- .setTitle(getString(R.string.error))
821- .setNeutralButton(getString(R.string.btnOk), new OnClickListener() {
822- public void onClick(DialogInterface dialog, int which) {
823- dialog.dismiss();
824- finish();
825- }})
826- .show();
827- }
828- }
829-
830+ showNoteNotFoundDialog(uri);
831+ } else handleNoteUri(uri);
832+ }
833+
834+ private void handleNoteUri(final Uri uri) {// We were triggered by an Intent URI
835+ TLog.d(TAG, "ViewNote started: Intent-filter triggered.");
836+
837+ // TODO validate the good action?
838+ // intent.getAction()
839+
840+ // TODO verify that getNote is doing the proper validation
841+ note = NoteManager.getNote(this, uri);
842+
843+ if(note != null) {
844+ noteContent = note.getNoteContent(noteContentHandler);
845+ } else {
846+ TLog.d(TAG, "The note "+uri+" doesn't exist");
847+ showNoteNotFoundDialog(uri);
848+ }
849+ }
850+
851+ private void showNoteNotFoundDialog(final Uri uri) {
852+ final AlertDialog.Builder builder = new AlertDialog.Builder(this);
853+ addCommonNoteNotFoundDialogElements(builder);
854+ addShortcutNoteNotFoundElements(uri, builder);
855+ builder.show();
856+ }
857+
858+ private void addShortcutNoteNotFoundElements(final Uri uri, final AlertDialog.Builder builder) {
859+ final boolean proposeShortcutRemoval;
860+ final boolean calledFromShortcut = getIntent().getBooleanExtra(CALLED_FROM_SHORTCUT_EXTRA, false);
861+ final String shortcutName = getIntent().getStringExtra(SHORTCUT_NAME);
862+ proposeShortcutRemoval = calledFromShortcut && uri != null && shortcutName != null;
863+
864+ if (proposeShortcutRemoval) {
865+ final Intent removeIntent = new NoteViewShortcutsHelper(this).getRemoveShortcutIntent(shortcutName, uri);
866+ builder.setPositiveButton(getString(R.string.btnRemoveShortcut), new OnClickListener() {
867+ public void onClick(final DialogInterface dialogInterface, final int i) {
868+ sendBroadcast(removeIntent);
869+ finish();
870+ }
871+ });
872+ }
873+ }
874+
875+ private void addCommonNoteNotFoundDialogElements(final AlertDialog.Builder builder) {
876+ builder.setMessage(getString(R.string.messageNoteNotFound))
877+ .setTitle(getString(R.string.titleNoteNotFound))
878+ .setNeutralButton(getString(R.string.btnOk), new OnClickListener() {
879+ public void onClick(DialogInterface dialog, int which) {
880+ dialog.dismiss();
881+ finish();
882+ }
883+ });
884+ }
885+
886 @Override
887 public void onResume(){
888 super.onResume();
889 SyncManager.setActivity(this);
890 SyncManager.setHandler(this.syncMessageHandler);
891 }
892-
893+
894 @Override
895 public boolean onCreateOptionsMenu(Menu menu) {
896
897@@ -154,7 +163,7 @@
898 return true;
899
900 }
901-
902+
903 @Override
904 public boolean onOptionsItemSelected(MenuItem item) {
905 switch (item.getItemId()) {
906@@ -164,42 +173,42 @@
907 }
908 return super.onOptionsItemSelected(item);
909 }
910-
911+
912 private void showNote() {
913
914 // show the note (spannable makes the TextView able to output styled text)
915 content.setText(noteContent, TextView.BufferType.SPANNABLE);
916 title.setText((CharSequence) note.getTitle());
917-
918+
919 // add links to stuff that is understood by Android except phone numbers because it's too aggressive
920 // TODO this is SLOWWWW!!!!
921 Linkify.addLinks(content, Linkify.EMAIL_ADDRESSES|Linkify.WEB_URLS|Linkify.MAP_ADDRESSES);
922-
923+
924 // Custom phone number linkifier (fixes lp:512204)
925 Linkify.addLinks(content, LinkifyPhone.PHONE_PATTERN, "tel:", LinkifyPhone.sPhoneNumberMatchFilter, Linkify.sPhoneNumberTransformFilter);
926-
927+
928 // This will create a link every time a note title is found in the text.
929 // The pattern contains a very dumb (title1)|(title2) escaped correctly
930 // Then we transform the url from the note name to the note id to avoid characters that mess up with the URI (ex: ?)
931- Linkify.addLinks(content,
932+ Linkify.addLinks(content,
933 buildNoteLinkifyPattern(),
934 Tomdroid.CONTENT_URI+"/",
935 null,
936 noteTitleTransformFilter);
937 }
938-
939+
940 private Handler noteContentHandler = new Handler() {
941
942 @Override
943 public void handleMessage(Message msg) {
944-
945+
946 //parsed ok - show
947 if(msg.what == NoteContentBuilder.PARSE_OK) {
948 showNote();
949
950 //parsed not ok - error
951 } else if(msg.what == NoteContentBuilder.PARSE_ERROR) {
952-
953+
954 // TODO put this String in a translatable resource
955 new AlertDialog.Builder(ViewNote.this)
956 .setMessage("The requested note could not be parsed. If you see this error " +
957@@ -214,47 +223,47 @@
958 }
959 }
960 };
961-
962+
963 /**
964 * Builds a regular expression pattern that will match any of the note title currently in the collection.
965 * Useful for the Linkify to create the links to the notes.
966 * @return regexp pattern
967 */
968 private Pattern buildNoteLinkifyPattern() {
969-
970+
971 StringBuilder sb = new StringBuilder();
972 Cursor cursor = NoteManager.getTitles(this);
973-
974- // cursor must not be null and must return more than 0 entry
975+
976+ // cursor must not be null and must return more than 0 entry
977 if (!(cursor == null || cursor.getCount() == 0)) {
978-
979+
980 String title;
981-
982+
983 cursor.moveToFirst();
984-
985+
986 do {
987 title = cursor.getString(cursor.getColumnIndexOrThrow(Note.TITLE));
988-
989- // Pattern.quote() here make sure that special characters in the note's title are properly escaped
990+
991+ // Pattern.quote() here make sure that special characters in the note's title are properly escaped
992 sb.append("("+Pattern.quote(title)+")|");
993-
994+
995 } while (cursor.moveToNext());
996-
997+
998 // get rid of the last | that is not needed (I know, its ugly.. better idea?)
999 String pt = sb.substring(0, sb.length()-1);
1000
1001 // return a compiled match pattern
1002 return Pattern.compile(pt);
1003-
1004+
1005 } else {
1006-
1007+
1008 // TODO send an error to the user
1009 TLog.d(TAG, "Cursor returned null or 0 notes");
1010 }
1011-
1012+
1013 return null;
1014 }
1015-
1016+
1017 // custom transform filter that takes the note's title part of the URI and translate it into the note id
1018 // this was done to avoid problems with invalid characters in URI (ex: ? is the query separator but could be in a note title)
1019 private TransformFilter noteTitleTransformFilter = new TransformFilter() {
1020@@ -262,9 +271,9 @@
1021 public String transformUrl(Matcher m, String str) {
1022
1023 int id = NoteManager.getNoteId(ViewNote.this, str);
1024-
1025+
1026 // return something like content://org.tomdroid.notes/notes/3
1027 return Tomdroid.CONTENT_URI.toString()+"/"+id;
1028- }
1029+ }
1030 };
1031 }
1032
1033=== added file 'src/org/tomdroid/util/NoteViewShortcutsHelper.java'
1034--- src/org/tomdroid/util/NoteViewShortcutsHelper.java 1970-01-01 00:00:00 +0000
1035+++ src/org/tomdroid/util/NoteViewShortcutsHelper.java 2012-03-31 19:28:19 +0000
1036@@ -0,0 +1,89 @@
1037+/**
1038+ Tomdroid
1039+ Tomboy on Android
1040+ http://www.launchpad.net/tomdroid
1041+
1042+ Copyright 2011 Piotr Adamski <mcveat@gmail.com>
1043+
1044+ This file is part of Tomdroid.
1045+
1046+ Tomdroid is free software: you can redistribute it and/or modify
1047+ it under the terms of the GNU General Public License as published by
1048+ the Free Software Foundation, either version 3 of the License, or
1049+ (at your option) any later version.
1050+
1051+ Tomdroid is distributed in the hope that it will be useful,
1052+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1053+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1054+ GNU General Public License for more details.
1055+
1056+ You should have received a copy of the GNU General Public License
1057+ along with Tomdroid. If not, see <http://www.gnu.org/licenses/>.
1058+ */
1059+package org.tomdroid.util;
1060+
1061+import android.content.Context;
1062+import android.content.Intent;
1063+import android.database.Cursor;
1064+import android.net.Uri;
1065+import org.tomdroid.Note;
1066+import org.tomdroid.R;
1067+import org.tomdroid.ui.Tomdroid;
1068+import org.tomdroid.ui.ViewNote;
1069+
1070+import static android.content.Intent.ShortcutIconResource.fromContext;
1071+
1072+/**
1073+ * @author Piotr Adamski <mcveat@gmail.com>
1074+ */
1075+public class NoteViewShortcutsHelper {
1076+ private final Context context;
1077+
1078+ public NoteViewShortcutsHelper(final Context context) {
1079+ this.context = context;
1080+ }
1081+
1082+ public Intent getCreateShortcutIntent(final Cursor item) {
1083+ final String name = getNoteTitle(item);
1084+ final Uri uri = Tomdroid.getNoteIntentUri(getNoteId(item));
1085+ return getCreateShortcutIntent(name, uri);
1086+ }
1087+
1088+ private Intent getCreateShortcutIntent(final String name, final Uri uri) {
1089+ Intent i = new Intent();
1090+ i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, getNoteViewShortcutIntent(name, uri));
1091+ i.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
1092+ final Intent.ShortcutIconResource icon = fromContext(context, R.drawable.ic_shortcut);
1093+ i.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
1094+ return i;
1095+ }
1096+
1097+ public Intent getBroadcastableCreateShortcutIntent(final Uri uri, final String name) {
1098+ final Intent i = getCreateShortcutIntent(name, uri);
1099+ i.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
1100+ return i;
1101+ }
1102+
1103+ public Intent getRemoveShortcutIntent(final String name, final Uri uri) {
1104+ final Intent i = new Intent();
1105+ i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, getNoteViewShortcutIntent(name, uri));
1106+ i.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
1107+ i.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
1108+ return i;
1109+ }
1110+
1111+ private Intent getNoteViewShortcutIntent(final String name, final Uri intentUri) {
1112+ final Intent i = new Intent(Intent.ACTION_VIEW, intentUri, context, ViewNote.class);
1113+ i.putExtra(ViewNote.CALLED_FROM_SHORTCUT_EXTRA, true);
1114+ i.putExtra(ViewNote.SHORTCUT_NAME, name);
1115+ return i;
1116+ }
1117+
1118+ private String getNoteTitle(final Cursor item) {
1119+ return item.getString(item.getColumnIndexOrThrow(Note.TITLE));
1120+ }
1121+
1122+ private int getNoteId(final Cursor item) {
1123+ return item.getInt(item.getColumnIndexOrThrow(Note.ID));
1124+ }
1125+}

Subscribers

People subscribed via source and target branches