|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Communication Launcher widget for Friend widget |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <QDebug> |
|
19 #include <HbStyleLoader> |
|
20 #include <QGraphicsLinearLayout> |
|
21 #include <HbEffect> |
|
22 #include <HbPushButton> |
|
23 #include <qtcontacts.h> |
|
24 #include <hbdocumentloader.h> |
|
25 #include <xqappmgr.h> |
|
26 |
|
27 #include "commlauncherwidget.h" |
|
28 |
|
29 // ContactManager backend |
|
30 #ifdef Q_OS_SYMBIAN |
|
31 QString cmBackend = "symbian"; |
|
32 #else |
|
33 QString cmBackend = "memory"; |
|
34 #endif |
|
35 const QString commLauncherDocml = ":/commlauncherwidget.docml"; |
|
36 // Note: these are case sensitive |
|
37 const QString callButtonName = "ButtonCall"; |
|
38 const QString emailButtonName = "ButtonEmail"; |
|
39 const QString messageButtonName = "ButtonMessage"; |
|
40 const QString mycardButtonName = "ButtonMycard"; |
|
41 |
|
42 const QString appearTL = "appear_tl"; |
|
43 const QString appearTR = "appear_tr"; |
|
44 const QString appearBL = "appear_bl"; |
|
45 const QString appearBR = "appear_br"; |
|
46 |
|
47 const int commLauncherMargin = 120; // heights of titlebar & comm.launcher |
|
48 |
|
49 /*! |
|
50 \class CommLauncherWidget |
|
51 */ |
|
52 |
|
53 /*! |
|
54 Constructor |
|
55 */ |
|
56 CommLauncherWidget::CommLauncherWidget(QGraphicsItem *parent) : |
|
57 HbPopup(parent), |
|
58 mContact(0), |
|
59 mButtonCount(0), |
|
60 mRequest(NULL), |
|
61 mCallButton(0), |
|
62 mSendMsgButton(0), |
|
63 mEmailButton(0), |
|
64 mPhonebookButton(0), |
|
65 mApplicationManager(0) |
|
66 { |
|
67 |
|
68 HbStyleLoader::registerFilePath(":/commlauncherbuttons.css"); |
|
69 // effect triggers |
|
70 connect(this, SIGNAL(aboutToShow()), SLOT(popupAboutToShow())); |
|
71 connect(this, SIGNAL(aboutToClose()), SLOT(popupAboutToClose())); |
|
72 |
|
73 // create layout |
|
74 mLayout = new QGraphicsLinearLayout(this); |
|
75 qreal verticalMargin = 0.0; |
|
76 style()->parameter("hb-param-margin-gene-middle-vertical", verticalMargin); |
|
77 qreal horizontalMargin = 0.0; |
|
78 style()->parameter("hb-param-margin-gene-middle-horizontal", horizontalMargin); |
|
79 |
|
80 mLayout->setContentsMargins(horizontalMargin, verticalMargin, |
|
81 horizontalMargin, 2*verticalMargin); |
|
82 |
|
83 // create document loader |
|
84 HbDocumentLoader *documentLoader = new HbDocumentLoader(); |
|
85 bool result = false; |
|
86 documentLoader->load(commLauncherDocml, &result); |
|
87 ASSERT(result); |
|
88 |
|
89 // create buttons |
|
90 const QString callIconName = "qtg_large_active_call"; |
|
91 mCallButton = createButton(callIconName, callButtonName, documentLoader); |
|
92 connect(mCallButton, SIGNAL(clicked()), this, SLOT(makeCall())); |
|
93 |
|
94 const QString messagingIconName = "qtg_large_message"; |
|
95 mSendMsgButton = createButton(messagingIconName, messageButtonName, documentLoader); |
|
96 connect(mSendMsgButton, SIGNAL(clicked()), this, SLOT(sendMessage())); |
|
97 |
|
98 const QString emailIconName = "qtg_large_email"; |
|
99 mEmailButton = createButton(emailIconName, emailButtonName, documentLoader); |
|
100 // EMAIL FUNCTIONALITY COMMENTED OUT BECAUSE PLATFORM DOES NOT SUPPORT IT! |
|
101 //connect(mEmailButton, SIGNAL(clicked()), this, SLOT(sendEmail())); |
|
102 |
|
103 const QString phonebookIconName = "qtg_large_mycard"; |
|
104 mPhonebookButton = createButton(phonebookIconName, mycardButtonName, documentLoader); |
|
105 connect(mPhonebookButton, SIGNAL(clicked()), this, SLOT(openPhonebook())); |
|
106 |
|
107 delete documentLoader; |
|
108 } |
|
109 |
|
110 /*! |
|
111 Destructor |
|
112 */ |
|
113 CommLauncherWidget::~CommLauncherWidget() |
|
114 { |
|
115 // Deleting request cancels all pending requests |
|
116 delete mRequest; |
|
117 } |
|
118 |
|
119 /*! |
|
120 Sets the contact for the widget |
|
121 */ |
|
122 void CommLauncherWidget::setContact(QContact &contact) |
|
123 { |
|
124 mContact = &contact; |
|
125 } |
|
126 |
|
127 /*! |
|
128 Sets the application manager for the widget |
|
129 */ |
|
130 void CommLauncherWidget::setApplicationManager(XQApplicationManager &appManager) |
|
131 { |
|
132 mApplicationManager = &appManager; |
|
133 } |
|
134 |
|
135 /*! |
|
136 Creates the UI for the widget |
|
137 */ |
|
138 void CommLauncherWidget::createUI() |
|
139 { |
|
140 mButtonCount = 0; |
|
141 // Create call button, if number is available |
|
142 QList<QContactActionDescriptor> callActionDescriptors = |
|
143 QContactAction::actionDescriptors("call", cmBackend); |
|
144 if (callActionDescriptors.count() > 0) { |
|
145 QList<QContactPhoneNumber> numberList = mContact->details<QContactPhoneNumber>(); |
|
146 if (numberList.count() > 0) { |
|
147 mLayout->addItem(mCallButton); |
|
148 mCallButton->show(); |
|
149 mButtonCount++; |
|
150 |
|
151 } else { |
|
152 mCallButton->hide(); |
|
153 mLayout->removeItem(mCallButton); |
|
154 mLayout->invalidate(); |
|
155 mLayout->activate(); |
|
156 } |
|
157 } else { |
|
158 qDebug() << "Call button is not created"; |
|
159 } |
|
160 |
|
161 // Create sms button, if number is available |
|
162 QList<QContactActionDescriptor> messageActionDescriptors = |
|
163 QContactAction::actionDescriptors("message", cmBackend); |
|
164 if (messageActionDescriptors.count() > 0) { |
|
165 QList<QContactPhoneNumber> numberList = mContact->details<QContactPhoneNumber>(); |
|
166 if (numberList.count() > 0) { |
|
167 mLayout->addItem(mSendMsgButton); |
|
168 mSendMsgButton->show(); |
|
169 mButtonCount++; |
|
170 } else { |
|
171 mSendMsgButton->hide(); |
|
172 mLayout->removeItem(mSendMsgButton); |
|
173 mLayout->invalidate(); |
|
174 mLayout->activate(); |
|
175 } |
|
176 } else { |
|
177 qDebug() << "Sms button is not created"; |
|
178 } |
|
179 |
|
180 // Create email button, if email count exists |
|
181 // EMAIL FUNCTIONALITY COMMENTED OUT BECAUSE PLATFORM DOES NOT SUPPORT IT! |
|
182 /*QList<QContactActionDescriptor> emailActionDescriptors = |
|
183 QContactAction::actionDescriptors("email", cmBackend); |
|
184 if (emailActionDescriptors.count() > 0) { |
|
185 QList<QContactEmailAddress> emailList = mContact->details<QContactEmailAddress>(); |
|
186 if (emailList.count() > 0) { |
|
187 mLayout->addItem(mEmailButton); |
|
188 mEmailButton->show(); |
|
189 mButtonCount++; |
|
190 } else { |
|
191 mEmailButton->hide(); |
|
192 mLayout->removeItem(mEmailButton); |
|
193 mLayout->invalidate(); |
|
194 mLayout->activate(); |
|
195 } |
|
196 } else { |
|
197 qDebug() << "Email button not created"; |
|
198 } |
|
199 */ |
|
200 |
|
201 mLayout->addItem(mPhonebookButton); |
|
202 mButtonCount++; |
|
203 |
|
204 // add Effects |
|
205 HbEffect::add(this, QString(":/friend_expand_tl.fxml"), appearTL); |
|
206 HbEffect::add(this, QString(":/friend_expand_tr.fxml"), appearTR); |
|
207 HbEffect::add(this, QString(":/friend_expand_bl.fxml"), appearBL); |
|
208 HbEffect::add(this, QString(":/friend_expand_br.fxml"), appearBR); |
|
209 HbEffect::add(this, QString(":/friend_minimize.fxml"), "disappear"); |
|
210 |
|
211 setLayout(mLayout); |
|
212 } |
|
213 |
|
214 /*! |
|
215 This widget is about to show, show effect |
|
216 */ |
|
217 void CommLauncherWidget::popupAboutToShow() |
|
218 { |
|
219 HbEffect::start(this, mAppearEffect); |
|
220 } |
|
221 |
|
222 /* |
|
223 * Select which appear effect to use depending on FriendWidget position |
|
224 */ |
|
225 void CommLauncherWidget::selectAppearEffect(QPointF FriendPos, QPointF LauncherPos) |
|
226 { |
|
227 bool left=true; |
|
228 bool top=true; |
|
229 |
|
230 qDebug() << "FriendPos " << FriendPos; |
|
231 qDebug() << "LauncherPos " << LauncherPos; |
|
232 |
|
233 if (LauncherPos.y() > FriendPos.y()) { |
|
234 top = false; |
|
235 } |
|
236 if (LauncherPos.x() > FriendPos.x()) { |
|
237 left = false; |
|
238 } |
|
239 |
|
240 if (top && left) { |
|
241 mAppearEffect = appearTL; |
|
242 } |
|
243 else if (top && !left) { |
|
244 mAppearEffect = appearTR; |
|
245 } |
|
246 else if (!top && left) { |
|
247 mAppearEffect = appearBL; |
|
248 } |
|
249 else { |
|
250 mAppearEffect = appearBR; |
|
251 } |
|
252 qDebug() << "---------------top " << top << "--- left " << left << " " << mAppearEffect; |
|
253 } |
|
254 |
|
255 /*! |
|
256 This widget is about to close, show effect |
|
257 */ |
|
258 void CommLauncherWidget::popupAboutToClose() |
|
259 { |
|
260 HbEffect::start(this, "disappear"); |
|
261 emit launcherClosed(); |
|
262 } |
|
263 |
|
264 /*! |
|
265 Returns a button with a given name and icon to layout |
|
266 */ |
|
267 HbPushButton* CommLauncherWidget::createButton(const QString iconName, const QString buttonName, |
|
268 const HbDocumentLoader *documentLoader) |
|
269 { |
|
270 HbPushButton *button = 0; |
|
271 button = qobject_cast<HbPushButton *> |
|
272 (documentLoader->findWidget(buttonName)); |
|
273 if (button) { |
|
274 button->setIcon(HbIcon(iconName)); |
|
275 } |
|
276 |
|
277 return button; |
|
278 } |
|
279 |
|
280 |
|
281 /*! |
|
282 Returns screen position for communication launcher for a widget |
|
283 */ |
|
284 QPointF CommLauncherWidget::commLauncherPosition(QPointF widgetPosition, QRectF& widgetBoundingRect, |
|
285 QRectF& sceneRect, QRectF& launcherRect) |
|
286 { |
|
287 QPointF commLauncherPosition(widgetPosition.x(), commLauncherMargin); |
|
288 qDebug() << "friend widgetPosition " << widgetPosition.x() << widgetPosition.y(); |
|
289 |
|
290 qreal topMargin = 0.0; |
|
291 style()->parameter("hb-param-margin-gene-top",topMargin); |
|
292 qDebug() << "topMargin------------ " << topMargin; |
|
293 qDebug() << "launcher size.y " << launcherRect.size().height(); |
|
294 |
|
295 // Calculate vertical position |
|
296 if (widgetPosition.y() > commLauncherMargin) { |
|
297 commLauncherPosition.setY(widgetPosition.y() - launcherRect.size().height() + topMargin ); |
|
298 } else { |
|
299 commLauncherPosition.setY(widgetPosition.y() + widgetBoundingRect.height() |
|
300 - launcherRect.size().height()/2); |
|
301 } |
|
302 |
|
303 // Calculate horizontal position |
|
304 if ((widgetPosition.x() + widgetBoundingRect.width()/2) < sceneRect.width()/2 ) { |
|
305 // Communication launcher to the right |
|
306 qDebug() << "launcher to right"; |
|
307 commLauncherPosition.setX(widgetPosition.x() + widgetBoundingRect.width()/2); |
|
308 |
|
309 } else { |
|
310 // Communication launcher to the left |
|
311 qDebug() << "launcher to left"; |
|
312 // The width needs to be calculated based on visible buttons. |
|
313 launcherRect.setWidth(commLauncherWidth()); |
|
314 commLauncherPosition.setX(widgetPosition.x() + widgetBoundingRect.width()/2 |
|
315 - launcherRect.size().width()); |
|
316 } |
|
317 |
|
318 // Check that the communication launcher is not positioned outside the scene in y-axis |
|
319 // HbPopup takes care that the launcher is not positioned outside the scene in x-axis |
|
320 if (commLauncherPosition.y() > sceneRect.height()) { |
|
321 commLauncherPosition.setY(sceneRect.height()); |
|
322 } else if (commLauncherPosition.y() < sceneRect.y()){ |
|
323 commLauncherPosition.setY(sceneRect.y()); |
|
324 } |
|
325 |
|
326 qDebug() << "commLauncherPosition " << commLauncherPosition.x() << commLauncherPosition.y(); |
|
327 return commLauncherPosition; |
|
328 } |
|
329 |
|
330 |
|
331 /*! |
|
332 Makes a phone call to contact. |
|
333 */ |
|
334 void CommLauncherWidget::makeCall() |
|
335 { |
|
336 QList<QContactActionDescriptor> callActionDescriptors = |
|
337 QContactAction::actionDescriptors("call", cmBackend); |
|
338 if (callActionDescriptors.count() > 0) { |
|
339 //Get preferred number |
|
340 QContactDetail detail = mContact->preferredDetail("call"); |
|
341 QContactPhoneNumber phoneNumber; |
|
342 |
|
343 //If preferred number is available, cast it to phonenumber |
|
344 if(!detail.isEmpty()) { |
|
345 phoneNumber = static_cast<QContactPhoneNumber>(detail); |
|
346 } else { |
|
347 //if preferred is not set select the first number |
|
348 phoneNumber = mContact->detail<QContactPhoneNumber>(); |
|
349 } |
|
350 // invoke action |
|
351 QContactAction *callAction = QContactAction::action(callActionDescriptors.at(0)); |
|
352 if (!phoneNumber.isEmpty()) { |
|
353 callAction->invokeAction(*mContact, phoneNumber); |
|
354 |
|
355 qDebug() << "call to number " << phoneNumber.number(); |
|
356 } |
|
357 } else { |
|
358 qDebug() << "contact has no Actions, can't make a call"; |
|
359 } |
|
360 |
|
361 close(); |
|
362 } |
|
363 |
|
364 /*! |
|
365 Sends a message to contact. |
|
366 */ |
|
367 void CommLauncherWidget::sendMessage() |
|
368 { |
|
369 QList<QContactActionDescriptor> messageActionDescriptors = |
|
370 QContactAction::actionDescriptors("message", cmBackend); |
|
371 if (messageActionDescriptors.count() > 0) { |
|
372 //Get preferred message number |
|
373 QContactDetail detail = mContact->preferredDetail("message"); |
|
374 QContactPhoneNumber messageNumber; |
|
375 |
|
376 //If preferred number is available, cast it to phonenumber |
|
377 if(!detail.isEmpty()) { |
|
378 messageNumber = static_cast<QContactPhoneNumber>(detail); |
|
379 } else { |
|
380 //if preferred is not set select the first number |
|
381 messageNumber = mContact->detail<QContactPhoneNumber>(); |
|
382 } |
|
383 // invoke action |
|
384 QContactAction *messageAction = QContactAction::action(messageActionDescriptors.at(0)); |
|
385 if (!messageNumber.isEmpty()) { |
|
386 messageAction->invokeAction(*mContact, messageNumber); |
|
387 |
|
388 qDebug() << "send to number " << messageNumber.number(); |
|
389 } |
|
390 } else { |
|
391 qDebug() << "contact has no Actions, can't send a message"; |
|
392 } |
|
393 |
|
394 close(); |
|
395 } |
|
396 |
|
397 /*! |
|
398 Sends an email to contact. |
|
399 */ |
|
400 // EMAIL FUNCTIONALITY COMMENTED OUT BECAUSE WK20 PLATFORM DOES NOT SUPPORT IT! |
|
401 |
|
402 /* |
|
403 void CommLauncherWidget::sendEmail() |
|
404 { |
|
405 |
|
406 QList<QContactActionDescriptor> emailActionDescriptors = |
|
407 QContactAction::actionDescriptors("email", cmBackend); |
|
408 if (emailActionDescriptors.count() > 0) { |
|
409 QContactAction *emailAction = QContactAction::action(emailActionDescriptors.at(0)); |
|
410 //TODO: implement |
|
411 QList<QContactEmailAddress> emailList = mContact->details<QContactEmailAddress>(); |
|
412 if (emailList.count() > 0) { |
|
413 emailAction->invokeAction(*mContact, emailList.at(0)); |
|
414 |
|
415 QString emailAddress = emailList.at(0).emailAddress(); |
|
416 qDebug() << "send to email " << emailAddress; |
|
417 } |
|
418 } else { |
|
419 qDebug() << "contact has no Actions, can't send a email"; |
|
420 } |
|
421 |
|
422 // Deleting request cancels all pending requests |
|
423 if (mRequest) { |
|
424 delete mRequest; |
|
425 mRequest = NULL; |
|
426 } |
|
427 |
|
428 QMap<QString, QVariant> map; |
|
429 static const QString emailSendToKey = "to"; |
|
430 QString emailAddress; |
|
431 QList<QContactEmailAddress> emailList = mContact->details<QContactEmailAddress>(); |
|
432 if (emailList.count() > 0) { |
|
433 emailAddress = emailList.at(0).emailAddress(); |
|
434 } |
|
435 |
|
436 // Add to recipient: |
|
437 map.insert(emailSendToKey, QVariant::fromValue(emailAddress)); |
|
438 QVariant mapAsVariant = QVariant::fromValue(map); |
|
439 |
|
440 mRequest = mApplicationManager->create("com.nokia.symbian.IMessage", |
|
441 "Send", "send(QVariant)", false); |
|
442 if (mRequest) { |
|
443 mRequest->setSynchronous(false); |
|
444 QList<QVariant> arguments; |
|
445 arguments.append(mapAsVariant); |
|
446 mRequest->setArguments(arguments); |
|
447 bool result = mRequest->send(); |
|
448 if (!result) { |
|
449 qDebug() << "Sending request failed: " << mRequest->lastErrorMessage(); |
|
450 } |
|
451 } else { |
|
452 qDebug() << "Creating service request failed"; |
|
453 } |
|
454 |
|
455 close(); |
|
456 } |
|
457 */ |
|
458 |
|
459 /*! |
|
460 Opens contact card from phonebook to contact. |
|
461 */ |
|
462 void CommLauncherWidget::openPhonebook() |
|
463 { |
|
464 // Deleting request cancels all pending requests |
|
465 if (mRequest) { |
|
466 delete mRequest; |
|
467 mRequest = NULL; |
|
468 } |
|
469 mRequest = mApplicationManager->create("com.nokia.services.phonebookservices", |
|
470 "Fetch", "open(int)", false); |
|
471 if (mRequest) { |
|
472 mRequest->setSynchronous(false); |
|
473 QList<QVariant> arguments; |
|
474 arguments.append(QVariant(mContact->localId())); |
|
475 mRequest->setArguments(arguments); |
|
476 bool result = mRequest->send(); |
|
477 if (!result) { |
|
478 qDebug() << "Sending request failed: " << mRequest->lastErrorMessage(); |
|
479 } |
|
480 } else { |
|
481 qDebug() << "Creating service request failed"; |
|
482 } |
|
483 |
|
484 close(); |
|
485 } |
|
486 |
|
487 /*! |
|
488 Opens phonebook to create a new contact. |
|
489 */ |
|
490 void CommLauncherWidget::openPhonebookCreateNew() |
|
491 { |
|
492 // Deleting request cancels all pending requests |
|
493 if (mRequest) { |
|
494 delete mRequest; |
|
495 mRequest = NULL; |
|
496 } |
|
497 mRequest = mApplicationManager->create("com.nokia.services.phonebookservices", |
|
498 "Fetch", "editCreateNew(QString,QString)", false); |
|
499 if (mRequest) { |
|
500 QList<QVariant> arguments; |
|
501 QString type = QContactPhoneNumber::DefinitionName; |
|
502 arguments.append(QVariant( type )); |
|
503 arguments.append(QVariant( "" )); |
|
504 mRequest->setArguments(arguments); |
|
505 |
|
506 bool result = mRequest->send(); |
|
507 if (!result) { |
|
508 qDebug() << "Sending request failed: " << mRequest->lastErrorMessage(); |
|
509 } |
|
510 |
|
511 } else { |
|
512 qDebug() << "Creating service request failed"; |
|
513 } |
|
514 } |
|
515 |
|
516 /*! |
|
517 Handles call key events |
|
518 */ |
|
519 void CommLauncherWidget::keyPressEvent(QKeyEvent *event) |
|
520 { |
|
521 if (event->key() == Qt::Key_Yes) { |
|
522 // Call key initializes a call |
|
523 makeCall(); |
|
524 event->accept(); |
|
525 } else if (event->key() == Qt::Key_No || event->key() == Qt::Key_Select) { |
|
526 // End key and Select key close the communication launcher and |
|
527 // forward the key event to HbPopup |
|
528 close(); |
|
529 HbPopup::keyPressEvent(event); |
|
530 } else { |
|
531 HbPopup::keyPressEvent(event); |
|
532 } |
|
533 } |
|
534 |
|
535 /*! |
|
536 Counts the width for the launcher. |
|
537 The width is not known before the launcher is drawn for the first time. |
|
538 */ |
|
539 int CommLauncherWidget::commLauncherWidth() |
|
540 { |
|
541 int width = 0; |
|
542 qreal verticalMargin = 0.0; |
|
543 style()->parameter("hb-param-margin-gene-middle-vertical", verticalMargin); |
|
544 qreal unit = HbDeviceProfile::current().unitValue(); |
|
545 const int buttonSize = 9 * unit; |
|
546 |
|
547 width = mButtonCount * buttonSize + (mButtonCount + 1) * verticalMargin; |
|
548 |
|
549 return width; |
|
550 } |
|
551 |