123 htmlPart = originalMessage->htmlBodyPart(); |
123 htmlPart = originalMessage->htmlBodyPart(); |
124 plainPart = originalMessage->plainTextBodyPart(); |
124 plainPart = originalMessage->plainTextBodyPart(); |
125 } |
125 } |
126 |
126 |
127 if (htmlPart) { |
127 if (htmlPart) { |
128 bodyContent.append(htmlPart->textContent()); |
128 QString bodyText(htmlPart->textContent()); |
|
129 if (editorStartMode==NmUiEditorReply || editorStartMode==NmUiEditorReplyAll || |
|
130 editorStartMode==NmUiEditorForward) { |
|
131 convertBodyStylesToDivision(bodyText); |
|
132 } |
|
133 |
129 if(editorStartMode==NmUiEditorReply || editorStartMode==NmUiEditorReplyAll ) { |
134 if(editorStartMode==NmUiEditorReply || editorStartMode==NmUiEditorReplyAll ) { |
130 removeEmbeddedImages(bodyContent); |
135 removeEmbeddedImages(bodyText); |
131 } |
136 } |
|
137 |
|
138 bodyContent.append(bodyText); |
|
139 cursor.insertHtml(bodyContent); |
132 } |
140 } |
133 else if (plainPart) { |
141 else if (plainPart) { |
134 // Plain text part was present, set it to HbTextEdit as HTML |
142 // Plain text part was present, set it to HbTextEdit as HTML |
135 bodyContent.append(QString("<html><body><p>")); |
143 bodyContent.append(QString("<html><body><p>")); |
136 bodyContent.append(plainPart->textContent()); |
144 bodyContent.append(plainPart->textContent()); |
271 adjusted so that the cursor can be seen. |
279 adjusted so that the cursor can be seen. |
272 */ |
280 */ |
273 void NmEditorContent::ensureCursorVisibility() |
281 void NmEditorContent::ensureCursorVisibility() |
274 { |
282 { |
275 NM_FUNCTION; |
283 NM_FUNCTION; |
276 |
284 |
277 // check which of the editors has the focus and get the x/y coordinates for the cursor position |
285 QGraphicsItem *focused = NULL; |
278 QGraphicsWidget *focused = mScrollAreaContents->focusWidget(); |
286 QRectF localRect; // set to empty |
279 |
287 |
280 if (focused) { |
288 // find out which widget has the input focus and get the cursor position ractangle |
281 QRectF localRect(0, 0, 0, 0); |
289 if (mHeader->toEdit() && mHeader->toEdit()->hasInputFocus()) { |
282 bool notFound = false; |
290 focused = mHeader->toEdit(); |
283 |
291 localRect = mHeader->toEdit()->rectForCursorPosition(); |
284 if (focused == mHeader->toEdit()) { |
292 } |
285 localRect = mHeader->toEdit()->rectForCursorPosition(); |
293 else if (mHeader->ccEdit() && mHeader->ccEdit()->hasInputFocus()) { |
|
294 focused = mHeader->ccEdit(); |
|
295 localRect = mHeader->ccEdit()->rectForCursorPosition(); |
|
296 } |
|
297 else if (mHeader->bccEdit() && mHeader->bccEdit()->hasInputFocus()) { |
|
298 focused = mHeader->bccEdit(); |
|
299 localRect = mHeader->bccEdit()->rectForCursorPosition(); |
|
300 } |
|
301 else if (mHeader->subjectEdit() && mHeader->subjectEdit()->hasInputFocus()) { |
|
302 focused = mHeader->subjectEdit(); |
|
303 localRect = mHeader->subjectEdit()->rectForCursorPosition(); |
|
304 } |
|
305 else if (mEditorWidget->hasInputFocus()) { |
|
306 focused = mEditorWidget; |
|
307 localRect = mEditorWidget->rectForCursorPosition(); |
|
308 } |
|
309 |
|
310 // ensure that the cursor position is visible |
|
311 if (focused && !localRect.isEmpty()) { |
|
312 QPointF topLeftPos = focused->mapToItem(mScrollAreaContents, localRect.topLeft()); |
|
313 QPointF bottomRightPos = |
|
314 focused->mapToItem(mScrollAreaContents, localRect.bottomRight()); |
|
315 qreal marginRight = 0; |
|
316 if (mScrollArea->style()) { |
|
317 mScrollArea->style()->parameter("hb-param-margin-gene-right", marginRight); |
286 } |
318 } |
287 else if (focused == mHeader->ccEdit()) { |
319 bottomRightPos.rx() += marginRight; |
288 localRect = mHeader->ccEdit()->rectForCursorPosition(); |
320 |
289 } |
321 mScrollArea->ensureVisible(topLeftPos); |
290 else if (focused == mHeader->bccEdit()) { |
322 mScrollArea->ensureVisible(bottomRightPos); |
291 localRect = mHeader->bccEdit()->rectForCursorPosition(); |
|
292 } |
|
293 else if (focused == mHeader->subjectEdit()) { |
|
294 localRect = mHeader->subjectEdit()->rectForCursorPosition(); |
|
295 } |
|
296 else if (focused == mEditorWidget) { |
|
297 localRect = mEditorWidget->rectForCursorPosition(); |
|
298 } |
|
299 else { |
|
300 notFound = true; |
|
301 } |
|
302 |
|
303 if (!notFound) { |
|
304 QPointF topLeftPos = focused->mapToItem(mScrollAreaContents, localRect.topLeft()); |
|
305 QPointF bottomRightPos = |
|
306 focused->mapToItem(mScrollAreaContents, localRect.bottomRight()); |
|
307 qreal marginRight = 0; |
|
308 mScrollArea->style()->parameter("hb-param-margin-gene-right", marginRight); |
|
309 bottomRightPos.rx() += marginRight; |
|
310 mScrollArea->ensureVisible(topLeftPos); |
|
311 mScrollArea->ensureVisible(bottomRightPos); |
|
312 } |
|
313 } |
323 } |
314 } |
324 } |
315 /*! |
325 /*! |
316 Removes embedded images from the message body |
326 Removes embedded images from the message body |
317 */ |
327 */ |
357 } |
367 } |
358 // Call header to perform the translation which moves hader to new position. |
368 // Call header to perform the translation which moves hader to new position. |
359 mHeader->repositHeader(tr); |
369 mHeader->repositHeader(tr); |
360 } |
370 } |
361 |
371 |
|
372 /*! |
|
373 Removes body bgcolor tag from content and creates DIV from it. |
|
374 */ |
|
375 void NmEditorContent::convertBodyStylesToDivision(QString &bodyContent) |
|
376 { |
|
377 NM_FUNCTION; |
|
378 convertBGColorToStyle(bodyContent); |
|
379 |
|
380 // Make division from the head style body tag |
|
381 createDivisionFromHead(bodyContent); |
|
382 } |
|
383 |
|
384 /*! |
|
385 * Creates div.reply from the html header styles (if there is any) and applies this |
|
386 * style to the message by surrounding the message with the div.reply element. |
|
387 * |
|
388 * Example: |
|
389 * <html><head> |
|
390 * <style type="text/css"> |
|
391 * body { |
|
392 * color: #FF0000; |
|
393 * background-color: #ffffff } |
|
394 * h3{ color: blue } |
|
395 * </style></head> |
|
396 * <body> |
|
397 * <h3>This is bigger text.</h3> |
|
398 * This is the body text. |
|
399 * </body></html> |
|
400 * |
|
401 * ----> |
|
402 * |
|
403 * <html><head> |
|
404 * <style type="text/css"> |
|
405 * div.reply { |
|
406 * color: #FF0000; |
|
407 * background-color: #ffffff } |
|
408 * h3 { color: blue } |
|
409 * </style></head> |
|
410 * <body> |
|
411 * <div class="reply"> |
|
412 * <h3>This is bigger text.</h3> |
|
413 * This is the body text. |
|
414 * </div></body></html> |
|
415 * |
|
416 */ |
|
417 void NmEditorContent::createDivisionFromHead(QString &bodyContent) |
|
418 { |
|
419 NM_FUNCTION; |
|
420 |
|
421 // Regular expression string for searching <head> part that contains <style> |
|
422 QString bodyStyleDefined( |
|
423 "<head" |
|
424 "(\\s)*" // 0-* white spaces, browsers seem to accept this too. |
|
425 ">" |
|
426 "(.)*" // 0-* any characters |
|
427 "<style" |
|
428 "(.)*" // 0-* any characters |
|
429 "</head" |
|
430 "(\\s)*" // 0-* white spaces |
|
431 ">"); |
|
432 QRegExp bodyStyleDefinedRegExp(bodyStyleDefined, Qt::CaseInsensitive); |
|
433 bodyStyleDefinedRegExp.setMinimal(true); |
|
434 |
|
435 QString bodyStartReplacement("<body>\n<div"); |
|
436 |
|
437 if(bodyContent.contains(bodyStyleDefinedRegExp)) { |
|
438 QString headPartString = bodyStyleDefinedRegExp.cap(0); |
|
439 QString headBodyStyleString("body(\\s)*"); |
|
440 QRegExp bodyStyleReplacementRegExp(headBodyStyleString, Qt::CaseInsensitive); |
|
441 |
|
442 if(headPartString.contains(bodyStyleReplacementRegExp)) { |
|
443 headPartString.replace(bodyStyleReplacementRegExp, "div.reply "); |
|
444 bodyContent.replace(bodyStyleDefinedRegExp, headPartString); |
|
445 |
|
446 bodyStartReplacement = "<body>\n<div class=\"reply\""; |
|
447 } |
|
448 } |
|
449 |
|
450 convertBodyToDiv(bodyContent, bodyStartReplacement); |
|
451 } |
|
452 |
|
453 /*! |
|
454 * Renames <body...></body> to <div...></div> and creates new <body> element. |
|
455 * |
|
456 * Example: |
|
457 * <body style="background: #00ff00; color: red; border: solid"> |
|
458 * This is the body text. |
|
459 * </body> |
|
460 * |
|
461 * ----> |
|
462 * |
|
463 * <body> |
|
464 * <div style="background: #00ff00; color: red; border: solid"> |
|
465 * This is the body text. |
|
466 * </div> |
|
467 * </body> |
|
468 * |
|
469 * TODO: Tämä tapahtuu toistaiseksi riippumatta siitä onko bodyssa style-määrittelyä. |
|
470 * TODO: Entä jos dokumentissa on määritelty useampi <body>? |
|
471 */ |
|
472 void NmEditorContent::convertBodyToDiv(QString &bodyContent, const QString &replacementString) |
|
473 { |
|
474 NM_FUNCTION; |
|
475 |
|
476 QString bodyStart("<body"); |
|
477 QString bodyEnd("</body>"); |
|
478 QString bodyEndReplacement("</div></body>"); |
|
479 QRegExp bodyStartRegExp(bodyStart, Qt::CaseInsensitive); |
|
480 QRegExp bodyEndRegExp(bodyEnd, Qt::CaseInsensitive); |
|
481 |
|
482 bodyContent.replace(bodyStartRegExp, replacementString); |
|
483 bodyContent.replace(bodyEndRegExp, bodyEndReplacement); |
|
484 } |
|
485 |
|
486 /*! |
|
487 * Converts "body bgcolor=#color" attribute to "body style=background: #color". |
|
488 * |
|
489 * Example: |
|
490 * <body bgcolor="blue"></body> |
|
491 * |
|
492 * -----> |
|
493 * |
|
494 * <body style="background:blue"></div></body> |
|
495 */ |
|
496 void NmEditorContent::convertBGColorToStyle(QString &bodyContent) |
|
497 { |
|
498 NM_FUNCTION; |
|
499 |
|
500 QString bgColorInBodyFetchString("<body[^<]+(bgcolor(\\s|)=(\\s|)(\"|)(#|))*>"); |
|
501 QRegExp bgColorInBodyRegExp(bgColorInBodyFetchString, Qt::CaseInsensitive); |
|
502 |
|
503 if(bodyContent.contains(bgColorInBodyRegExp)) { |
|
504 // There can be only one meaningful bgcolor, the first one. |
|
505 QString bgColorString = bgColorInBodyRegExp.cap(0); |
|
506 |
|
507 // Extract the color code from the string |
|
508 QString colorCode(bgColorString); |
|
509 QRegExp removeBeginningRegExp( |
|
510 "<body" |
|
511 "[^<]+" // 1...* any character except '<' |
|
512 "bgcolor" |
|
513 "(\\s|)" // White space or nothing |
|
514 "=" |
|
515 "(\\s|)" // White space or nothing |
|
516 "(\"|)" // '"' or nothing |
|
517 "(#|)", // '#' or nothing |
|
518 Qt::CaseInsensitive); |
|
519 colorCode.remove(removeBeginningRegExp); |
|
520 |
|
521 QRegExp removeEndRegExp("" |
|
522 "((\"|\\s)" // '"' or white space |
|
523 "([^<]*)" // 0...* any characters except '<' |
|
524 ">)" // '>' |
|
525 "|>"); // ... or nothing before this, just '>' |
|
526 colorCode.remove(removeEndRegExp); |
|
527 |
|
528 QString plainBgColorFetchString("bgcolor(\\s|)*=(\\s|)*[^\\s]+(\\s|(?=>))"); |
|
529 QString bgColorReplacement("style=\"background: #"+colorCode+"\" "); |
|
530 QRegExp plainBgColorFetchRegExp(plainBgColorFetchString, Qt::CaseInsensitive); |
|
531 |
|
532 // Create temporary string for bgcolor |
|
533 bgColorString.replace(plainBgColorFetchRegExp, bgColorReplacement); |
|
534 |
|
535 // Copy the contents of the temporary string to the message |
|
536 bodyContent.replace(bgColorInBodyRegExp, bgColorString); |
|
537 } |
|
538 } |