Merge lp:~mzanetti/reminders-app/contenthub-import into lp:reminders-app
- contenthub-import
- Merge into trunk
Proposed by
Michael Zanetti
Status: | Merged |
---|---|
Approved by: | Riccardo Padovani |
Approved revision: | 455 |
Merged at revision: | 461 |
Proposed branch: | lp:~mzanetti/reminders-app/contenthub-import |
Merge into: | lp:reminders-app |
Diff against target: |
597 lines (+335/-89) 11 files modified
CMakeLists.txt (+1/-0) manifest.json.in (+2/-1) reminders-contenthub.json (+8/-0) src/app/qml/components/NotesDelegate.qml (+1/-1) src/app/qml/components/StatusBar.qml (+35/-21) src/app/qml/reminders.qml (+112/-18) src/app/qml/ui/NotesPage.qml (+0/-3) src/libqtevernote/note.cpp (+15/-1) src/libqtevernote/note.h (+2/-0) src/libqtevernote/utils/enmldocument.cpp (+155/-44) src/libqtevernote/utils/enmldocument.h (+4/-0) |
To merge this branch: | bzr merge lp:~mzanetti/reminders-app/contenthub-import |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Riccardo Padovani | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+261919@code.launchpad.net |
Commit message
Make Notes a Content Hub Target for pictures and links
Description of the change
To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
review:
Approve
(continuous-integration)
Revision history for this message
Riccardo Padovani (rpadovani) wrote : | # |
Looks good (just three little things to change if you don't mind).
review:
Needs Fixing
- 455. By Michael Zanetti
-
fix nitpicks from review
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2015-02-16 22:01:20 +0000 | |||
3 | +++ CMakeLists.txt 2015-06-22 08:35:28 +0000 | |||
4 | @@ -74,6 +74,7 @@ | |||
5 | 74 | reminders.url-dispatcher | 74 | reminders.url-dispatcher |
6 | 75 | push-helper.json | 75 | push-helper.json |
7 | 76 | push-helper.apparmor | 76 | push-helper.apparmor |
8 | 77 | reminders-contenthub.json | ||
9 | 77 | DESTINATION ${CMAKE_INSTALL_PREFIX}) | 78 | DESTINATION ${CMAKE_INSTALL_PREFIX}) |
10 | 78 | install(FILES COPYING DESTINATION ${CMAKE_INSTALL_PREFIX}) | 79 | install(FILES COPYING DESTINATION ${CMAKE_INSTALL_PREFIX}) |
11 | 79 | else(CLICK_MODE) | 80 | else(CLICK_MODE) |
12 | 80 | 81 | ||
13 | === modified file 'manifest.json.in' | |||
14 | --- manifest.json.in 2015-03-20 11:16:35 +0000 | |||
15 | +++ manifest.json.in 2015-06-22 08:35:28 +0000 | |||
16 | @@ -8,7 +8,8 @@ | |||
17 | 8 | "account-service": "@ACCOUNT_SERVICE_DIR@/com.ubuntu.reminders_reminders.service", | 8 | "account-service": "@ACCOUNT_SERVICE_DIR@/com.ubuntu.reminders_reminders.service", |
18 | 9 | "apparmor": "reminders.apparmor", | 9 | "apparmor": "reminders.apparmor", |
19 | 10 | "desktop": "com.ubuntu.reminders.desktop", | 10 | "desktop": "com.ubuntu.reminders.desktop", |
21 | 11 | "urls": "reminders.url-dispatcher" | 11 | "urls": "reminders.url-dispatcher", |
22 | 12 | "content-hub": "reminders-contenthub.json" | ||
23 | 12 | }, | 13 | }, |
24 | 13 | "evernote-account-plugin": { | 14 | "evernote-account-plugin": { |
25 | 14 | "account-qml-plugin": "@ACCOUNT_QML_PLUGIN_DIR@/evernote", | 15 | "account-qml-plugin": "@ACCOUNT_QML_PLUGIN_DIR@/evernote", |
26 | 15 | 16 | ||
27 | === added file 'reminders-contenthub.json' | |||
28 | --- reminders-contenthub.json 1970-01-01 00:00:00 +0000 | |||
29 | +++ reminders-contenthub.json 2015-06-22 08:35:28 +0000 | |||
30 | @@ -0,0 +1,8 @@ | |||
31 | 1 | { | ||
32 | 2 | "destination": [ | ||
33 | 3 | "pictures", | ||
34 | 4 | "links", | ||
35 | 5 | "text" | ||
36 | 6 | ] | ||
37 | 7 | } | ||
38 | 8 | |||
39 | 0 | 9 | ||
40 | === modified file 'src/app/qml/components/NotesDelegate.qml' | |||
41 | --- src/app/qml/components/NotesDelegate.qml 2015-03-15 20:00:21 +0000 | |||
42 | +++ src/app/qml/components/NotesDelegate.qml 2015-06-22 08:35:28 +0000 | |||
43 | @@ -136,7 +136,7 @@ | |||
44 | 136 | Layout.fillHeight: true | 136 | Layout.fillHeight: true |
45 | 137 | text: "<font color=\"" + root.notebookColor + "\">" + | 137 | text: "<font color=\"" + root.notebookColor + "\">" + |
46 | 138 | Qt.formatDateTime(root.date, Qt.LocalDate) + | 138 | Qt.formatDateTime(root.date, Qt.LocalDate) + |
48 | 139 | " </font>" + root.content | 139 | " </font>" + root.content.replace("\n", " ").trim() |
49 | 140 | wrapMode: Text.WordWrap | 140 | wrapMode: Text.WordWrap |
50 | 141 | textFormat: Text.StyledText | 141 | textFormat: Text.StyledText |
51 | 142 | maximumLineCount: 2 | 142 | maximumLineCount: 2 |
52 | 143 | 143 | ||
53 | === modified file 'src/app/qml/components/StatusBar.qml' | |||
54 | --- src/app/qml/components/StatusBar.qml 2015-03-08 21:29:28 +0000 | |||
55 | +++ src/app/qml/components/StatusBar.qml 2015-06-22 08:35:28 +0000 | |||
56 | @@ -10,36 +10,50 @@ | |||
57 | 10 | 10 | ||
58 | 11 | property bool shown: false | 11 | property bool shown: false |
59 | 12 | property alias iconName: icon.name | 12 | property alias iconName: icon.name |
60 | 13 | property alias iconColor: icon.color | ||
61 | 13 | property alias text: label.text | 14 | property alias text: label.text |
62 | 15 | property alias showCancelButton: cancelButton.visible | ||
63 | 16 | |||
64 | 17 | signal cancel(); | ||
65 | 14 | 18 | ||
66 | 15 | Behavior on height { | 19 | Behavior on height { |
67 | 16 | UbuntuNumberAnimation {} | 20 | UbuntuNumberAnimation {} |
68 | 17 | } | 21 | } |
69 | 18 | 22 | ||
71 | 19 | ColumnLayout { | 23 | RowLayout { |
72 | 20 | id: statusBarContents | 24 | id: statusBarContents |
74 | 21 | anchors { left: parent.left; top: parent.top; right: parent.right } | 25 | anchors { left: parent.left; right: parent.right; leftMargin: units.gu(1); rightMargin: units.gu(1); verticalCenter: parent.verticalCenter } |
75 | 22 | spacing: units.gu(1) | 26 | spacing: units.gu(1) |
79 | 23 | 27 | Column { | |
77 | 24 | Row { | ||
78 | 25 | anchors { left: parent.left; right: parent.right; margins: units.gu(1) } | ||
80 | 26 | spacing: units.gu(1) | 28 | spacing: units.gu(1) |
97 | 27 | height: label.height | 29 | Layout.fillWidth: true |
98 | 28 | 30 | ||
99 | 29 | Icon { | 31 | Row { |
100 | 30 | id: icon | 32 | anchors { left: parent.left; right: parent.right } |
101 | 31 | height: units.gu(3) | 33 | spacing: units.gu(1) |
102 | 32 | width: height | 34 | height: label.height |
103 | 33 | color: UbuntuColors.red | 35 | |
104 | 34 | anchors.verticalCenter: parent.verticalCenter | 36 | Icon { |
105 | 35 | } | 37 | id: icon |
106 | 36 | 38 | height: units.gu(3) | |
107 | 37 | Label { | 39 | width: height |
108 | 38 | id: label | 40 | anchors.verticalCenter: parent.verticalCenter |
109 | 39 | width: parent.width - x | 41 | } |
110 | 40 | wrapMode: Text.WordWrap | 42 | |
111 | 41 | anchors.verticalCenter: parent.verticalCenter | 43 | Label { |
112 | 42 | } | 44 | id: label |
113 | 45 | width: parent.width - x | ||
114 | 46 | wrapMode: Text.WordWrap | ||
115 | 47 | anchors.verticalCenter: parent.verticalCenter | ||
116 | 48 | } | ||
117 | 49 | } | ||
118 | 50 | } | ||
119 | 51 | |||
120 | 52 | Button { | ||
121 | 53 | id: cancelButton | ||
122 | 54 | Layout.preferredWidth: height | ||
123 | 55 | iconName: "cancel" | ||
124 | 56 | onClicked: root.cancel(); | ||
125 | 43 | } | 57 | } |
126 | 44 | } | 58 | } |
127 | 45 | } | 59 | } |
128 | 46 | 60 | ||
129 | === modified file 'src/app/qml/reminders.qml' | |||
130 | --- src/app/qml/reminders.qml 2015-06-12 09:48:22 +0000 | |||
131 | +++ src/app/qml/reminders.qml 2015-06-22 08:35:28 +0000 | |||
132 | @@ -26,6 +26,7 @@ | |||
133 | 26 | import Ubuntu.OnlineAccounts 0.1 | 26 | import Ubuntu.OnlineAccounts 0.1 |
134 | 27 | import Ubuntu.OnlineAccounts.Client 0.1 | 27 | import Ubuntu.OnlineAccounts.Client 0.1 |
135 | 28 | import Ubuntu.PushNotifications 0.1 | 28 | import Ubuntu.PushNotifications 0.1 |
136 | 29 | import Ubuntu.Content 1.0 | ||
137 | 29 | import "components" | 30 | import "components" |
138 | 30 | import "ui" | 31 | import "ui" |
139 | 31 | 32 | ||
140 | @@ -79,6 +80,45 @@ | |||
141 | 79 | } | 80 | } |
142 | 80 | } | 81 | } |
143 | 81 | 82 | ||
144 | 83 | property var importTransfer: null | ||
145 | 84 | function handleImportTransfer(note) { | ||
146 | 85 | if (importTransfer == null) return; | ||
147 | 86 | |||
148 | 87 | for (var i = 0; i < importTransfer.items.length; i++) { | ||
149 | 88 | var url = importTransfer.items[i].url; | ||
150 | 89 | switch (importTransfer.contentType) { | ||
151 | 90 | case ContentType.Links: | ||
152 | 91 | note.insertLink(note.plaintextContent.length, url) | ||
153 | 92 | break; | ||
154 | 93 | default: | ||
155 | 94 | note.attachFile(note.plaintextContent.length, url) | ||
156 | 95 | break; | ||
157 | 96 | } | ||
158 | 97 | } | ||
159 | 98 | note.save(); | ||
160 | 99 | importTransfer = null; | ||
161 | 100 | } | ||
162 | 101 | |||
163 | 102 | Connections { | ||
164 | 103 | target: ContentHub | ||
165 | 104 | onImportRequested: { | ||
166 | 105 | importTransfer = transfer; | ||
167 | 106 | var popup = PopupUtils.open(importQuestionComponent); | ||
168 | 107 | popup.accepted.connect(function(createNew) { | ||
169 | 108 | PopupUtils.close(popup); | ||
170 | 109 | if (createNew) { | ||
171 | 110 | var note = NotesStore.createNote(i18n.tr("Untitled")); | ||
172 | 111 | handleImportTransfer(note); | ||
173 | 112 | } | ||
174 | 113 | }) | ||
175 | 114 | |||
176 | 115 | popup.rejected.connect(function() { | ||
177 | 116 | PopupUtils.close(popup); | ||
178 | 117 | importTransfer = null; | ||
179 | 118 | }) | ||
180 | 119 | } | ||
181 | 120 | } | ||
182 | 121 | |||
183 | 82 | Timer { | 122 | Timer { |
184 | 83 | id: connectDelayTimer | 123 | id: connectDelayTimer |
185 | 84 | interval: 2000 | 124 | interval: 2000 |
186 | @@ -107,6 +147,10 @@ | |||
187 | 107 | conflictMode = false; | 147 | conflictMode = false; |
188 | 108 | } | 148 | } |
189 | 109 | 149 | ||
190 | 150 | if (importTransfer != null) { | ||
191 | 151 | handleImportTransfer(note); | ||
192 | 152 | } | ||
193 | 153 | |||
194 | 110 | print("displayNote:", note.guid) | 154 | print("displayNote:", note.guid) |
195 | 111 | note.load(true); | 155 | note.load(true); |
196 | 112 | if (root.narrowMode) { | 156 | if (root.narrowMode) { |
197 | @@ -436,26 +480,43 @@ | |||
198 | 436 | } | 480 | } |
199 | 437 | } | 481 | } |
200 | 438 | 482 | ||
202 | 439 | StatusBar { | 483 | Column { |
203 | 440 | id: statusBar | 484 | id: statusBar |
204 | 441 | anchors { left: parent.left; right: parent.right; top: parent.top; topMargin: units.gu(9) } | 485 | anchors { left: parent.left; right: parent.right; top: parent.top; topMargin: units.gu(9) } |
222 | 442 | color: root.backgroundColor | 486 | |
223 | 443 | shown: text | 487 | StatusBar { |
224 | 444 | text: EvernoteConnection.error || NotesStore.error | 488 | anchors { left: parent.left; right: parent.right } |
225 | 445 | iconName: "sync-error" | 489 | color: root.backgroundColor |
226 | 446 | 490 | shown: text | |
227 | 447 | Timer { | 491 | text: EvernoteConnection.error || NotesStore.error |
228 | 448 | interval: 5000 | 492 | iconName: "sync-error" |
229 | 449 | repeat: true | 493 | iconColor: UbuntuColors.red |
230 | 450 | running: NotesStore.error | 494 | showCancelButton: true |
231 | 451 | onTriggered: NotesStore.clearError(); | 495 | |
232 | 452 | } | 496 | onCancel: { |
233 | 453 | 497 | NotesStore.clearError(); | |
234 | 454 | MouseArea { | 498 | } |
235 | 455 | anchors.fill: parent | 499 | |
236 | 456 | onClicked: NotesStore.clearError(); | 500 | Timer { |
237 | 457 | } | 501 | interval: 5000 |
238 | 458 | 502 | repeat: true | |
239 | 503 | running: NotesStore.error | ||
240 | 504 | onTriggered: NotesStore.clearError(); | ||
241 | 505 | } | ||
242 | 506 | } | ||
243 | 507 | |||
244 | 508 | StatusBar { | ||
245 | 509 | anchors { left: parent.left; right: parent.right } | ||
246 | 510 | color: root.backgroundColor | ||
247 | 511 | shown: importTransfer != null | ||
248 | 512 | text: importTransfer.items.length === 1 ? i18n.tr("Select note to attach imported file") : i18n.tr("Select note to attach imported files") | ||
249 | 513 | iconName: "document-save" | ||
250 | 514 | showCancelButton: true | ||
251 | 515 | |||
252 | 516 | onCancel: { | ||
253 | 517 | importTransfer = null; | ||
254 | 518 | } | ||
255 | 519 | } | ||
256 | 459 | } | 520 | } |
257 | 460 | 521 | ||
258 | 461 | PageStack { | 522 | PageStack { |
259 | @@ -673,4 +734,37 @@ | |||
260 | 673 | } | 734 | } |
261 | 674 | } | 735 | } |
262 | 675 | } | 736 | } |
263 | 737 | |||
264 | 738 | Component { | ||
265 | 739 | id: importQuestionComponent | ||
266 | 740 | |||
267 | 741 | Dialog { | ||
268 | 742 | id: importDialog | ||
269 | 743 | title: importTransfer.items.length > 1 ? | ||
270 | 744 | i18n.tr("Importing %1 items").arg(importTransfer.items.length) | ||
271 | 745 | : i18n.tr("Importing 1 item") | ||
272 | 746 | text: importTransfer.items.length > 1 ? | ||
273 | 747 | i18n.tr("Do you want to create a new note for those items or do you want to attach them to an existing note?") | ||
274 | 748 | : i18n.tr("Do you want to create a new note for this item or do you want to attach it to an existing note?") | ||
275 | 749 | |||
276 | 750 | signal accepted(bool createNew); | ||
277 | 751 | signal rejected(); | ||
278 | 752 | |||
279 | 753 | Button { | ||
280 | 754 | text: i18n.tr("Create new note") | ||
281 | 755 | onClicked: importDialog.accepted(true) | ||
282 | 756 | color: UbuntuColors.green | ||
283 | 757 | } | ||
284 | 758 | Button { | ||
285 | 759 | text: i18n.tr("Attach to existing note") | ||
286 | 760 | onClicked: importDialog.accepted(false); | ||
287 | 761 | color: UbuntuColors.blue | ||
288 | 762 | } | ||
289 | 763 | Button { | ||
290 | 764 | text: i18n.tr("Cancel import") | ||
291 | 765 | onClicked: importDialog.rejected(); | ||
292 | 766 | color: UbuntuColors.red | ||
293 | 767 | } | ||
294 | 768 | } | ||
295 | 769 | } | ||
296 | 676 | } | 770 | } |
297 | 677 | 771 | ||
298 | === modified file 'src/app/qml/ui/NotesPage.qml' | |||
299 | --- src/app/qml/ui/NotesPage.qml 2015-06-11 22:02:25 +0000 | |||
300 | +++ src/app/qml/ui/NotesPage.qml 2015-06-22 08:35:28 +0000 | |||
301 | @@ -142,15 +142,12 @@ | |||
302 | 142 | } | 142 | } |
303 | 143 | 143 | ||
304 | 144 | function sortOrderToString(sortOrder){ | 144 | function sortOrderToString(sortOrder){ |
305 | 145 | print("asking for sortOrder", sortOrder, Notes.SortOrderDateUpdatedNewest) | ||
306 | 146 | switch(sortOrder) { | 145 | switch(sortOrder) { |
307 | 147 | case Notes.SortOrderDateCreatedNewest: | 146 | case Notes.SortOrderDateCreatedNewest: |
308 | 148 | case Notes.SortOrderDateCreatedOldest: | 147 | case Notes.SortOrderDateCreatedOldest: |
309 | 149 | print("returning createdString") | ||
310 | 150 | return "createdString"; | 148 | return "createdString"; |
311 | 151 | case Notes.SortOrderDateUpdatedNewest: | 149 | case Notes.SortOrderDateUpdatedNewest: |
312 | 152 | case Notes.SortOrderDateUpdatedOldest: | 150 | case Notes.SortOrderDateUpdatedOldest: |
313 | 153 | print("returning updatedString") | ||
314 | 154 | return "updatedString"; | 151 | return "updatedString"; |
315 | 155 | case Notes.SortOrderTitleAscending: | 152 | case Notes.SortOrderTitleAscending: |
316 | 156 | case Notes.SortOrderTitleDescending: | 153 | case Notes.SortOrderTitleDescending: |
317 | 157 | 154 | ||
318 | === modified file 'src/libqtevernote/note.cpp' | |||
319 | --- src/libqtevernote/note.cpp 2015-06-03 17:45:45 +0000 | |||
320 | +++ src/libqtevernote/note.cpp 2015-06-22 08:35:28 +0000 | |||
321 | @@ -277,7 +277,7 @@ | |||
322 | 277 | 277 | ||
323 | 278 | QString Note::plaintextContent() const | 278 | QString Note::plaintextContent() const |
324 | 279 | { | 279 | { |
326 | 280 | return m_content.toPlaintext().trimmed(); | 280 | return m_content.toPlaintext(); |
327 | 281 | } | 281 | } |
328 | 282 | 282 | ||
329 | 283 | QString Note::tagline() const | 283 | QString Note::tagline() const |
330 | @@ -570,6 +570,20 @@ | |||
331 | 570 | NotesStore::instance()->untagNote(m_guid, tagGuid); | 570 | NotesStore::instance()->untagNote(m_guid, tagGuid); |
332 | 571 | } | 571 | } |
333 | 572 | 572 | ||
334 | 573 | void Note::insertText(int position, const QString &text) | ||
335 | 574 | { | ||
336 | 575 | m_content.insertText(position, text); | ||
337 | 576 | m_tagline = m_content.toPlaintext().left(100); | ||
338 | 577 | emit contentChanged(); | ||
339 | 578 | } | ||
340 | 579 | |||
341 | 580 | void Note::insertLink(int position, const QString &url) | ||
342 | 581 | { | ||
343 | 582 | m_content.insertLink(position, url); | ||
344 | 583 | m_tagline = m_content.toPlaintext().left(100); | ||
345 | 584 | emit contentChanged(); | ||
346 | 585 | } | ||
347 | 586 | |||
348 | 573 | int Note::renderWidth() const | 587 | int Note::renderWidth() const |
349 | 574 | { | 588 | { |
350 | 575 | return m_content.renderWidth(); | 589 | return m_content.renderWidth(); |
351 | 576 | 590 | ||
352 | === modified file 'src/libqtevernote/note.h' | |||
353 | --- src/libqtevernote/note.h 2015-03-15 20:00:21 +0000 | |||
354 | +++ src/libqtevernote/note.h 2015-06-22 08:35:28 +0000 | |||
355 | @@ -165,6 +165,8 @@ | |||
356 | 165 | Q_INVOKABLE void attachFile(int position, const QUrl &fileName); | 165 | Q_INVOKABLE void attachFile(int position, const QUrl &fileName); |
357 | 166 | Q_INVOKABLE void addTag(const QString &tagGuid); | 166 | Q_INVOKABLE void addTag(const QString &tagGuid); |
358 | 167 | Q_INVOKABLE void removeTag(const QString &tagGuid); | 167 | Q_INVOKABLE void removeTag(const QString &tagGuid); |
359 | 168 | Q_INVOKABLE void insertText(int position, const QString &text); | ||
360 | 169 | Q_INVOKABLE void insertLink(int position, const QString &url); | ||
361 | 168 | 170 | ||
362 | 169 | int renderWidth() const; | 171 | int renderWidth() const; |
363 | 170 | void setRenderWidth(int renderWidth); | 172 | void setRenderWidth(int renderWidth); |
364 | 171 | 173 | ||
365 | === modified file 'src/libqtevernote/utils/enmldocument.cpp' | |||
366 | --- src/libqtevernote/utils/enmldocument.cpp 2015-04-13 20:42:38 +0000 | |||
367 | +++ src/libqtevernote/utils/enmldocument.cpp 2015-06-22 08:35:28 +0000 | |||
368 | @@ -486,48 +486,161 @@ | |||
369 | 486 | 486 | ||
370 | 487 | void EnmlDocument::attachFile(int position, const QString &hash, const QString &type) | 487 | void EnmlDocument::attachFile(int position, const QString &hash, const QString &type) |
371 | 488 | { | 488 | { |
414 | 489 | QXmlStreamReader reader(m_enml); | 489 | qCDebug(dcEnml) << "Attaching file at position" << position; |
415 | 490 | 490 | QXmlStreamReader reader(m_enml); | |
416 | 491 | QString output; | 491 | |
417 | 492 | QXmlStreamWriter writer(&output); | 492 | QString output; |
418 | 493 | writer.writeStartDocument(); | 493 | QXmlStreamWriter writer(&output); |
419 | 494 | writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">"); | 494 | writer.writeStartDocument(); |
420 | 495 | 495 | writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">"); | |
421 | 496 | int textPos = 0; | 496 | |
422 | 497 | bool inserted = false; | 497 | int textPos = 0; |
423 | 498 | 498 | bool inserted = false; | |
424 | 499 | while (!reader.atEnd() && !reader.hasError()) { | 499 | |
425 | 500 | QXmlStreamReader::TokenType token = reader.readNext(); | 500 | while (!reader.atEnd() && !reader.hasError()) { |
426 | 501 | 501 | QXmlStreamReader::TokenType token = reader.readNext(); | |
427 | 502 | if (token == QXmlStreamReader::StartElement) { | 502 | |
428 | 503 | writer.writeStartElement(reader.name().toString()); | 503 | if (token == QXmlStreamReader::StartElement) { |
429 | 504 | writer.writeAttributes(reader.attributes()); | 504 | writer.writeStartElement(reader.name().toString()); |
430 | 505 | } | 505 | writer.writeAttributes(reader.attributes()); |
431 | 506 | 506 | } | |
432 | 507 | if (token == QXmlStreamReader::Characters) { | 507 | |
433 | 508 | QString textString = reader.text().toString(); | 508 | if (token == QXmlStreamReader::Characters) { |
434 | 509 | if (textPos <= position && textPos + textString.length() > position) { | 509 | QString textString = reader.text().toString(); |
435 | 510 | writer.writeCharacters(textString.left(position - textPos)); | 510 | if (textPos <= position && textPos + textString.length() > position) { |
436 | 511 | 511 | writer.writeCharacters(textString.left(position - textPos)); | |
437 | 512 | writer.writeStartElement("en-media"); | 512 | |
438 | 513 | writer.writeAttribute("hash", hash); | 513 | writer.writeStartElement("en-media"); |
439 | 514 | writer.writeAttribute("type", type); | 514 | writer.writeAttribute("hash", hash); |
440 | 515 | writer.writeEndElement(); | 515 | writer.writeAttribute("type", type); |
441 | 516 | inserted = true; | 516 | writer.writeEndElement(); |
442 | 517 | 517 | inserted = true; | |
443 | 518 | writer.writeCharacters(textString.right(textString.length() - (position - textPos))); | 518 | |
444 | 519 | } else { | 519 | writer.writeCharacters(textString.right(textString.length() - (position - textPos))); |
445 | 520 | writer.writeCharacters(reader.text().toString()); | 520 | } else { |
446 | 521 | } | 521 | writer.writeCharacters(reader.text().toString()); |
447 | 522 | textPos += textString.length(); | 522 | } |
448 | 523 | } | 523 | textPos += textString.length(); |
449 | 524 | if (token == QXmlStreamReader::EndElement) { | 524 | } |
450 | 525 | 525 | if (token == QXmlStreamReader::EndElement) { | |
451 | 526 | // The above logic would fail on an empty note | 526 | |
452 | 527 | if (reader.name() == "en-note" && !inserted) { | 527 | // The above logic would fail on an empty note |
453 | 528 | writer.writeStartElement("en-media"); | 528 | if (reader.name() == "en-note" && !inserted) { |
454 | 529 | writer.writeAttribute("hash", hash); | 529 | writer.writeStartElement("en-media"); |
455 | 530 | writer.writeAttribute("type", type); | 530 | writer.writeAttribute("hash", hash); |
456 | 531 | writer.writeAttribute("type", type); | ||
457 | 532 | writer.writeEndElement(); | ||
458 | 533 | } | ||
459 | 534 | |||
460 | 535 | writer.writeEndElement(); | ||
461 | 536 | } | ||
462 | 537 | } | ||
463 | 538 | m_enml = output; | ||
464 | 539 | } | ||
465 | 540 | |||
466 | 541 | void EnmlDocument::insertText(int position, const QString &text) | ||
467 | 542 | { | ||
468 | 543 | qCDebug(dcEnml) << "Inserting Text at position" << position; | ||
469 | 544 | |||
470 | 545 | QXmlStreamReader reader(m_enml); | ||
471 | 546 | |||
472 | 547 | QString output; | ||
473 | 548 | QXmlStreamWriter writer(&output); | ||
474 | 549 | writer.writeStartDocument(); | ||
475 | 550 | writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">"); | ||
476 | 551 | |||
477 | 552 | int textPos = 0; | ||
478 | 553 | bool inserted = false; | ||
479 | 554 | |||
480 | 555 | while (!reader.atEnd() && !reader.hasError()) { | ||
481 | 556 | QXmlStreamReader::TokenType token = reader.readNext(); | ||
482 | 557 | |||
483 | 558 | if (token == QXmlStreamReader::StartElement) { | ||
484 | 559 | writer.writeStartElement(reader.name().toString()); | ||
485 | 560 | writer.writeAttributes(reader.attributes()); | ||
486 | 561 | } | ||
487 | 562 | |||
488 | 563 | if (token == QXmlStreamReader::Characters) { | ||
489 | 564 | QString textString = reader.text().toString(); | ||
490 | 565 | if (textPos <= position && textPos + textString.length() > position) { | ||
491 | 566 | writer.writeCharacters(textString.left(position - textPos)); | ||
492 | 567 | |||
493 | 568 | writer.writeStartElement("div"); | ||
494 | 569 | writer.writeCharacters(text); | ||
495 | 570 | writer.writeEndElement(); | ||
496 | 571 | inserted = true; | ||
497 | 572 | |||
498 | 573 | writer.writeCharacters(textString.right(textString.length() - (position - textPos))); | ||
499 | 574 | } else { | ||
500 | 575 | writer.writeCharacters(reader.text().toString()); | ||
501 | 576 | } | ||
502 | 577 | textPos += textString.length(); | ||
503 | 578 | } | ||
504 | 579 | if (token == QXmlStreamReader::EndElement) { | ||
505 | 580 | |||
506 | 581 | // The above logic would fail on an empty note | ||
507 | 582 | if (reader.name() == "en-note" && !inserted) { | ||
508 | 583 | writer.writeStartElement("div"); | ||
509 | 584 | writer.writeCharacters(text); | ||
510 | 585 | writer.writeEndElement(); | ||
511 | 586 | } | ||
512 | 587 | |||
513 | 588 | writer.writeEndElement(); | ||
514 | 589 | } | ||
515 | 590 | } | ||
516 | 591 | m_enml = output; | ||
517 | 592 | } | ||
518 | 593 | |||
519 | 594 | void EnmlDocument::insertLink(int position, const QString &url) | ||
520 | 595 | { | ||
521 | 596 | qCDebug(dcEnml) << "Inserting Link at position" << position; | ||
522 | 597 | |||
523 | 598 | QXmlStreamReader reader(m_enml); | ||
524 | 599 | |||
525 | 600 | QString output; | ||
526 | 601 | QXmlStreamWriter writer(&output); | ||
527 | 602 | writer.writeStartDocument(); | ||
528 | 603 | writer.writeDTD("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">"); | ||
529 | 604 | |||
530 | 605 | int textPos = 0; | ||
531 | 606 | bool inserted = false; | ||
532 | 607 | |||
533 | 608 | while (!reader.atEnd() && !reader.hasError()) { | ||
534 | 609 | QXmlStreamReader::TokenType token = reader.readNext(); | ||
535 | 610 | |||
536 | 611 | if (token == QXmlStreamReader::StartElement) { | ||
537 | 612 | writer.writeStartElement(reader.name().toString()); | ||
538 | 613 | writer.writeAttributes(reader.attributes()); | ||
539 | 614 | } | ||
540 | 615 | |||
541 | 616 | if (token == QXmlStreamReader::Characters) { | ||
542 | 617 | QString textString = reader.text().toString(); | ||
543 | 618 | if (textPos <= position && textPos + textString.length() > position) { | ||
544 | 619 | writer.writeCharacters(textString.left(position - textPos)); | ||
545 | 620 | |||
546 | 621 | writer.writeStartElement("div"); | ||
547 | 622 | writer.writeStartElement("a"); | ||
548 | 623 | writer.writeAttribute("href", url); | ||
549 | 624 | writer.writeCharacters(url); | ||
550 | 625 | writer.writeEndElement(); | ||
551 | 626 | writer.writeEndElement(); | ||
552 | 627 | inserted = true; | ||
553 | 628 | |||
554 | 629 | writer.writeCharacters(textString.right(textString.length() - (position - textPos))); | ||
555 | 630 | } else { | ||
556 | 631 | writer.writeCharacters(reader.text().toString()); | ||
557 | 632 | } | ||
558 | 633 | textPos += textString.length(); | ||
559 | 634 | } | ||
560 | 635 | if (token == QXmlStreamReader::EndElement) { | ||
561 | 636 | |||
562 | 637 | // The above logic would fail on an empty note | ||
563 | 638 | if (reader.name() == "en-note" && !inserted) { | ||
564 | 639 | writer.writeStartElement("div"); | ||
565 | 640 | writer.writeStartElement("a"); | ||
566 | 641 | writer.writeAttribute("href", url); | ||
567 | 642 | writer.writeCharacters(url); | ||
568 | 643 | writer.writeEndElement(); | ||
569 | 531 | writer.writeEndElement(); | 644 | writer.writeEndElement(); |
570 | 532 | } | 645 | } |
571 | 533 | 646 | ||
572 | @@ -551,10 +664,8 @@ | |||
573 | 551 | // Write all normal text inside <body> </body> to output | 664 | // Write all normal text inside <body> </body> to output |
574 | 552 | if (token == QXmlStreamReader::Characters) { | 665 | if (token == QXmlStreamReader::Characters) { |
575 | 553 | plaintext.append(reader.text().toString()); | 666 | plaintext.append(reader.text().toString()); |
576 | 554 | plaintext.append(' '); | ||
577 | 555 | } | 667 | } |
578 | 556 | } | 668 | } |
579 | 557 | 669 | ||
580 | 558 | plaintext.remove('\n').trimmed(); | ||
581 | 559 | return plaintext; | 670 | return plaintext; |
582 | 560 | } | 671 | } |
583 | 561 | 672 | ||
584 | === modified file 'src/libqtevernote/utils/enmldocument.h' | |||
585 | --- src/libqtevernote/utils/enmldocument.h 2015-03-05 18:23:25 +0000 | |||
586 | +++ src/libqtevernote/utils/enmldocument.h 2015-06-22 08:35:28 +0000 | |||
587 | @@ -41,6 +41,10 @@ | |||
588 | 41 | // Will insert the file described by hash at position in the plaintext string | 41 | // Will insert the file described by hash at position in the plaintext string |
589 | 42 | void attachFile(int position, const QString &hash, const QString &type); | 42 | void attachFile(int position, const QString &hash, const QString &type); |
590 | 43 | 43 | ||
591 | 44 | // Convenience functions to insert some text without having a complete Editor attached | ||
592 | 45 | void insertText(int position, const QString &text); | ||
593 | 46 | void insertLink(int position, const QString &url); | ||
594 | 47 | |||
595 | 44 | void markTodo(const QString &todoId, bool checked); | 48 | void markTodo(const QString &todoId, bool checked); |
596 | 45 | 49 | ||
597 | 46 | int renderWidth() const; | 50 | int renderWidth() const; |
PASSED: Continuous integration, rev:454 91.189. 93.70:8080/ job/reminders- app-ci/ 758/ 91.189. 93.70:8080/ job/generic- mediumtests- utopic/ 2932 91.189. 93.70:8080/ job/generic- mediumtests- utopic/ 2932/artifact/ work/output/ *zip*/output. zip 91.189. 93.70:8080/ job/reminders- app-utopic- amd64-ci/ 360 91.189. 93.70:8080/ job/reminders- app-vivid- amd64-ci/ 180
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/reminders- app-ci/ 758/rebuild
http://