Merge lp:~frankencode/ubuntu-calendar-app/data-service into lp:ubuntu-calendar-app

Proposed by Frank Mertens
Status: Merged
Merged at revision: 11
Proposed branch: lp:~frankencode/ubuntu-calendar-app/data-service
Merge into: lp:ubuntu-calendar-app
Diff against target: 907 lines (+729/-50) (has conflicts)
8 files modified
DiaryView.qml (+82/-0)
EventListModel.qml (+26/-0)
EventView.qml (+19/-13)
MonthView.qml (+9/-3)
calendar.qml (+26/-34)
calendarTests.qml (+14/-0)
dataService.js (+361/-0)
dataServiceTests.js (+192/-0)
Text conflict in MonthView.qml
To merge this branch: bzr merge lp:~frankencode/ubuntu-calendar-app/data-service
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Needs Fixing
Frank Mertens Pending
Review via email: mp+154240@code.launchpad.net

Commit message

Added a data model for the local store, some simulation data and thin API on top, which is called DataService.

Description of the change

Added a data model for the local store, some simulation data and thin API on top, which is called DataService. The idea behind: abstract away the access to events, contacts and places. Especially the last two will be delivered by some system service in a later version. For now this is only simulated. But the user of the DataService API shouldn't need to worry about.

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)
11. By Frank Mertens

Added more complex test case in preparation for integration of the diary view.

To run the tests and load the test data run 'qmlscene calendarTest.qml' once.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
12. By Frank Mertens

Use singleton pattern to improve startup performance

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
13. By Frank Mertens

Extended the database model by an events category and added a basic diary view.

The events category allows to use section headers.
The basic diary view uses the standard Ubuntu component ListItem.Standard to show
the events of the current day.

14. By Frank Mertens

Removed testing icon and added new icons needed for the diary view.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
15. By Frank Mertens

Missing file.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
16. By Frank Mertens

