1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "testmodelui.h" |
|
43 #include "qtcontacts.h" |
|
44 #include "qcontactlistmodel.h" |
|
45 #include "qcontactfetchrequest.h" |
|
46 |
|
47 #include <QtGui> |
|
48 |
|
49 TestModelView::TestModelView(QContactManager* manager) |
|
50 : QListView() |
|
51 { |
|
52 model = new QContactListModel(manager); |
|
53 setModel(model); |
|
54 } |
|
55 |
|
56 TestModelView::~TestModelView() |
|
57 { |
|
58 delete model; |
|
59 } |
|
60 |
|
61 QContactLocalId TestModelView::currentId() const |
|
62 { |
|
63 return QContactLocalId(model->data(currentIndex(), QContactListModel::IdRole).toUInt()); |
|
64 } |
|
65 |
|
66 QVariant TestModelView::currentData(QContactListModel::ContactDataRole role) const |
|
67 { |
|
68 return model->data(currentIndex(), role); |
|
69 } |
|
70 |
|
71 TestModelUi::TestModelUi() |
|
72 : QWidget() |
|
73 { |
|
74 manager = new QContactManager("memory"); |
|
75 populateContacts(); |
|
76 nbrMissedCalls = 0; |
|
77 talkingToNumber = ""; |
|
78 |
|
79 dialog = new FilterDialog; |
|
80 connect(dialog, SIGNAL(hidden()), this, SLOT(filterFound())); |
|
81 |
|
82 fetchRequest = new QContactFetchRequest; |
|
83 fetchRequest->setManager(manager); |
|
84 connect(fetchRequest, SIGNAL(progress(QContactFetchRequest*,bool)), this, SLOT(dataAvailable(QContactFetchRequest*,bool))); |
|
85 filterRequest = new QContactFetchRequest; |
|
86 filterRequest->setManager(manager); |
|
87 connect(filterRequest, SIGNAL(progress(QContactFetchRequest*,bool)), this, SLOT(filterResults(QContactFetchRequest*,bool))); |
|
88 |
|
89 incomingCallTimer = new QTimer; |
|
90 incomingCallTimer->setInterval(15000); // 15 seconds between incoming calls. |
|
91 dialTimer = new QTimer; |
|
92 dialTimer->setInterval(3000); // they answer after 3 seconds |
|
93 answerTimer = new QTimer; |
|
94 answerTimer->setInterval(6000); // missed call after 6 seconds |
|
95 |
|
96 connect(incomingCallTimer, SIGNAL(timeout()), this, SLOT(incoming())); |
|
97 connect(dialTimer, SIGNAL(timeout()), this, SLOT(talking())); |
|
98 connect(answerTimer, SIGNAL(timeout()), this, SLOT(missedCall())); |
|
99 incomingCallTimer->start(); |
|
100 |
|
101 list = new TestModelView(manager); |
|
102 textEdit = new QTextEdit; |
|
103 viewArea = new QStackedWidget; |
|
104 viewArea->addWidget(list); |
|
105 viewArea->addWidget(textEdit); |
|
106 viewArea->setCurrentIndex(0); |
|
107 |
|
108 missedCalls = new QLabel; |
|
109 missedCalls->setAlignment(Qt::AlignLeft); |
|
110 missedCalls->setText(QString(tr("# Missed Calls:"))); |
|
111 missedCallsNbr = new QLabel; |
|
112 missedCallsNbr->setAlignment(Qt::AlignRight); |
|
113 missedCallsNbr->setText(QString::number(nbrMissedCalls)); |
|
114 |
|
115 leftButton = new QPushButton(tr("Dial")); |
|
116 middleButton = new QPushButton(tr("Find")); |
|
117 rightButton = new QPushButton(tr("Quit")); |
|
118 |
|
119 connect(leftButton, SIGNAL(clicked()), this, SLOT(dial())); |
|
120 connect(middleButton, SIGNAL(clicked()), this, SLOT(findContact())); |
|
121 connect(rightButton, SIGNAL(clicked()), this, SLOT(close())); |
|
122 |
|
123 QHBoxLayout *missedLayout = new QHBoxLayout; |
|
124 missedLayout->addWidget(missedCalls); |
|
125 missedLayout->addWidget(missedCallsNbr); |
|
126 |
|
127 QHBoxLayout *btnLayout = new QHBoxLayout; |
|
128 btnLayout->addWidget(leftButton); |
|
129 btnLayout->addWidget(middleButton); |
|
130 btnLayout->addWidget(rightButton); |
|
131 |
|
132 QVBoxLayout *listLayout = new QVBoxLayout; |
|
133 listLayout->addLayout(missedLayout); |
|
134 listLayout->addWidget(viewArea); |
|
135 listLayout->addLayout(btnLayout); |
|
136 |
|
137 setLayout(listLayout); |
|
138 } |
|
139 |
|
140 TestModelUi::~TestModelUi() |
|
141 { |
|
142 delete fetchRequest; |
|
143 delete filterRequest; |
|
144 |
|
145 delete leftButton; |
|
146 delete rightButton; |
|
147 delete list; |
|
148 delete textEdit; |
|
149 delete viewArea; |
|
150 delete dialog; |
|
151 delete manager; |
|
152 } |
|
153 |
|
154 void TestModelUi::populateContacts() |
|
155 { |
|
156 // generate some fictional contacts. |
|
157 QStringList nameFirst; |
|
158 nameFirst << "Adam" << "Adrianna" << "Alex" << "Brett" << "Bob" |
|
159 << "Carina" << "Christina" << "Carl" << "Daniel" << "Denise" |
|
160 << "Eric" << "Fred" << "Mario" << "William" << "Zandi"; |
|
161 QStringList nameLast; |
|
162 nameLast << "Citizen" << "Civilian" << "Doe" << "Generic" << "Public" << "Unlikely"; |
|
163 |
|
164 QStringList phoneFirst; |
|
165 phoneFirst << "111" << "222" << "333" << "444" << "555" << "666" << "777" << "888" |
|
166 << "123" << "234" << "345" << "456" << "567" << "678" << "789"; |
|
167 QStringList phoneLast; |
|
168 phoneLast << "9876" << "8765" << "7654" << "6543" << "5432" << "4321"; |
|
169 |
|
170 QStringList emailFirst; |
|
171 emailFirst << "testPersonOne" << "testPersonTwo" << "testPersonThree" << "testPersonFour" << "testPersonFive" |
|
172 << "testPersonSix" << "testPersonSeven" << "testPersonEight" << "testPersonNine" << "testPersonTen" |
|
173 << "testPersonEleven" << "testPersonTwelve" << "testPersonThirteen" << "testPersonFourteen" << "testPersonFifteen"; |
|
174 QStringList emailLast; |
|
175 emailLast << "@test1.nokia.com" << "@test2.nokia.com" << "@test3.nokia.com" |
|
176 << "@test4.nokia.com" << "@test5.nokia.com" << "@test6.nokia.com"; |
|
177 |
|
178 QStringList avatarFirst; |
|
179 avatarFirst << "party" << "celebration" << "happyface" << "grinning" << "smile" |
|
180 << "laughing" << "dance" << "serious" << "angry" << "sadface" |
|
181 << "tree" << "mountain" << "ocean" << "city" << "bridge"; |
|
182 QStringList avatarLast; |
|
183 avatarLast << ".png" << ".bmp" << ".jpg" << ".gif" << ".avi" << ".mpg"; |
|
184 |
|
185 for (int i = 0; i < 15; i++) { |
|
186 for (int j = 0; j < 6; j++) { |
|
187 QContact c; |
|
188 QContactName n; |
|
189 QContactPhoneNumber p; |
|
190 QContactEmailAddress e; |
|
191 QContactAvatar a; |
|
192 |
|
193 n.setFirst(nameFirst.at(i)); |
|
194 n.setLast(nameLast.at(j)); |
|
195 p.setNumber(phoneFirst.at(i) + phoneLast.at(j)); |
|
196 e.setEmailAddress(emailFirst.at(i) + emailLast.at(j)); |
|
197 a.setAvatar(avatarFirst.at(i) + avatarLast.at(j)); |
|
198 |
|
199 c.saveDetail(&n); |
|
200 c.saveDetail(&p); |
|
201 c.saveDetail(&e); |
|
202 c.saveDetail(&a); |
|
203 |
|
204 manager->saveContact(&c); |
|
205 } |
|
206 } |
|
207 } |
|
208 |
|
209 void TestModelUi::dataAvailable(QContactFetchRequest* request, bool appendOnly) |
|
210 { |
|
211 Q_UNUSED(appendOnly); |
|
212 |
|
213 // first, make sure we can use the data. |
|
214 if (currentState == TestModelUi::WaitingState || request->status() != QContactAbstractRequest::Finished) |
|
215 return; |
|
216 |
|
217 // we assume that we need the extra details. |
|
218 QString text; |
|
219 |
|
220 QList<QContact> requestData = request->contacts(); |
|
221 if (requestData.isEmpty() || requestData.at(0).isEmpty()) { |
|
222 text += "Unknown Contact"; |
|
223 talkingToDetails = text; |
|
224 textEdit->setText(talkingToFirstLine + " " + talkingToNumber + "\n\n" + talkingToDetails); |
|
225 return; |
|
226 } |
|
227 |
|
228 QContact curr = request->contacts().at(0); |
|
229 QList<QContactDetail> allDetails = curr.details(); |
|
230 foreach (const QContactDetail& det, allDetails) { |
|
231 QString defName = det.definitionName(); |
|
232 text += defName + ":" + "\n"; |
|
233 QList<QString> fieldKeys = det.values().keys(); |
|
234 foreach (const QString& key, fieldKeys) { |
|
235 text += "\t" + key + " = " + det.value(key) + "\n"; |
|
236 } |
|
237 text += "\n"; |
|
238 } |
|
239 |
|
240 talkingToName = curr.displayLabel(); |
|
241 if (currentState == TestModelUi::DialingState) { |
|
242 talkingToNumber = curr.detail(QContactPhoneNumber::DefinitionName).value(QContactPhoneNumber::FieldNumber); |
|
243 } |
|
244 |
|
245 if (!text.isEmpty()) |
|
246 text.chop(1); // kill unneeded newline. |
|
247 talkingToDetails = text; |
|
248 textEdit->setText(talkingToFirstLine + " " + talkingToName + "\n\n" + talkingToDetails); |
|
249 } |
|
250 |
|
251 void TestModelUi::filterResults(QContactFetchRequest* request, bool appendOnly) |
|
252 { |
|
253 Q_UNUSED(appendOnly); |
|
254 QList<QContact> results = request->contacts(); |
|
255 QString text = "Matching Contacts:\n"; |
|
256 for (int i = 0; i < results.size(); i++) { |
|
257 text += "\n" + results.at(i).displayLabel(); |
|
258 } |
|
259 textEdit->setText(text); |
|
260 |
|
261 if (request->status() == QContactAbstractRequest::Finished) { |
|
262 if (results.isEmpty()) |
|
263 textEdit->setText("Matching Contacts:\n\nNo Matches Found!"); |
|
264 rightButton->setText(tr("Done")); |
|
265 middleButton->setEnabled(true); |
|
266 } |
|
267 } |
|
268 |
|
269 void TestModelUi::filterFound() |
|
270 { |
|
271 QContactFilter fil = dialog->filter(); |
|
272 if (dialog->status() > 0) { |
|
273 textEdit->setText("Finding Contacts...\n\n"); |
|
274 filterRequest->cancel(); |
|
275 filterRequest->setFilter(fil); |
|
276 filterRequest->start(); |
|
277 } else { |
|
278 finishedFindContact(); |
|
279 } |
|
280 } |
|
281 |
|
282 void TestModelUi::showFilterDialog() |
|
283 { |
|
284 middleButton->setEnabled(false); |
|
285 textEdit->setText("Selecting search criteria..."); |
|
286 rightButton->setText(tr("Cancel")); |
|
287 dialog->showDialog(); |
|
288 } |
|
289 |
|
290 void TestModelUi::findContact() |
|
291 { |
|
292 // complex filtering. |
|
293 incomingCallTimer->stop(); |
|
294 dialTimer->stop(); |
|
295 answerTimer->stop(); |
|
296 |
|
297 textEdit->setText("Please select a search criteria (click search)"); |
|
298 middleButton->disconnect(); |
|
299 rightButton->disconnect(); |
|
300 leftButton->setEnabled(false); |
|
301 middleButton->setEnabled(true); |
|
302 rightButton->setEnabled(true); |
|
303 middleButton->setText(tr("Search")); |
|
304 rightButton->setText(tr("Cancel")); |
|
305 connect(middleButton, SIGNAL(clicked()), this, SLOT(showFilterDialog())); |
|
306 connect(rightButton, SIGNAL(clicked()), this, SLOT(finishedFindContact())); |
|
307 viewArea->setCurrentIndex(1); |
|
308 } |
|
309 |
|
310 void TestModelUi::finishedFindContact() |
|
311 { |
|
312 // only allow them to finish if they close the find contact dialog. |
|
313 if (dialog->status() == 0) |
|
314 return; |
|
315 |
|
316 hangup(); |
|
317 } |
|
318 |
|
319 void TestModelUi::dial() |
|
320 { |
|
321 // get current index id from view |
|
322 // change current widget to text |
|
323 // change buttons to <gray> <hangup> |
|
324 // ... |
|
325 incomingCallTimer->stop(); |
|
326 answerTimer->stop(); |
|
327 currentState = TestModelUi::DialingState; |
|
328 |
|
329 QContactLocalIdFilter fil; |
|
330 QList<QContactLocalId> fetchIds; |
|
331 fetchIds << list->currentId(); |
|
332 fil.setIds(fetchIds); |
|
333 fetchRequest->cancel(); // if not already stopped. |
|
334 fetchRequest->setFilter(fil); |
|
335 fetchRequest->start(); |
|
336 |
|
337 talkingToFirstLine = "Dialing"; |
|
338 talkingToName = list->currentData(QContactListModel::DisplayLabelRole).toString(); |
|
339 textEdit->setText(talkingToFirstLine + " " + talkingToName + "\n\n" + talkingToDetails); |
|
340 leftButton->disconnect(); |
|
341 rightButton->disconnect(); |
|
342 leftButton->setText(tr("Dial")); |
|
343 rightButton->setText(tr("Cancel")); |
|
344 connect(rightButton, SIGNAL(clicked()), this, SLOT(hangup())); |
|
345 leftButton->setEnabled(false); |
|
346 middleButton->setEnabled(false); |
|
347 viewArea->setCurrentIndex(1); |
|
348 dialTimer->start(); |
|
349 } |
|
350 |
|
351 void TestModelUi::incoming() |
|
352 { |
|
353 // change current widget to text |
|
354 // change buttons to <answer> <hangup> |
|
355 // ... |
|
356 incomingCallTimer->stop(); |
|
357 dialTimer->stop(); |
|
358 currentState = TestModelUi::IncomingState; |
|
359 |
|
360 // create some phone numbers. about half appear in our contacts, half do not. |
|
361 QStringList phoneFirst; |
|
362 phoneFirst << "111" << "222" << "337" << "944" << "555" << "611" << "777" << "855" |
|
363 << "123" << "234" << "385" << "456" << "587" << "688" << "788"; |
|
364 QStringList phoneLast; |
|
365 phoneLast << "9876" << "8765" << "7654" << "9543" << "5432" << "9321"; |
|
366 |
|
367 int firstIndex = qrand() % phoneFirst.size(); |
|
368 int lastIndex = qrand() % phoneLast.size(); |
|
369 talkingToNumber = phoneFirst.at(firstIndex) + phoneLast.at(lastIndex); |
|
370 talkingToFirstLine = "Incoming call from"; |
|
371 textEdit->setText(talkingToFirstLine + " " + talkingToNumber + "\n\n" + talkingToDetails); |
|
372 |
|
373 QContactDetailFilter fil; |
|
374 fil.setDetailDefinitionName(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldNumber); |
|
375 fil.setValue(talkingToNumber); |
|
376 fetchRequest->cancel(); // if not already stopped. |
|
377 fetchRequest->setFilter(fil); |
|
378 fetchRequest->start(); |
|
379 |
|
380 leftButton->disconnect(); |
|
381 rightButton->disconnect(); |
|
382 leftButton->setText(tr("Answer")); |
|
383 rightButton->setText(tr("Hang Up")); |
|
384 connect(leftButton, SIGNAL(clicked()), this, SLOT(talking())); |
|
385 connect(rightButton, SIGNAL(clicked()), this, SLOT(hangup())); |
|
386 leftButton->setEnabled(true); |
|
387 middleButton->setEnabled(false); |
|
388 viewArea->setCurrentIndex(1); |
|
389 |
|
390 answerTimer->start(); |
|
391 } |
|
392 |
|
393 void TestModelUi::talking() |
|
394 { |
|
395 // get id of contact from incoming? |
|
396 // using async contact request with filter? |
|
397 // change current widget to text |
|
398 // change buttons to <gray> <hangup> |
|
399 // ... |
|
400 incomingCallTimer->stop(); |
|
401 dialTimer->stop(); |
|
402 answerTimer->stop(); |
|
403 currentState = TestModelUi::TalkingState; |
|
404 |
|
405 talkingToFirstLine = "Talking to"; |
|
406 textEdit->setText(talkingToFirstLine + " " + (talkingToName.isEmpty() ? talkingToNumber : talkingToName) + "\n\n" + talkingToDetails); |
|
407 leftButton->disconnect(); |
|
408 rightButton->disconnect(); |
|
409 leftButton->setText(tr("Answer")); |
|
410 rightButton->setText(tr("Hang Up")); |
|
411 connect(rightButton, SIGNAL(clicked()), this, SLOT(hangup())); |
|
412 leftButton->setEnabled(false); |
|
413 middleButton->setEnabled(false); |
|
414 } |
|
415 |
|
416 void TestModelUi::hangup() |
|
417 { |
|
418 // change current widget to list |
|
419 // change buttons to <dial> <exit> |
|
420 // ... |
|
421 incomingCallTimer->stop(); |
|
422 dialTimer->stop(); |
|
423 answerTimer->stop(); |
|
424 currentState = TestModelUi::WaitingState; |
|
425 |
|
426 talkingToName = ""; |
|
427 talkingToNumber = ""; |
|
428 talkingToDetails = ""; |
|
429 talkingToFirstLine = ""; |
|
430 textEdit->setText(""); |
|
431 leftButton->disconnect(); |
|
432 middleButton->disconnect(); |
|
433 rightButton->disconnect(); |
|
434 leftButton->setText(tr("Dial")); |
|
435 middleButton->setText(tr("Find")); |
|
436 rightButton->setText(tr("Quit")); |
|
437 connect(leftButton, SIGNAL(clicked()), this, SLOT(dial())); |
|
438 connect(middleButton, SIGNAL(clicked()), this, SLOT(findContact())); |
|
439 connect(rightButton, SIGNAL(clicked()), this, SLOT(close())); |
|
440 leftButton->setEnabled(true); |
|
441 middleButton->setEnabled(true); |
|
442 viewArea->setCurrentIndex(0); |
|
443 incomingCallTimer->start(); // restart the incoming call timer. |
|
444 } |
|
445 |
|
446 void TestModelUi::missedCall() |
|
447 { |
|
448 // increment missed call count |
|
449 // change current widget to list |
|
450 // change buttons to <dial> <exit> |
|
451 // ... |
|
452 nbrMissedCalls += 1; |
|
453 missedCallsNbr->setText(QString::number(nbrMissedCalls)); |
|
454 hangup(); |
|
455 } |
|