|
1 /* |
|
2 * Copyright (c) 2009 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "nmuiheaders.h" |
|
19 |
|
20 static const char *NMUI_MESSAGE_VIEWER_XML = ":/docml/nmmailviewer.docml"; |
|
21 static const char *NMUI_MESSAGE_VIEWER_VIEW = "nmailViewerView"; |
|
22 static const char *NMUI_MESSAGE_VIEWER_CONTENT = "content"; |
|
23 static const char *NMUI_MESSAGE_VIEWER_SCROLL_AREA = "viewerScrollArea"; |
|
24 static const char *NMUI_MESSAGE_VIEWER_SCROLL_AREA_CONTENTS = "viewerScrollAreaContents"; |
|
25 static const char *NMUI_MESSAGE_VIEWER_HEADER = "viewerHeader"; |
|
26 static const char *NMUI_MESSAGE_VIEWER_SCROLL_WEB_VIEW = "viewerWebView"; |
|
27 |
|
28 static const int nmViewLoadTimer=10; |
|
29 |
|
30 /*! |
|
31 \class NmViewerView |
|
32 \brief Mail viewer class |
|
33 */ |
|
34 |
|
35 /*! |
|
36 Constructor |
|
37 */ |
|
38 NmViewerView::NmViewerView( |
|
39 NmApplication &application, |
|
40 NmUiStartParam* startParam, |
|
41 NmUiEngine &uiEngine, |
|
42 HbMainWindow *mainWindow, |
|
43 QGraphicsItem *parent) |
|
44 :NmBaseView(startParam, parent), |
|
45 mApplication(application), |
|
46 mUiEngine(uiEngine), |
|
47 mMainWindow(mainWindow), |
|
48 mMessage(NULL), |
|
49 mScrollArea(NULL), |
|
50 mViewerContent(NULL), |
|
51 mWebView(NULL), |
|
52 mHeaderWidget(NULL), |
|
53 mViewerContentLayout(NULL), |
|
54 mMessageFetchingOperation(NULL), |
|
55 mDisplayingPlainText(false), |
|
56 mDocumentLoader(NULL), |
|
57 mScrollAreaContents(NULL), |
|
58 mViewerHeaderContainer(NULL), |
|
59 mScreenSize(QSize(0,0)), |
|
60 mWaitDialog(NULL), |
|
61 loadingCompleted(false), |
|
62 mLatestLoadingSize(QSize(0,0)) |
|
63 { |
|
64 // Create documentloader |
|
65 mDocumentLoader = new NmUiDocumentLoader(mMainWindow); |
|
66 // Get screensize |
|
67 mScreenSize = mApplication.screenSize(); |
|
68 // Fetch message |
|
69 loadMessage(); |
|
70 // Load view layout |
|
71 loadViewLayout(); |
|
72 // Set message data |
|
73 QTimer::singleShot(nmViewLoadTimer, this, SLOT(fetchMessage())); |
|
74 } |
|
75 |
|
76 /*! |
|
77 Destructor |
|
78 */ |
|
79 NmViewerView::~NmViewerView() |
|
80 { |
|
81 delete mWebView; |
|
82 mWebView=NULL; |
|
83 delete mMessage; |
|
84 mMessage = NULL; |
|
85 delete mDocumentLoader; |
|
86 mDocumentLoader = NULL; |
|
87 mWidgetList.clear(); |
|
88 delete mWaitDialog; |
|
89 mWaitDialog = NULL; |
|
90 } |
|
91 |
|
92 /*! |
|
93 View layout loading from XML |
|
94 */ |
|
95 void NmViewerView::loadViewLayout() |
|
96 { |
|
97 // Use document loader to load the view |
|
98 bool ok = false; |
|
99 setObjectName(QString(NMUI_MESSAGE_VIEWER_VIEW)); |
|
100 QObjectList objectList; |
|
101 objectList.append(this); |
|
102 // Pass the view to documentloader. Document loader uses this view |
|
103 // when docml is parsed, instead of creating new view. |
|
104 if (mDocumentLoader) { |
|
105 mDocumentLoader->setObjectTree(objectList); |
|
106 mWidgetList = mDocumentLoader->load(NMUI_MESSAGE_VIEWER_XML, &ok); |
|
107 } |
|
108 int widgetCount = mWidgetList.count(); |
|
109 if (ok == true && widgetCount) |
|
110 { |
|
111 // Create content and content layout |
|
112 mViewerContent = reinterpret_cast<HbWidget *>( |
|
113 mDocumentLoader->findObject(NMUI_MESSAGE_VIEWER_CONTENT)); |
|
114 // Find scroll area |
|
115 mScrollArea = reinterpret_cast<NmBaseViewScrollArea *>( |
|
116 mDocumentLoader->findObject(NMUI_MESSAGE_VIEWER_SCROLL_AREA)); |
|
117 if (mScrollArea){ |
|
118 mScrollArea->setParentItem(this); |
|
119 mScrollArea->setScrollDirections(Qt::Vertical | Qt::Horizontal); |
|
120 connect(mScrollArea, SIGNAL(scrollPositionChanged(QPointF)), |
|
121 this, SLOT(contentScrollPositionChanged(QPointF))); |
|
122 connect(mScrollArea, SIGNAL(handleMousePressEvent(QGraphicsSceneMouseEvent*)), |
|
123 this, SLOT(handleMousePressEvent(QGraphicsSceneMouseEvent*))); |
|
124 connect(mScrollArea, SIGNAL(handleMouseReleaseEvent(QGraphicsSceneMouseEvent*)), |
|
125 this, SLOT(handleMouseReleaseEvent(QGraphicsSceneMouseEvent*))); |
|
126 |
|
127 // Get scroll area contents and set layout margins |
|
128 mScrollAreaContents = qobject_cast<HbWidget *>( |
|
129 mDocumentLoader->findObject(NMUI_MESSAGE_VIEWER_SCROLL_AREA_CONTENTS)); |
|
130 if (mScrollAreaContents->layout()){ |
|
131 mScrollAreaContents->layout()->setContentsMargins(0,0,0,0); |
|
132 } |
|
133 |
|
134 // Set white pixmap to backgrounditem |
|
135 QPixmap whitePixmap(10,10); |
|
136 whitePixmap.fill(Qt::white); |
|
137 QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(whitePixmap); |
|
138 mScrollAreaContents->setBackgroundItem(pixmapItem); |
|
139 |
|
140 // Load headerwidget |
|
141 mHeaderWidget = qobject_cast<NmViewerHeader *>( |
|
142 mDocumentLoader->findObject(NMUI_MESSAGE_VIEWER_HEADER)); |
|
143 if (mHeaderWidget) { |
|
144 mHeaderWidget->setView(this); |
|
145 mHeaderWidget->rescaleHeader(mScreenSize); |
|
146 mHeaderWidget->setMessage(mMessage); |
|
147 mHeaderStartScenePos = mHeaderWidget->scenePos(); |
|
148 } |
|
149 |
|
150 // Load webview |
|
151 mWebView = reinterpret_cast<NmMailViewerWK *>( |
|
152 mDocumentLoader->findObject(QString(NMUI_MESSAGE_VIEWER_SCROLL_WEB_VIEW))); |
|
153 if (mWebView){ |
|
154 mWebView->setParentView(this); |
|
155 HbEditorInterface editorInterface(mWebView); |
|
156 editorInterface.setConstraints(HbEditorConstraintIgnoreFocus); |
|
157 mWebView->setAcceptedMouseButtons(Qt::NoButton); |
|
158 if (mWebView->page()){ |
|
159 mWebView->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, |
|
160 Qt::ScrollBarAlwaysOff); |
|
161 mWebView->page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, |
|
162 Qt::ScrollBarAlwaysOff); |
|
163 bool connectOk = connect(mWebView->page()->mainFrame(), SIGNAL(contentsSizeChanged(const QSize&)), |
|
164 this, SLOT(scaleWebViewWhenLoading(const QSize&))); |
|
165 } |
|
166 } |
|
167 } |
|
168 } |
|
169 // call the createToolBar on load view layout |
|
170 createToolBar(); |
|
171 // Set mailbox name to title |
|
172 setMailboxName(); |
|
173 } |
|
174 |
|
175 /*! |
|
176 Function fecthes message data based on parameters |
|
177 */ |
|
178 void NmViewerView::loadMessage() |
|
179 { |
|
180 if (mMessage) { |
|
181 delete mMessage; |
|
182 mMessage = NULL; |
|
183 } |
|
184 NmId mailboxId; |
|
185 NmId folderId; |
|
186 NmId msgId; |
|
187 // Read start params and message object |
|
188 if (mStartParam){ |
|
189 mailboxId = mStartParam->mailboxId(); |
|
190 folderId = mStartParam->folderId(); |
|
191 msgId = mStartParam->messageId(); |
|
192 mMessage = mUiEngine.message(mailboxId, folderId, msgId); |
|
193 } |
|
194 } |
|
195 |
|
196 /*! |
|
197 Function fecthes message data based on parameters. Returns false if message is available, |
|
198 true if message have to be fetched |
|
199 */ |
|
200 void NmViewerView::fetchMessage() |
|
201 { |
|
202 #ifdef Q_OS_SYMBIAN |
|
203 if (mMessage) { |
|
204 NmId mailboxId = mStartParam->mailboxId(); |
|
205 NmId folderId = mStartParam->folderId(); |
|
206 NmId msgId = mStartParam->messageId(); |
|
207 NmMessagePart *body = mMessage->htmlBodyPart(); |
|
208 if (!body) { |
|
209 // try plain to plain text part |
|
210 body = mMessage->plainTextBodyPart(); |
|
211 } |
|
212 // try to fetch if body missing or fetched size is smaller than content size |
|
213 // if body missing it might mean that only header is fetched or message has no body |
|
214 if (!body || (body && (body->fetchedSize() < body->size()))) { |
|
215 // start fetching operation |
|
216 if (mMessageFetchingOperation) { |
|
217 mMessageFetchingOperation->cancelOperation(); |
|
218 delete mMessageFetchingOperation; |
|
219 mMessageFetchingOperation = NULL; |
|
220 } |
|
221 mMessageFetchingOperation = mUiEngine.fetchMessage(mailboxId, folderId, msgId); |
|
222 |
|
223 if (mMessageFetchingOperation) { |
|
224 // QObject handles deletion |
|
225 mMessageFetchingOperation->setParent(this); |
|
226 connect(mMessageFetchingOperation, |
|
227 SIGNAL(operationCompleted(int)), |
|
228 this, |
|
229 SLOT(messageFetched(int))); |
|
230 |
|
231 delete mWaitDialog; |
|
232 mWaitDialog = NULL; |
|
233 |
|
234 mWaitDialog = new HbProgressDialog(HbProgressDialog::WaitDialog); |
|
235 mWaitDialog->setModal(true); |
|
236 connect(mWaitDialog, SIGNAL(cancelled()), this, SLOT(waitNoteCancelled())); |
|
237 mWaitDialog->setText(hbTrId("txt_mail_dialog_loading_mail_content")); |
|
238 mWaitDialog->show(); |
|
239 } |
|
240 } |
|
241 else { |
|
242 // message is fetched |
|
243 setMessageData(); |
|
244 } |
|
245 |
|
246 } |
|
247 #else |
|
248 setMessageData(); |
|
249 #endif |
|
250 } |
|
251 |
|
252 /*! |
|
253 This is signalled by mMessageFetchingOperation when the original message is fetched. |
|
254 */ |
|
255 void NmViewerView::messageFetched(int result) |
|
256 { |
|
257 delete mWaitDialog; |
|
258 mWaitDialog = NULL; |
|
259 |
|
260 if (result == NmNoError && mMessageFetchingOperation) { |
|
261 if (mMessage) { |
|
262 delete mMessage; |
|
263 mMessage = NULL; |
|
264 } |
|
265 NmId mailboxId; |
|
266 NmId folderId; |
|
267 NmId msgId; |
|
268 // Read start params and message object |
|
269 if (mStartParam){ |
|
270 mailboxId = mStartParam->mailboxId(); |
|
271 folderId = mStartParam->folderId(); |
|
272 msgId = mStartParam->messageId(); |
|
273 mMessage = mUiEngine.message(mailboxId, folderId, msgId); |
|
274 } |
|
275 setMessageData(); |
|
276 // Update header message data |
|
277 if (mHeaderWidget){ |
|
278 mHeaderWidget->updateMessageData(mMessage); |
|
279 } |
|
280 } |
|
281 } |
|
282 |
|
283 |
|
284 /*! |
|
285 This is signalled by mWaitDialog when the note is cancelled |
|
286 */ |
|
287 void NmViewerView::waitNoteCancelled() |
|
288 { |
|
289 if (mMessageFetchingOperation) { |
|
290 mMessageFetchingOperation->cancelOperation(); |
|
291 } |
|
292 QTimer::singleShot(nmViewLoadTimer, &mApplication, SLOT(popView())); |
|
293 } |
|
294 |
|
295 |
|
296 /*! |
|
297 Function sets message data to web view and header |
|
298 */ |
|
299 void NmViewerView::setMessageData() |
|
300 { |
|
301 // Connect to observe orientation change events |
|
302 connect(mApplication.mainWindow(), SIGNAL(orientationChanged(Qt::Orientation)), |
|
303 this, SLOT(orientationChanged(Qt::Orientation))); |
|
304 |
|
305 // Set page parameters |
|
306 QWebPage *page(NULL); |
|
307 if (mWebView){ |
|
308 page = mWebView->page(); |
|
309 } |
|
310 if (page){ |
|
311 // Set custom network access manager for embedded image handling |
|
312 NmViewerViewNetManager* netMngr = mApplication.networkAccessManager(); |
|
313 if (netMngr){ |
|
314 netMngr->setView(this); |
|
315 page->setNetworkAccessManager(netMngr); |
|
316 } |
|
317 connect(page, SIGNAL(loadFinished(bool)), |
|
318 this, SLOT(webFrameLoaded(bool))); |
|
319 page->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); |
|
320 page->setContentEditable(false); |
|
321 } |
|
322 |
|
323 // if everything is ok, set message to html viewer |
|
324 if (mMessage && mWebView && page) { |
|
325 // Set initial size of component and content before loading data |
|
326 mWebView->setMaximumWidth(mScreenSize.width()); |
|
327 page->setPreferredContentsSize(mScreenSize); |
|
328 //Set message data to html viewer. |
|
329 mWebView->setHtml(formatMessage()); |
|
330 // Connect to link clicked |
|
331 QObject::connect(page, SIGNAL(linkClicked(const QUrl&)), |
|
332 this, SLOT(linkClicked(const QUrl&))); |
|
333 changeMessageReadStatus(true); |
|
334 } |
|
335 } |
|
336 |
|
337 /*! |
|
338 Function formats message based on actual data |
|
339 */ |
|
340 QString NmViewerView::formatMessage() |
|
341 { |
|
342 QString msg = ""; |
|
343 QString body = ""; |
|
344 // null pointer check for mMessage is done before calling this function |
|
345 NmMessagePart *html = mMessage->htmlBodyPart(); |
|
346 if (html) { |
|
347 QList<NmMessagePart*> parts; |
|
348 mMessage->attachmentList(parts); |
|
349 for (int i=0; i < parts.count(); i++) { |
|
350 NmMessagePart *child = parts[i]; |
|
351 // Browse through embedded image parts and add those |
|
352 // the web view. |
|
353 if (child->contentType().startsWith("image", Qt::CaseInsensitive)) { |
|
354 QString contentId = child->contentId(); |
|
355 int ret = mUiEngine.contentToMessagePart( |
|
356 mMessage->mailboxId(), |
|
357 mMessage->parentId(), |
|
358 mMessage->envelope().id(), |
|
359 *child); |
|
360 if (ret == NmNoError) { |
|
361 mWebView->addContent(contentId, QVariant::fromValue(child->binaryContent())); |
|
362 } |
|
363 } |
|
364 } |
|
365 int ret = mUiEngine.contentToMessagePart( |
|
366 mMessage->mailboxId(), |
|
367 mMessage->parentId(), |
|
368 mMessage->envelope().id(), |
|
369 *html); |
|
370 if (ret == NmNoError) { |
|
371 body = html->textContent(); |
|
372 } |
|
373 msg = body; |
|
374 } |
|
375 else { |
|
376 NmMessagePart *plain = mMessage->plainTextBodyPart(); |
|
377 if (plain) { |
|
378 int ret = mUiEngine.contentToMessagePart( |
|
379 mMessage->mailboxId(), |
|
380 mMessage->parentId(), |
|
381 mMessage->envelope().id(), |
|
382 *plain); |
|
383 if (ret == NmNoError) { |
|
384 body += escapeSpecialCharacters(plain->textContent()); |
|
385 } |
|
386 // Set plain text to viewer according to layout direction |
|
387 if (qApp->layoutDirection()==Qt::LeftToRight){ |
|
388 // Define html start and end tags for plain text |
|
389 QString start = "<html><body text=\"black\"><P align=\"left\">"; |
|
390 QString end = "</p></body></html>"; |
|
391 msg = start + body + end; |
|
392 } |
|
393 else { |
|
394 // Define html start and end tags for plain text |
|
395 QString start = "<html><body text=\"black\"><P align=\"right\">"; |
|
396 QString end = "</p></body></html>"; |
|
397 msg = start + body + end; |
|
398 } |
|
399 mDisplayingPlainText=true; |
|
400 } |
|
401 } |
|
402 return msg; |
|
403 } |
|
404 |
|
405 /*! |
|
406 Reload view contents with new start parameters |
|
407 Typically when view is already open and external view activation occurs |
|
408 for this same view |
|
409 */ |
|
410 void NmViewerView::reloadViewContents(NmUiStartParam* startParam) |
|
411 { |
|
412 // Check start parameter validity, message view cannot |
|
413 // be updated if given parameter is zero. |
|
414 if (startParam && startParam->viewId() == NmUiViewMessageViewer && |
|
415 startParam->messageId()!= 0) { |
|
416 // Delete existing start parameter data |
|
417 delete mStartParam; |
|
418 mStartParam = NULL; |
|
419 // Store new start parameter data |
|
420 mStartParam = startParam; |
|
421 // Reload viewer with new message information |
|
422 setMessageData(); |
|
423 } |
|
424 else { |
|
425 NMLOG("nmailui: Invalid viewer start parameter"); |
|
426 // Unused start parameter needs to be deleted |
|
427 delete startParam; |
|
428 } |
|
429 } |
|
430 |
|
431 /*! |
|
432 nmailViewId |
|
433 */ |
|
434 NmUiViewId NmViewerView::nmailViewId() const |
|
435 { |
|
436 return NmUiViewMessageViewer; |
|
437 } |
|
438 |
|
439 /*! |
|
440 Scale web view width |
|
441 */ |
|
442 void NmViewerView::webFrameLoaded(bool loaded) |
|
443 { |
|
444 if (loaded){ |
|
445 loadingCompleted = true; |
|
446 // Scale web view after loading the |
|
447 // complete contents, including images |
|
448 QTimer::singleShot(nmViewLoadTimer, this, SLOT(scaleWebViewWhenLoaded())); |
|
449 } |
|
450 } |
|
451 |
|
452 /*! |
|
453 Scale web view width when loading is ongoing |
|
454 */ |
|
455 void NmViewerView::scaleWebViewWhenLoading(const QSize &size) |
|
456 { |
|
457 // Try to scale web view while mainframe is being loaded. |
|
458 // So that screen is scrollable even before images are fully loaded |
|
459 // First check that new size is different than previous, no need to react if |
|
460 // same size value is received more than once. |
|
461 if (size!=mLatestLoadingSize){ |
|
462 if (!loadingCompleted&&mWebView&&mWebView->page()&& |
|
463 (size.width()>mScreenSize.width()||size.height()>mScreenSize.height())) { |
|
464 int width = (int)size.width(); |
|
465 int height = (int)size.height(); |
|
466 // Set content (webview) width |
|
467 if (mDisplayingPlainText){ |
|
468 mWebView->setMaximumWidth(mScreenSize.width()); |
|
469 mWebView->setMinimumWidth(mScreenSize.width()); |
|
470 mWebView->setPreferredWidth(mScreenSize.width()); |
|
471 } |
|
472 else { |
|
473 mWebView->setMaximumWidth(width); |
|
474 mWebView->setMinimumWidth(width); |
|
475 mWebView->setPreferredWidth(width); |
|
476 } |
|
477 mWebView->setMinimumHeight(height); |
|
478 mWebView->setPreferredHeight(height); |
|
479 } |
|
480 } |
|
481 mLatestLoadingSize=size; |
|
482 } |
|
483 |
|
484 /*! |
|
485 Scale web view width when loading is completed |
|
486 */ |
|
487 void NmViewerView::scaleWebViewWhenLoaded() |
|
488 { |
|
489 if (mWebView&&mWebView->page()) { |
|
490 QSizeF contentSize = mWebView->page()->mainFrame()->contentsSize(); |
|
491 int width = (int)contentSize.width(); |
|
492 int height = (int)contentSize.height(); |
|
493 // Set content (webview) width |
|
494 if (mDisplayingPlainText){ |
|
495 mWebView->page()->setPreferredContentsSize(mScreenSize); |
|
496 mWebView->setMinimumWidth(mScreenSize.width()); |
|
497 mWebView->setMaximumWidth(mScreenSize.width()); |
|
498 mWebView->setPreferredWidth(mScreenSize.width()); |
|
499 } |
|
500 else { |
|
501 mWebView->setMinimumWidth(width); |
|
502 mWebView->setMaximumWidth(width); |
|
503 mWebView->setPreferredWidth(width); |
|
504 } |
|
505 // Set content (webview) height |
|
506 if (mScrollAreaContents){ |
|
507 QRectF contentRect = mScrollAreaContents->geometry(); |
|
508 if (contentRect.height()<geometry().height()){ |
|
509 contentRect.setHeight(geometry().height()); |
|
510 mViewerContent->setPreferredHeight(contentRect.height()); |
|
511 qreal webViewHeight = geometry().height()-mHeaderWidget->geometry().height(); |
|
512 mWebView->setMinimumHeight(webViewHeight); |
|
513 mWebView->setMaximumHeight(webViewHeight); |
|
514 mWebView->setPreferredHeight(webViewHeight); |
|
515 } |
|
516 else{ |
|
517 mWebView->setMinimumHeight(height); |
|
518 mWebView->setMaximumHeight(height); |
|
519 mWebView->setPreferredHeight(height); |
|
520 } |
|
521 } |
|
522 } |
|
523 } |
|
524 |
|
525 |
|
526 /*! |
|
527 Screen orientation changed. Web view needs to be scaled when |
|
528 landscape <-> portrait switch occurs because text needs to |
|
529 be wrapped again. |
|
530 */ |
|
531 void NmViewerView::orientationChanged(Qt::Orientation orientation) |
|
532 { |
|
533 Q_UNUSED(orientation); |
|
534 // Update current screensize |
|
535 mScreenSize = mApplication.screenSize(); |
|
536 // Scale header to screen width |
|
537 if (mHeaderWidget){ |
|
538 mHeaderWidget->rescaleHeader(mScreenSize); |
|
539 } |
|
540 |
|
541 // Scale web view and its contens |
|
542 if (mWebView){ |
|
543 if (mDisplayingPlainText){ |
|
544 mWebView->setMaximumWidth((int)mScreenSize.width()); |
|
545 mWebView->page()->setPreferredContentsSize(QSize((int)mScreenSize.width(), |
|
546 (int)mScreenSize.height())); |
|
547 } |
|
548 else{ |
|
549 // Check whether contentsize fits to screen |
|
550 // and if not, set preferred size again to allow panning |
|
551 QSizeF contentSize = mWebView->page()->mainFrame()->contentsSize(); |
|
552 if (contentSize.width()>mScreenSize.width()){ |
|
553 mWebView->setMaximumWidth((int)contentSize.width()); |
|
554 mWebView->page()->setPreferredContentsSize(QSize((int)contentSize.width(), |
|
555 (int)contentSize.height())); |
|
556 } |
|
557 else{ |
|
558 mWebView->setMaximumWidth((int)mScreenSize.width()); |
|
559 mWebView->page()->setPreferredContentsSize(QSize((int)mScreenSize.width(), |
|
560 (int)mScreenSize.height())); |
|
561 } |
|
562 } |
|
563 } |
|
564 |
|
565 // Re-create toolbar in orientation switch |
|
566 createToolBar(); |
|
567 } |
|
568 |
|
569 /*! |
|
570 Link clicked callback |
|
571 */ |
|
572 void NmViewerView::linkClicked(const QUrl& link) |
|
573 { |
|
574 NMLOG("link clicked"); |
|
575 if (link.scheme() == "http" || |
|
576 link.scheme() == "https" ) { |
|
577 QDesktopServices::openUrl(link); |
|
578 } |
|
579 else if (link.scheme() == "mailto"){ |
|
580 QList<NmAddress*> *addrList = new QList<NmAddress*>(); |
|
581 NmAddress *mailtoAddr = new NmAddress(); |
|
582 QString address = link.toString(QUrl::RemoveScheme); |
|
583 mailtoAddr->setAddress(address); |
|
584 mailtoAddr->setDisplayName(address); |
|
585 addrList->append(mailtoAddr); |
|
586 // Create start parameters. Address list ownership |
|
587 // is transferred to startparam object |
|
588 NmUiStartParam* param = new NmUiStartParam(NmUiViewMessageEditor, |
|
589 mStartParam->mailboxId(), |
|
590 mStartParam->folderId(), |
|
591 0, NmUiEditorMailto, addrList ); |
|
592 mApplication.enterNmUiView(param); |
|
593 } |
|
594 } |
|
595 |
|
596 /*! |
|
597 Send mouse release event to web view |
|
598 */ |
|
599 void NmViewerView::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event) |
|
600 { |
|
601 NmMailViewerWK* view = webView(); |
|
602 if (event&& view && mHeaderWidget && mScrollAreaContents) { |
|
603 QPointF lastReleasePoint = event->pos(); |
|
604 QPointF contentWidgetPos = mScrollAreaContents->pos(); |
|
605 qreal headerHeight = mHeaderWidget->geometry().height(); |
|
606 qreal y = lastReleasePoint.y()-headerHeight; |
|
607 y -= contentWidgetPos.y(); |
|
608 qreal x = lastReleasePoint.x()-contentWidgetPos.x(); |
|
609 const QPointF pointToWebView(x, y); |
|
610 event->setPos(pointToWebView); |
|
611 event->setAccepted(true); |
|
612 view->sendMouseReleaseEvent(event); |
|
613 } |
|
614 } |
|
615 |
|
616 /*! |
|
617 Send mouse press event |
|
618 */ |
|
619 void NmViewerView::handleMousePressEvent(QGraphicsSceneMouseEvent *event) |
|
620 { |
|
621 NmMailViewerWK* view = webView(); |
|
622 if (event&& view && mHeaderWidget && mScrollAreaContents) { |
|
623 QPointF lastPressPoint = event->pos(); |
|
624 QPointF contentWidgetPos = mScrollAreaContents->pos(); |
|
625 qreal headerHeight = mHeaderWidget->geometry().height(); |
|
626 qreal y = lastPressPoint.y()-headerHeight; |
|
627 y -= contentWidgetPos.y(); |
|
628 qreal x = lastPressPoint.x()-contentWidgetPos.x(); |
|
629 const QPointF pointToWebView(x, y); |
|
630 event->setPos(pointToWebView); |
|
631 event->setAccepted(true); |
|
632 view->sendMousePressEvent(event); |
|
633 } |
|
634 } |
|
635 |
|
636 /*! |
|
637 Function can be used to check whether mouse event has |
|
638 occured on top of header area. |
|
639 */ |
|
640 bool NmViewerView::eventOnTopOfHeaderArea(QGraphicsSceneMouseEvent *event) |
|
641 { |
|
642 bool ret(false); |
|
643 if (event && mHeaderWidget){ |
|
644 QPointF lastReleasePoint = event->lastPos(); |
|
645 QPointF contentWidgetPos = mScrollAreaContents->pos(); |
|
646 int headerHeight = (int)mHeaderWidget->geometry().height(); |
|
647 if (lastReleasePoint.y()<headerHeight+contentWidgetPos.y()){ |
|
648 ret=true; |
|
649 } |
|
650 } |
|
651 return ret; |
|
652 } |
|
653 |
|
654 /*! |
|
655 get function for content widget web view. |
|
656 */ |
|
657 NmMailViewerWK* NmViewerView::webView() |
|
658 { |
|
659 return mWebView; |
|
660 } |
|
661 |
|
662 /*! |
|
663 Replace html special characters from plain text content. |
|
664 */ |
|
665 QString NmViewerView::escapeSpecialCharacters(const QString text) |
|
666 { |
|
667 const QString amp("&"); |
|
668 const QString ampReplace("&"); |
|
669 const QString lt("<"); |
|
670 const QString ltReplace("<"); |
|
671 const QString gt(">"); |
|
672 const QString gtReplace(">"); |
|
673 const QString quot("\""); |
|
674 const QString quotReplace("""); |
|
675 const QString apos("'"); |
|
676 const QString aposReplace("'"); |
|
677 QString ret = text; |
|
678 ret.replace(amp, ampReplace); |
|
679 ret.replace(lt, ltReplace); |
|
680 ret.replace(gt, gtReplace); |
|
681 ret.replace(quot, quotReplace); |
|
682 ret.replace(apos, aposReplace); |
|
683 return ret; |
|
684 } |
|
685 |
|
686 /*! |
|
687 Function to set message read status |
|
688 */ |
|
689 void NmViewerView::changeMessageReadStatus(bool read) |
|
690 { |
|
691 QList<const NmMessageEnvelope*> envelopeList; |
|
692 NmMessageEnvelope *envelope = &mMessage->envelope(); |
|
693 NmStoreEnvelopesOperation* op = NULL; |
|
694 if (envelope){ |
|
695 if ( read != envelope->isRead() ){ |
|
696 if (read){ |
|
697 envelope->setRead(true); |
|
698 envelopeList.append(envelope); |
|
699 op = mUiEngine.setEnvelopes( |
|
700 mStartParam->mailboxId(), |
|
701 mStartParam->folderId(), |
|
702 MarkAsRead, |
|
703 envelopeList); |
|
704 } |
|
705 else { |
|
706 envelope->setRead(false); |
|
707 envelopeList.append(envelope); |
|
708 op = mUiEngine.setEnvelopes( |
|
709 mStartParam->mailboxId(), |
|
710 mStartParam->folderId(), |
|
711 MarkAsUnread, |
|
712 envelopeList); |
|
713 } |
|
714 } |
|
715 if(op){ |
|
716 mUiEngine.storeOperation(op); |
|
717 } |
|
718 } |
|
719 } |
|
720 |
|
721 /*! |
|
722 Set mailbox name to title |
|
723 */ |
|
724 void NmViewerView::setMailboxName() |
|
725 { |
|
726 if (mStartParam){ |
|
727 NmMailboxMetaData *meta = mUiEngine.mailboxById(mStartParam->mailboxId()); |
|
728 if (meta){ |
|
729 setTitle(meta->name()); |
|
730 } |
|
731 } |
|
732 } |
|
733 |
|
734 /*! |
|
735 contentScrollPositionChanged. |
|
736 Function reacts to scroll position change events and sets |
|
737 header to correct position |
|
738 */ |
|
739 void NmViewerView::contentScrollPositionChanged(const QPointF &newPosition) |
|
740 { |
|
741 if (mWebView&&mHeaderWidget){ |
|
742 QRectF webViewRect = mWebView->geometry(); |
|
743 QTransform tr; |
|
744 qreal leftMovementThreshold(webViewRect.width()-mHeaderWidget->geometry().width()); |
|
745 if (newPosition.x()<0){ |
|
746 tr.translate(webViewRect.topLeft().x() ,0); |
|
747 } |
|
748 else if (newPosition.x()>=0 && newPosition.x()<leftMovementThreshold){ |
|
749 tr.translate(mHeaderStartScenePos.x()+newPosition.x() ,0); |
|
750 } |
|
751 else { |
|
752 tr.translate(webViewRect.topLeft().x()+leftMovementThreshold ,0); |
|
753 } |
|
754 mHeaderWidget->setTransform(tr); |
|
755 } |
|
756 mLatestScrollPos = newPosition; |
|
757 } |
|
758 |
|
759 /*! |
|
760 createToolBar. Function asks menu commands from extension |
|
761 to be added to toolbar owned by the HbView. |
|
762 */ |
|
763 void NmViewerView::createToolBar() |
|
764 { |
|
765 HbToolBar *tb = toolBar(); |
|
766 NmUiExtensionManager &extMngr = mApplication.extManager(); |
|
767 if (tb && &extMngr && mStartParam) { |
|
768 tb->clearActions(); |
|
769 NmActionRequest request(this, NmActionToolbar, NmActionContextViewViewer, |
|
770 NmActionContextDataNone, mStartParam->mailboxId(), mStartParam->folderId() ); |
|
771 QList<NmAction *> list; |
|
772 extMngr.getActions(request, list); |
|
773 for (int i = 0; i < list.count(); i++) { |
|
774 tb->addAction(list[i]); |
|
775 } |
|
776 } |
|
777 } |
|
778 |
|
779 /*! |
|
780 handleActionCommand. From NmActionObserver, extension manager calls this |
|
781 call to handle menu command in the UI. |
|
782 */ |
|
783 void NmViewerView::handleActionCommand(NmActionResponse &actionResponse) |
|
784 { |
|
785 bool showSendInProgressNote = false; |
|
786 |
|
787 // Handle options menu |
|
788 if (actionResponse.menuType() == NmActionOptionsMenu) { |
|
789 } |
|
790 else if (actionResponse.menuType() == NmActionToolbar) { |
|
791 switch (actionResponse.responseCommand()) { |
|
792 case NmActionResponseCommandReply: { |
|
793 if (mUiEngine.isSendingMessage()) { |
|
794 showSendInProgressNote = true; |
|
795 break; |
|
796 } |
|
797 NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMessageEditor, |
|
798 mStartParam->mailboxId(), mStartParam->folderId(), |
|
799 mStartParam->messageId(), NmUiEditorReply); |
|
800 mApplication.enterNmUiView(startParam); |
|
801 } |
|
802 break; |
|
803 case NmActionResponseCommandReplyAll: { |
|
804 if (mUiEngine.isSendingMessage()) { |
|
805 showSendInProgressNote = true; |
|
806 break; |
|
807 } |
|
808 NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMessageEditor, |
|
809 mStartParam->mailboxId(), mStartParam->folderId(), |
|
810 mStartParam->messageId(), NmUiEditorReplyAll); |
|
811 mApplication.enterNmUiView(startParam); |
|
812 } |
|
813 break; |
|
814 case NmActionResponseCommandForward: { |
|
815 if (mUiEngine.isSendingMessage()) { |
|
816 showSendInProgressNote = true; |
|
817 break; |
|
818 } |
|
819 NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMessageEditor, |
|
820 mStartParam->mailboxId(), mStartParam->folderId(), |
|
821 mStartParam->messageId(), NmUiEditorForward); |
|
822 mApplication.enterNmUiView(startParam); |
|
823 } |
|
824 break; |
|
825 case NmActionResponseCommandDeleteMail: { |
|
826 } |
|
827 break; |
|
828 default: |
|
829 break; |
|
830 } |
|
831 } |
|
832 |
|
833 if (showSendInProgressNote) { |
|
834 QString noteText = hbTrId("txt_mail_dialog_still_sending"); |
|
835 |
|
836 // get message subject from the message being sent |
|
837 const NmMessage *message = mUiEngine.messageBeingSent(); |
|
838 if (message) { |
|
839 noteText = noteText.arg(NmUtilities::truncate(message->envelope().subject(), 20)); |
|
840 } |
|
841 HbMessageBox::warning(noteText); |
|
842 } |
|
843 } |