Allow proper interactions with the compressed event view.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'DiaryView.qml'
--- DiaryView.qml 1970-01-01 00:00:00 +0000
+++ DiaryView.qml 2013-03-27 23:13:20 +0000
@@ -0,0 +1,82 @@
1import QtQuick 2.0
2import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem
4import "dateExt.js" as DateExt
5import "colorUtils.js" as Color
6
7ListView {
8 id: diaryView
9
10 property var dayStart: new Date()
11
12 property bool expanded: false
13
14 property bool expanding: false
15 property bool compressing: false
16
17 signal expand()
18 signal compress()
19
20 clip: true
21
22 model: EventListModel {
23 termStart: dayStart
24 termLength: Date.msPerDay
25 }
26
27 section {
28 property: "category"
29 // labelPositioning: ViewSection.CurrentLabelAtStart // FIXME, unreliable
30 delegate: ListItem.Header {
31 text: i18n.tr(section)
32 MouseArea {
33 anchors.fill: parent
34 onClicked: {
35 if (expanded)
36 compress()
37 else
38 expand()
39 }
40 }
41 }
42 }
43
44 delegate: ListItem.Standard {
45 text: startTime.toLocaleTimeString(Qt.locale(i18n.language), Locale.ShortFormat) + " " + title
46 }
47
48 footer: ListItem.Standard {
49 text: i18n.tr("(+) New Event / Todo")
50 }
51
52 onContentYChanged: {
53 // console.log(expanded, expanding, compressing, dragging, flicking, moving, contentY)
54 if (expanding || compressing || !dragging) return
55
56 if (expanded) {
57 if (contentY < -units.gu(0.5)) {
58 compressing = true
59 expanding = false
60 }
61 }
62 else {
63 if (contentY < -units.gu(0.5)) {
64 expanding = true
65 compressing = false
66 }
67 }
68 }
69
70 onDraggingChanged: {
71 if (dragging) return
72
73 if (expanding) {
74 expanding = false
75 expand()
76 }
77 else if (compressing) {
78 compressing = false
79 compress()
80 }
81 }
82}
083
=== added file 'EventListModel.qml'
--- EventListModel.qml 1970-01-01 00:00:00 +0000
+++ EventListModel.qml 2013-03-27 23:13:20 +0000
@@ -0,0 +1,26 @@
1import QtQuick 2.0
2import "dateExt.js" as DateExt
3import "dataService.js" as DataService
4
5ListModel {
6 id: model
7
8 property var termStart: new Date()
9 property var termLength: Date.msPerDay
10
11 signal reload
12
13 onReload: {
14 var t0 = termStart.getTime()
15 var t1 = t0 + termLength
16 model.clear()
17 DataService.getEvents(t0, t1, model)
18 // for (var i = 0; i < model.count; ++i)
19 // DataService.printEvent(model.get(i))
20 }
21 Component.onCompleted: {
22 reload()
23 DataService.eventsNotifier().dataChanged.connect(reload)
24 termStartChanged.connect(reload)
25 }
26}
027
=== modified file 'EventView.qml'
--- EventView.qml 2013-03-07 00:13:06 +0000
+++ EventView.qml 2013-03-27 23:13:20 +0000
@@ -1,6 +1,6 @@
1import QtQuick 2.01import QtQuick 2.0
2import Ubuntu.Components 0.12import Ubuntu.Components 0.1
3import "DateLib.js" as DateLib3import "dateExt.js" as DateExt
44
5PathView {5PathView {
6 id: eventView6 id: eventView
@@ -10,6 +10,11 @@
10 signal incrementCurrentDay10 signal incrementCurrentDay
11 signal decrementCurrentDay11 signal decrementCurrentDay
1212
13 property bool expanded: false
14
15 signal compress()
16 signal expand()
17
13 readonly property real visibleHeight: parent.height - y18 readonly property real visibleHeight: parent.height - y
1419
15 QtObject {20 QtObject {
@@ -43,7 +48,7 @@
4348
44 path: Path {49 path: Path {
45 startX: -eventView.width; startY: eventView.height / 250 startX: -eventView.width; startY: eventView.height / 2
46 PathLine { relativeX: eventView.width; relativeY: 0 }51 PathLine { relativeX: eventView.width; relativeY: 0 }
47 PathLine { relativeX: eventView.width; relativeY: 0 }52 PathLine { relativeX: eventView.width; relativeY: 0 }
48 PathLine { relativeX: eventView.width; relativeY: 0 }53 PathLine { relativeX: eventView.width; relativeY: 0 }
49 }54 }
@@ -52,21 +57,22 @@
5257
53 model: 358 model: 3
5459
55 delegate: Rectangle {60 delegate: DiaryView {
56 property var dayStart: {61 id: diaryView
62
63 width: eventView.width
64 height: eventView.height
65
66 dayStart: {
57 if (index == intern.currentIndex) return intern.currentDayStart67 if (index == intern.currentIndex) return intern.currentDayStart
58 var previousIndex = intern.currentIndex > 0 ? intern.currentIndex - 1 : 268 var previousIndex = intern.currentIndex > 0 ? intern.currentIndex - 1 : 2
59 if (index == previousIndex) return intern.currentDayStart.addDays(-1)69 if (index == previousIndex) return intern.currentDayStart.addDays(-1)
60 return intern.currentDayStart.addDays(1)70 return intern.currentDayStart.addDays(1)
61 }71 }
62 width: eventView.width72
63 height: eventView.height73 expanded: eventView.expanded
64 color: index == 0 ? "#FFFFFF" : index == 1 ? "#EEEEEE" : "#DDDDDD"74
65 Label {75 onExpand: eventView.expand()
66 anchors.horizontalCenter: parent.horizontalCenter76 onCompress: eventView.compress()
67 y: units.gu(4)
68 text: i18n.tr("No events for") + "\n" + Qt.formatDate(dayStart)
69 fontSize: "large"
70 }
71 }77 }
72}78}
7379
=== modified file 'MonthView.qml'
--- MonthView.qml 2013-03-18 20:39:06 +0000
+++ MonthView.qml 2013-03-27 23:13:20 +0000
@@ -1,6 +1,6 @@
1import QtQuick 2.01import QtQuick 2.0
2import Ubuntu.Components 0.12import Ubuntu.Components 0.1
3import "DateLib.js" as DateLib3import "dateExt.js" as DateExt
4import "colorUtils.js" as Color4import "colorUtils.js" as Color
55
6ListView {6ListView {
@@ -11,7 +11,8 @@
11 readonly property var currentDayStart: intern.currentDayStart11 readonly property var currentDayStart: intern.currentDayStart
1212
13 property bool compressed: false13 property bool compressed: false
14 property real compressedHeight: intern.squareUnit + intern.verticalMargin * 214 readonly property real compressedHeight: intern.squareUnit + intern.verticalMargin * 2
15 readonly property real expandedHeight: intern.squareUnit * 6 + intern.verticalMargin * 2
1516
16 signal incrementCurrentDay17 signal incrementCurrentDay
17 signal decrementCurrentDay18 signal decrementCurrentDay
@@ -90,7 +91,7 @@
9091
91 property int squareUnit: monthView.width / 892 property int squareUnit: monthView.width / 8
92 property int verticalMargin: units.gu(1)93 property int verticalMargin: units.gu(1)
93 property int weekstartDay: Qt.locale().firstDayOfWeek94 property int weekstartDay: Qt.locale(i18n.language).firstDayOfWeek
94 property int monthCount: 49 // months for +-2 years95 property int monthCount: 49 // months for +-2 years
9596
96 property var today: (new Date()).midnight() // TODO: update at midnight97 property var today: (new Date()).midnight() // TODO: update at midnight
@@ -99,8 +100,13 @@
99 property var monthStart0: today.monthStart()100 property var monthStart0: today.monthStart()
100 }101 }
101102
103<<<<<<< TREE
102 width: parent.width > 0 ? parent.width : 1104 width: parent.width > 0 ? parent.width : 1
103 height: intern.squareUnit * 6 + intern.verticalMargin * 2105 height: intern.squareUnit * 6 + intern.verticalMargin * 2
106=======
107 width: parent.width
108 height: compressed ? compressedHeight : expandedHeight
109>>>>>>> MERGE-SOURCE
104110
105 interactive: !compressed111 interactive: !compressed
106 clip: true112 clip: true
107113
=== added file 'avatar@8.png'
108Binary files avatar@8.png 1970-01-01 00:00:00 +0000 and avatar@8.png 2013-03-27 23:13:20 +0000 differ114Binary files avatar@8.png 1970-01-01 00:00:00 +0000 and avatar@8.png 2013-03-27 23:13:20 +0000 differ
=== removed file 'avatar@8.png'
109Binary files avatar@8.png 2013-02-12 16:18:48 +0000 and avatar@8.png 1970-01-01 00:00:00 +0000 differ115Binary files avatar@8.png 2013-02-12 16:18:48 +0000 and avatar@8.png 1970-01-01 00:00:00 +0000 differ
=== modified file 'calendar.qml'
--- calendar.qml 2013-03-18 11:39:23 +0000
+++ calendar.qml 2013-03-27 23:13:20 +0000
@@ -31,55 +31,47 @@
31 onSelectedTabIndexChanged: monthView.gotoNextMonth(selectedTabIndex)31 onSelectedTabIndexChanged: monthView.gotoNextMonth(selectedTabIndex)
32 }32 }
3333
34 Rectangle {
35 anchors.fill: monthView
36 color: "white"
37 }
38
34 MonthView {39 MonthView {
35 id: monthView40 id: monthView
36 onMonthStartChanged: tabs.selectedTabIndex = monthStart.getMonth()41 onMonthStartChanged: tabs.selectedTabIndex = monthStart.getMonth()
37 y: pageArea.y42 y: pageArea.y
43 onMovementEnded: eventView.currentDayStart = currentDayStart
44 onCurrentDayStartChanged: if (!(dragging || flicking)) eventView.currentDayStart = currentDayStart
45 Component.onCompleted: eventView.currentDayStart = currentDayStart
38 }46 }
3947
40 EventView {48 EventView {
41 id: eventView49 id: eventView
50
42 property real minY: pageArea.y + monthView.compressedHeight51 property real minY: pageArea.y + monthView.compressedHeight
43 property real maxY: pageArea.y + monthView.height52 property real maxY: pageArea.y + monthView.expandedHeight
53
44 y: maxY54 y: maxY
45 width: mainView.width55 width: mainView.width
46 height: parent.height - monthView.compressedHeight56 height: parent.height - y
47 currentDayStart: monthView.currentDayStart57
58 expanded: monthView.compressed
59
48 Component.onCompleted: {60 Component.onCompleted: {
49 incrementCurrentDay.connect(monthView.incrementCurrentDay)61 incrementCurrentDay.connect(monthView.incrementCurrentDay)
50 decrementCurrentDay.connect(monthView.decrementCurrentDay)62 decrementCurrentDay.connect(monthView.decrementCurrentDay)
51 }63 }
52 MouseArea {64
53 id: drawer65 onExpand: {
54 property bool compression: true66 monthView.compressed = true
55 anchors.fill: parent67 yBehavior.enabled = true
56 drag {68 y = minY
57 axis: Drag.YAxis69 }
58 target: eventView70 onCompress: {
59 minimumY: monthView.y + monthView.compressedHeight71 monthView.compressed = false
60 maximumY: monthView.y + monthView.height72 y = maxY
61 onActiveChanged: {73 }
62 if (compression) {74
63 if (drag.active) {
64 monthView.compressed = true
65 }
66 else {
67 yBehavior.enabled = true
68 eventView.y = Qt.binding(function() { return eventView.minY })
69 compression = false
70 }
71 }
72 else {
73 if (drag.active) {}
74 else{
75 eventView.y = Qt.binding(function() { return eventView.maxY })
76 monthView.compressed = false
77 compression = true
78 }
79 }
80 }
81 }
82 }
83 Behavior on y {75 Behavior on y {
84 id: yBehavior76 id: yBehavior
85 enabled: false77 enabled: false
8678
=== added file 'calendarTests.qml'
--- calendarTests.qml 1970-01-01 00:00:00 +0000
+++ calendarTests.qml 2013-03-27 23:13:20 +0000
@@ -0,0 +1,14 @@
1import QtQuick 2.0
2import Ubuntu.Components 0.1
3import "dataServiceTests.js" as DataServiceTests
4
5MainView {
6 width: units.gu(20)
7 height: units.gu(20)
8 Button {
9 anchors.fill: parent
10 anchors.margins: units.gu(5)
11 text: "Close"
12 onClicked: Qt.quit()
13 }
14}
015
=== added file 'dataService.js'
--- dataService.js 1970-01-01 00:00:00 +0000
+++ dataService.js 2013-03-27 23:13:20 +0000
@@ -0,0 +1,361 @@
1.pragma library
2
3.import QtQuick.LocalStorage 2.0 as LS
4
5Array.prototype.append = function(x) { this.push(x) }
6
7var CATEGORY_EVENT = 0
8var CATEGORY_TODO = 1
9
10function getEvents(termStart, termEnd, events)
11{
12 var result = null
13
14 db().readTransaction(
15 function(tx) {
16 result = tx.executeSql('\
17select * from Event \
18where (? <= startTime and startTime < ?) or \
19 (? < endTime and endTime <= ?) or \
20 (startTime <= ? and ? <= endTime) \
21order by startTime',
22 [ termStart, termEnd, termStart, termEnd, termStart, termEnd ]
23 )
24 }
25 )
26
27 events = events || []
28
29 for (var i = 0; i < result.rows.length; ++i) {
30 var e = result.rows.item(i)
31 e.startTime = new Date(e.startTime)
32 e.endTime = new Date(e.endTime)
33 events.append(e)
34 }
35
36 return events
37}
38
39function getAttendees(event, attendees)
40{
41 var result = null;
42
43 db().readTransaction(
44 function(tx) {
45 result = tx.executeSql('\
46select c.* from Attendance a, Contact c \
47where a.eventId = ? and a.contactId = c.id \
48order by c.name',
49 [ event.id ]
50 )
51 }
52 )
53
54 attendees = attendees || []
55
56 for (var i = 0; i < result.rows.length; ++i)
57 attendees.append(result.rows.item(i))
58
59 return attendees
60}
61
62function addEvent(event)
63{
64 var result = null
65
66 db().transaction(
67 function(tx) {
68 result = tx.executeSql('\
69insert into Event(title, message, startTime, endTime) \
70values (?, ?, ?, ?)',
71 [ event.title, event.message, event.startTime, event.endTime ]
72 )
73 }
74 )
75
76 event.id = result.insertId
77
78 eventsNotifier().dataChanged()
79
80 return event
81}
82
83function removeEvent(event)
84{
85 db().transaction(
86 function(tx) {
87 tx.executeSql(
88 'delete from Event where id = ?',
89 [ event.id ]
90 )
91 tx.executeSql(
92 'delete from Attendance where eventId = ?',
93 [ event.id ]
94 )
95 tx.executeSql(
96 'delete from Venue where eventId = ?',
97 [ event.id ]
98 )
99 }
100 )
101
102 delete event.id
103
104 eventsNotifier().dataChanged()
105}
106
107function getContacts(contacts)
108{
109 var result = null
110
111 db().readTransaction(
112 function(tx) {
113 result = tx.executeSql('select * from Contact order by name')
114 }
115 )
116
117 contacts = contacts || []
118
119 for (var i = 0; i < result.rows.length; ++i)
120 contacts.append(result.rows.item(i))
121
122 return contacts
123}
124
125function addAttendee(event, contact)
126{
127 db().transaction(
128 function(tx) {
129 tx.executeSql(
130 'insert into Attendance(eventId, contactId) values (?, ?)',
131 [ event.id, contact.id ]
132 )
133 }
134 )
135}
136
137function removeAttendee(event, contact)
138{
139 db().transaction(
140 function(tx) {
141 tx.executeSql(
142 'delete from Attendance where eventId = ? and contactId = ?',
143 [ event.id, contact.id ]
144 )
145 }
146 )
147}
148
149function getPlaces(places)
150{
151 var result = null
152
153 db().readTransaction(
154 function(tx) {
155 result = tx.executeSql('select * from Place')
156 }
157 )
158
159 places = places || []
160
161 for (var i = 0; i < result.rows.length; ++i)
162 places.append(result.rows.item(i))
163
164 return places
165}
166
167function addPlace(place)
168{
169 var result = null
170
171 if (typeof place.address == 'undefined') place.address = null
172 if (typeof place.latitude == 'undefined') place.latitude = null
173 if (typeof place.longitude == 'undefined') place.longitude = null
174
175 db().transaction(
176 function(tx) {
177 result = tx.executeSql(
178 'insert into Place(name, address, latitude, longitude) values(?, ?, ?, ?)',
179 [ place.name, place.address, place.latitude, place.longitude ]
180 )
181 }
182 )
183
184 place.id = result.insertId
185
186 return place
187}
188
189function removePlace(place)
190{
191 db().transaction(
192 function(tx) {
193 tx.executeSql(
194 'delete from Place where id = ?',
195 [ place.id ]
196 )
197 tx.executeSql(
198 'delete from Venue where placeId = ?',
199 [ place.id ]
200 )
201 }
202 )
203
204 delete place.id
205}
206
207function addVenue(event, place)
208{
209 db().transaction(
210 function(tx) {
211 tx.executeSql(
212 'insert into Venue(eventId, placeId) values(?, ?)',
213 [ event.id, place.id ]
214 )
215 }
216 )
217}
218
219function removeVenue(event, place)
220{
221 db().transaction(
222 function(tx) {
223 tx.executeSql(
224 'delete from Venue where eventId = ? and placeId = ?',
225 [ event.id, place.id ]
226 )
227 }
228 )
229}
230
231function getVenues(event, venues)
232{
233 var result = null
234
235 db().readTransaction(
236 function(tx) {
237 result = tx.executeSql('\
238select p.* \
239from Venue v, Place p \
240where v.eventId = ? and p.id = v.placeId \
241order by p.name',
242 [ event.id ]
243 )
244 }
245 )
246
247 venues = venues || []
248
249 for (var i = 0; i < result.rows.length; ++i)
250 venues.append(result.rows.item(i))
251
252 return venues
253}
254
255function printEvent(event)
256{
257 console.log('Event', event)
258 console.log(' id:', event.id)
259 console.log(' title:', event.title)
260 console.log(' message:', event.message)
261 console.log(' startTime:', new Date(event.startTime).toLocaleString())
262 console.log(' endTime:', new Date(event.endTime).toLocaleString())
263
264 var attendees = []
265 var venues = []
266 getAttendees(event, attendees)
267 getVenues(event, venues)
268 for (var j = 0; j < attendees.length; ++j)
269 printContact(attendees[j])
270 for (var j = 0; j < venues.length; ++j)
271 printPlace(venues[j])
272 console.log('')
273}
274
275function printContact(contact)
276{
277 console.log('Contact', contact)
278 console.log(' id:', contact.id)
279 console.log(' name:', contact.name)
280 console.log(' surname:', contact.surname)
281 console.log(' avatar:', contact.avatar)
282}
283
284function printPlace(place)
285{
286 console.log('Place', place)
287 console.log(' name:', place.name)
288 console.log(' address:', place.address)
289 console.log(' latitude:', place.latitude)
290 console.log(' longitude:', place.longitude)
291}
292
293function __createFirstTime(tx)
294{
295 var schema = '\
296create table Event(\
297 id integer primary key,\
298 title text,\
299 message text,\
300 startTime integer,\
301 endTime integer,\
302 category text default "Events"\
303);\
304\
305create index EventStartTimeIndex on Event(startTime);\
306create index EventEndTimeIndex on Event(endTime);\
307\
308create table Place(\
309 id integer primary key,\
310 name text,\
311 address text,\
312 latitude real,\
313 longitude real\
314);\
315\
316create table Contact(\
317 id integer primary key,\
318 name text,\
319 surname text,\
320 avatar text\
321);\
322\
323create table Attendance(\
324 id integer primary key,\
325 eventId integer references Event(id) on delete cascade,\
326 contactId integer references Contact(id) on delete cascade,\
327 placeId integer references Place(id) on delete set null\
328);\
329\
330create table Venue(\
331 id integer primary key,\
332 eventId integer references Event(id) on delete cascade,\
333 placeId integer references Place(id) on delete cascade\
334);\
335\
336'.split(';')
337
338 for (var i = 0; i < schema.length; ++i) {
339 var sql = schema[i]
340 if (sql != "") {
341 console.log(sql)
342 tx.executeSql(sql)
343 }
344 }
345}
346
347function eventsNotifier()
348{
349 if (!eventsNotifier.hasOwnProperty("instance"))
350 eventsNotifier.instance = Qt.createQmlObject('import QtQuick 2.0; QtObject { signal dataChanged }', Qt.application, 'DataService.eventsNotifier()')
351 return eventsNotifier.instance
352}
353
354function db()
355{
356 if (!db.hasOwnProperty("instance")) {
357 db.instance = LS.LocalStorage.openDatabaseSync("Calendar", "", "Offline Calendar", 100000)
358 if (db.instance.version == "") db.instance.changeVersion("", "0.1", __createFirstTime)
359 }
360 return db.instance
361}
0362
=== added file 'dataServiceTests.js'
--- dataServiceTests.js 1970-01-01 00:00:00 +0000
+++ dataServiceTests.js 2013-03-27 23:13:20 +0000
@@ -0,0 +1,192 @@
1.pragma library
2.import "dateExt.js" as DateExt
3.import "dataService.js" as DataService
4
5function clearData(tx) {
6 var deletes = '\
7delete from Event;\
8delete from Place;\
9delete from Contact;\
10delete from Attendance;\
11delete from Venue\
12'.split(';')
13 for (var i = 0; i < deletes.length; ++i)
14 tx.executeSql(deletes[i])
15}
16
17function loadTestDataSimple(tx)
18{
19 clearData(tx)
20
21 var inserts = '\
22insert into Contact(id, name, surname) values (1, "John", "Smith");\
23insert into Contact(id, name, surname) values (2, "Jane", "Smith");\
24insert into Contact(id, name, surname, avatar) values (3, "Frank", "Mertens", "http://www.gravatar.com/avatar/6d96fd4a98bba7b8779661d5db391ab6");\
25insert into Contact(id, name, surname) values (4, "Kunal", "Parmar");\
26insert into Contact(id, name, surname) values (5, "Mario", "Boikov");\
27insert into Place(id, name, address) values (1, "Quan Sen", "Pasing Arcaden, München");\
28insert into Place(id, name, address) values (2, "Jashan", "Landsberger Straße 84, 82110 Germering");\
29insert into Place(id, name, latitude, longitude) values (3, "Café Moskau", 52.521339, 13.42279);\
30insert into Place(id, name, address) values (4, "Santa Clara Marriott", "2700 Mission College Boulevard, Santa Clara, California");\
31insert into Place(id, name, address) values (5, "embeddedworld", "Messezentrum, 90471 Nürnberg");\
32insert into Event(id, title, message, startTime, endTime) values (1, "Team Meeting", "Bring your gear...", 1364648400000, 1364650200000);\
33insert into Event(id, title, message, startTime, endTime) values (2, "Jane\'s Birthday Party", "this year: southern wine", 1364061600000, 1364068800000);\
34insert into Event(id, title, startTime, endTime) values (3, "embeddedworld 2013", 1361836800000, 1362009600000);\
35insert into Attendance(eventId, contactId, placeId) values (1, 1, 1);\
36insert into Attendance(eventId, contactId, placeId) values (1, 2, 1);\
37insert into Attendance(eventId, contactId, placeId) values (1, 3, 1);\
38insert into Attendance(eventId, contactId, placeId) values (1, 4, 3);\
39insert into Attendance(eventId, contactId, placeId) values (1, 5, 3);\
40insert into Attendance(eventId, contactId) values (2, 1);\
41insert into Attendance(eventId, contactId) values (2, 2);\
42insert into Attendance(eventId, contactId) values (2, 3);\
43insert into Venue(eventId, placeId) values (2, 3);\
44insert into Venue(eventId, placeId) values (3, 5)\
45'.split(';')
46
47 for (var i = 0; i < inserts.length; ++i) {
48 var sql = inserts[i]
49 if (sql != "") {
50 console.log(sql)
51 tx.executeSql(sql)
52 }
53 }
54}
55
56function loadTestDataComplex(tx)
57{
58 clearData(tx)
59
60 function t(d, h, m) {
61 if (typeof t.today == "undefined") t.today = new Date().midnight()
62 return t.today.addDays(d).setHours(h, m)
63 }
64
65 var places = [
66 { id: 1, name: "Moskau A" },
67 { id: 2, name: "Moskau B" },
68 { id: 3, name: "Bischkek" },
69 { id: 4, name: "Asgabat A" },
70 { id: 5, name: "Asgabat B" },
71 { id: 6, name: "Vilnius" },
72 { id: 7, name: "Riga" }
73 ]
74
75 var speaker = [
76 { id: 1, name: "Sean", surname: "Harmer" },
77 { id: 2, name: "Marc", surname: "Lutz" },
78 { id: 3, name: "David", surname: "Faure" },
79 { id: 4, name: "Volker", surname: "Krause" },
80 { id: 5, name: "Kevin", surname: "Krammer" },
81 { id: 6, name: "Tobias", surname: "Nätterlund" },
82 { id: 7, name: "Steffen", surname: "Hansen" },
83 { id: 8, name: "Tommi", surname: "Laitinen" },
84 { id: 9, name: "Lars", surname: "Knoll" },
85 { id: 10, name: "Roland", surname: "Krause" },
86 { id: 11, name: "Jens", surname: "Bache-Wiig" },
87 { id: 12, name: "Michael", surname: "Wagner" },
88 { id: 13, name: "Helmut", surname: "Sedding" },
89 { id: 14, name: "Jeff", surname: "Tranter" },
90 { id: 15, name: "Simon", surname: "Hausmann" },
91 { id: 16, name: "Stephen", surname: "Kelly" },
92 { id: 17, name: "Tam", surname: "Hanna" },
93 { id: 18, name: "Mirko", surname: "Boehm" },
94 { id: 19, name: "Till", surname: "Adam" },
95 { id: 20, name: "Thomas", surname: "Senyk" }
96 ]
97
98 var events = [
99 { id: 1, room: 1, speaker: [ 1 ], title: "Modern OpenGL with Qt5", message: "hands-on training", startTime: t(0, 10, 00), endTime: t(0, 12 ,00) },
100 { id: 2, room: 2, speaker: [ 2 ], title: "What's new in C++11", message: "focus on Qt5", startTime: t(0, 13, 00), endTime: t(0, 14, 30) },
101 { id: 3, room: 3, speaker: [ 3 ], title: "Model/view Programming using Qt", message: "hands-on training", startTime: t(0, 14, 45), endTime: t(0, 16, 15) },
102 { id: 4, room: 4, speaker: [ 4 ], title: "Introduction to Qt Quick", message: "hands-on training", startTime: t(0, 16, 30), endTime: t(0, 17, 45) },
103 { id: 5, room: 1, speaker: [ 8 ], title: "Keynote: Qt – Gearing up for the Future", message: "", startTime: t(1, 9, 15), endTime: t(1, 9, 30) },
104 { id: 6, room: 1, speaker: [ 9 ], title: "Keynote: Qt 5 Roadmap", message: "", startTime: t(1, 9, 30), endTime: t(1, 10, 30) },
105 { id: 7, room: 3, speaker: [ 10 ], title: "Qt and the Google APIs", message: "", startTime: t(1, 10, 45), endTime: t(1, 11, 45) },
106 { id: 8, room: 7, speaker: [ 11 ], title: "Desktop Components for QtQuick", message: "", startTime: t(1, 10, 45), endTime: t(1, 11, 45) },
107 { id: 9, room: 2, speaker: [ 9 ], title: "The Future of Qt on Embedded Linux", message: "", startTime: t(1, 12, 45), endTime: t(1, 13, 45) },
108 { id: 10, room: 7, speaker: [ 12, 13 ], title: "QML for desktop apps", message: "", startTime: t(1, 12, 45), endTime: t(1, 13, 34) },
109 { id: 11, room: 2, speaker: [ 14 ], title: "Qt on Raspberry Pi", message: "", startTime: t(1, 14, 00), endTime: t(1, 15, 00) },
110 { id: 12, room: 3, speaker: [ 15 ], title: "What's new in QtWebKit in 5.0", message: "", startTime: t(1, 14, 00), endTime: t(1, 15, 00) },
111 { id: 13, room: 1, speaker: [ 16 ], title: "In Depth – QMetaType and QMetaObject", message: "", startTime: t(1, 15, 30), endTime: t(1, 16, 30) },
112 { id: 14, room: 2, speaker: [ 17 ], title: "Using Qt as mobile cross-platform system", message: "", startTime: t(1, 15, 30), endTime: t(1, 16, 30) },
113 { id: 15, room: 1, speaker: [ 18, 19 ], title: "Intentions good, warranty void: Using Qt in unexpected ways", message: "", startTime: t(1, 16, 45), endTime: t(1, 17, 45) },
114 { id: 16, room: 2, speaker: [ 20 ], title: "Porting Qt 5 to embedded hardware", message: "", startTime: t(1, 16, 45), endTime: t(1, 17, 45) }
115 ]
116
117 for (var i = 0; i < places.length; ++i) {
118 var p = places[i]
119 tx.executeSql(
120 'insert into Place(id, name, address) values (?, ?, ?)',
121 [ p.id, p.name, "Cafe Moskau, Berlin, Germany" ]
122 )
123 }
124
125 for (var i = 0; i < speaker.length; ++i) {
126 var s = speaker[i]
127 tx.executeSql(
128 'insert into Contact(id, name, surname) values (?, ?, ?)',
129 [ s.id, s.name, s.surname ]
130 )
131 }
132
133 for (var i = 0; i < events.length; ++i) {
134 var e = events[i]
135 tx.executeSql(
136 'insert into Event(id, title, message, startTime, endTime) values (?, ?, ?, ?, ?)',
137 [ e.id, e.title, e.message, e.startTime, e.endTime ]
138 )
139 tx.executeSql(
140 'insert into Venue(eventId, placeId) values (?, ?)',
141 [ e.id, e.room ]
142 )
143 for (var j = 0; j < e.speaker.length; ++j) {
144 tx.executeSql(
145 'insert into Attendance(eventId, contactId) values (?, ?)',
146 [ e.id, e.speaker[j] ]
147 )
148 }
149 }
150}
151
152function runTestSimple(tx)
153{
154 loadTestDataSimple(tx)
155
156 var contacts = []
157 DataService.getContacts(contacts)
158 for (var i = 0; i < contacts.length; ++i)
159 DataService.printContact(contacts[i])
160 console.log('')
161
162 var testEvent = DataService.addEvent({
163 title: 'Critical Review',
164 message: '',
165 startTime: new Date(2013, 2, 30, 10, 00).getTime(),
166 endTime: new Date(2013, 2, 30, 10, 30).getTime()
167 })
168 DataService.addAttendee(testEvent, contacts[1])
169 DataService.addAttendee(testEvent, contacts[2])
170 DataService.addAttendee(testEvent, contacts[0])
171 DataService.removeAttendee(testEvent, contacts[0])
172 var testPlace = DataService.addPlace({ name: 'Jane\'s bar' })
173 DataService.addVenue(testEvent, testPlace)
174 console.log('Added new event with id', testEvent.id)
175 console.log('')
176
177 var events = []
178 var dayStart = new Date(2013, 2, 30)
179 DataService.getEvents(dayStart.getTime(), dayStart.addDays(1).getTime(), events)
180 for (var i = 0; i < events.length; ++i)
181 DataService.printEvent(events[i])
182
183 DataService.removeEvent(testEvent)
184 DataService.removePlace(testPlace)
185}
186
187DataService.db().transaction(
188 function (tx) {
189 runTestSimple(tx)
190 loadTestDataComplex(tx)
191 }
192)
0193
=== renamed file 'DateLib.js' => 'dateExt.js'
=== added file 'icon-contacts@8.png'
1Binary files icon-contacts@8.png 1970-01-01 00:00:00 +0000 and icon-contacts@8.png 2013-03-27 23:13:20 +0000 differ194Binary files icon-contacts@8.png 1970-01-01 00:00:00 +0000 and icon-contacts@8.png 2013-03-27 23:13:20 +0000 differ
=== added file 'icon-location@18.png'
2Binary files icon-location@18.png 1970-01-01 00:00:00 +0000 and icon-location@18.png 2013-03-27 23:13:20 +0000 differ195Binary files icon-location@18.png 1970-01-01 00:00:00 +0000 and icon-location@18.png 2013-03-27 23:13:20 +0000 differ

Subscribers

People subscribed via source and target branches

to status/vote changes: