author | hgs |
Tue, 19 Oct 2010 12:30:59 +0300 | |
changeset 79 | 2508e95245f2 |
parent 74 | 6c59112cfd31 |
permissions | -rw-r--r-- |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
1 |
/* |
51 | 2 |
* Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies). |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
3 |
* All rights reserved. |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
4 |
* This component and the accompanying materials are made available |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
5 |
* under the terms of "Eclipse Public License v1.0" |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
6 |
* which accompanies this distribution, and is available |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html". |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
8 |
* |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
9 |
* Initial Contributors: |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
10 |
* Nokia Corporation - initial contribution. |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
11 |
* |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
12 |
* Contributors: |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
13 |
* |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
14 |
* Description: Message editor contents widget |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
15 |
* |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
16 |
*/ |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
17 |
|
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
18 |
#include "nmuiheaders.h" |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
19 |
|
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
20 |
// Layout |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
21 |
static const char *NMUI_EDITOR_BODY = "BodyTextEdit"; |
47 | 22 |
static const char *NMUI_EDITOR_SCROLL_AREA = "scrollArea"; |
23 |
static const char *NMUI_EDITOR_SCROLL_AREA_CONTENTS = "scrollAreaContents"; |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
24 |
|
47 | 25 |
// Regular expression for selecting img tags with "cid" in the mail. |
26 |
static const char *NMUI_EDITOR_REMOVE_EMBD_IMAGES_REG = |
|
48 | 27 |
"(<img[^<]+(src\\s*=\\s*)(.{0,1}cid)([^<]+)(>\\s*|/>\\s*|></img>\\s*))"; |
47 | 28 |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
29 |
/*! |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
30 |
Constructor |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
31 |
*/ |
47 | 32 |
NmEditorContent::NmEditorContent(QObject *parent, |
20
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
33 |
HbDocumentLoader *documentLoader, |
47 | 34 |
QNetworkAccessManager &manager, |
35 |
NmApplication &application) : |
|
36 |
QObject(parent), |
|
48 | 37 |
mHeader(NULL), |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
38 |
mEditorWidget(NULL), |
47 | 39 |
mScrollArea(NULL), |
40 |
mScrollAreaContents(NULL), |
|
51 | 41 |
mApplication(application), |
42 |
mNeedForWidthAdjustment(false) |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
43 |
{ |
43 | 44 |
NM_FUNCTION; |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
45 |
|
47 | 46 |
// Construct container for the header widgets |
51 | 47 |
mHeader = new NmEditorHeader(this, application, documentLoader); |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
48 |
|
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
49 |
// Get pointer to body text area handling widget |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
50 |
mEditorWidget = qobject_cast<NmEditorTextEdit *>(documentLoader->findWidget(NMUI_EDITOR_BODY)); |
51 | 51 |
|
52 |
// Enable the emoticons. |
|
53 |
mEditorWidget->setSmileysEnabled(true); |
|
54 |
||
20
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
55 |
// Set body editor to use NmEditorTextDocument |
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
56 |
NmEditorTextDocument *textDocument = new NmEditorTextDocument(manager); |
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
57 |
mEditorWidget->setDocument(textDocument); |
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
58 |
textDocument->setParent(mEditorWidget); // ownership changes |
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
59 |
|
47 | 60 |
mScrollArea = qobject_cast<NmBaseViewScrollArea *> |
49 | 61 |
(documentLoader->findWidget(NMUI_EDITOR_SCROLL_AREA)); |
51 | 62 |
|
48 | 63 |
mScrollArea->setScrollDirections(Qt::Vertical | Qt::Horizontal); |
51 | 64 |
mScrollArea->setClampingStyle(HbScrollArea::BounceBackClamping); |
65 |
||
23
2dc6caa42ec3
Revision: 201017
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
20
diff
changeset
|
66 |
// Enable style picker menu item. |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
67 |
mEditorWidget->setFormatDialog(new HbFormatDialog()); |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
68 |
|
47 | 69 |
mScrollAreaContents = |
70 |
qobject_cast<HbWidget *>(documentLoader->findWidget(NMUI_EDITOR_SCROLL_AREA_CONTENTS)); |
|
71 |
||
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
72 |
// Create signal slot connections |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
73 |
createConnections(); |
51 | 74 |
|
75 |
// The following line is necessary in terms of being able to add emoticons |
|
76 |
// (smileys) to an empty document (mail content). Otherwise the private |
|
77 |
// pointer of the QTextDocument which the smiley engine has is NULL and |
|
78 |
// inserting a smiley will lead to an error. |
|
79 |
mEditorWidget->setPlainText(""); |
|
74 | 80 |
|
81 |
QCoreApplication::instance()->installEventFilter(this); // see eventFilter() |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
82 |
} |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
83 |
|
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
84 |
/*! |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
85 |
Destructor |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
86 |
*/ |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
87 |
NmEditorContent::~NmEditorContent() |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
88 |
{ |
43 | 89 |
NM_FUNCTION; |
74 | 90 |
|
91 |
QCoreApplication::instance()->removeEventFilter(this); // see eventFilter() |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
92 |
} |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
93 |
|
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
94 |
/*! |
62 | 95 |
Sets the body content. If reply envelopw is present, reply header is generated and set to |
96 |
editor. Reply envelope ownership is not transferred here. |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
97 |
*/ |
62 | 98 |
void NmEditorContent::setBodyContent(NmUiEditorStartMode editorStartMode, |
99 |
const NmMessage *originalMessage, |
|
100 |
const QString *signature) |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
101 |
{ |
43 | 102 |
NM_FUNCTION; |
44 | 103 |
|
104 |
QString bodyContent; |
|
62 | 105 |
|
106 |
// first insert the signature |
|
107 |
if (signature) { |
|
108 |
bodyContent.append("<html><body><br><br>"); |
|
109 |
bodyContent.append(*signature); |
|
110 |
bodyContent.append("<br></body></html>"); |
|
111 |
} |
|
112 |
||
51 | 113 |
QTextCursor cursor(mEditorWidget->document()); |
44 | 114 |
|
47 | 115 |
// Create the "reply" header (also for forward message) |
62 | 116 |
// sets the font color of the reply header and the original body text to black |
74 | 117 |
if ((editorStartMode == NmUiEditorReply || editorStartMode == NmUiEditorReplyAll || |
118 |
editorStartMode == NmUiEditorForward) && originalMessage) { |
|
51 | 119 |
bodyContent.append(QString("<style type=\"text/css\">* { color: black; }</style>")); |
62 | 120 |
bodyContent.append(NmUtilities::createReplyHeader(originalMessage->envelope())); |
44 | 121 |
} |
122 |
||
43 | 123 |
// Check which part is present. Html or plain text part. We use the original message parts. |
62 | 124 |
const NmMessagePart *htmlPart = NULL; |
125 |
const NmMessagePart *plainPart = NULL; |
|
126 |
if (originalMessage) { |
|
127 |
htmlPart = originalMessage->htmlBodyPart(); |
|
128 |
plainPart = originalMessage->plainTextBodyPart(); |
|
129 |
} |
|
44 | 130 |
|
47 | 131 |
if (htmlPart) { |
68 | 132 |
QString bodyText(htmlPart->textContent()); |
74 | 133 |
if (editorStartMode == NmUiEditorReply || editorStartMode == NmUiEditorReplyAll || |
134 |
editorStartMode == NmUiEditorForward) { |
|
68 | 135 |
convertBodyStylesToDivision(bodyText); |
136 |
} |
|
137 |
||
74 | 138 |
if(editorStartMode == NmUiEditorReply || editorStartMode == NmUiEditorReplyAll ) { |
68 | 139 |
removeEmbeddedImages(bodyText); |
47 | 140 |
} |
68 | 141 |
bodyContent.append(bodyText); |
20
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
142 |
} |
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
143 |
else if (plainPart) { |
62 | 144 |
// Plain text part was present, set it to HbTextEdit as HTML |
145 |
bodyContent.append(QString("<html><body><p>")); |
|
44 | 146 |
bodyContent.append(plainPart->textContent()); |
62 | 147 |
bodyContent.append(QString("</p></body></html>")); |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
148 |
} |
62 | 149 |
cursor.insertHtml(bodyContent); |
150 |
||
51 | 151 |
// Update of the body width is done when next contentChanged signal comes from the body. |
152 |
mNeedForWidthAdjustment = true; |
|
153 |
cursor.clearSelection(); |
|
154 |
cursor.setPosition(0); |
|
62 | 155 |
cursor.insertHtml(QString("<html><body></body></html>")); |
74 | 156 |
mEditorWidget->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor); |
157 |
QMetaObject::invokeMethod(this, "ensureCursorVisibility", Qt::QueuedConnection); |
|
20
ecc8def7944a
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
18
diff
changeset
|
158 |
} |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
159 |
|
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
160 |
/*! |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
161 |
This method creates all needed signal-slot connections |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
162 |
*/ |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
163 |
void NmEditorContent::createConnections() |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
164 |
{ |
43 | 165 |
NM_FUNCTION; |
166 |
||
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
167 |
// Signal for setting HbTextEdit widgets html content |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
168 |
connect(this, SIGNAL(setHtml(QString)), |
44 | 169 |
mEditorWidget, SLOT(setHtml(QString)), Qt::QueuedConnection); |
47 | 170 |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
171 |
// Signal for setting HbTextEdit widgets plain text content |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
172 |
connect(this, SIGNAL(setPlainText(QString)), |
44 | 173 |
mEditorWidget, SLOT(setPlainText(QString)), Qt::QueuedConnection); |
47 | 174 |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
175 |
// Inform text edit widget that header height has been changed |
48 | 176 |
connect(mHeader, SIGNAL(headerHeightChanged(int)), this, SLOT(setEditorContentHeight()), |
47 | 177 |
Qt::QueuedConnection); |
178 |
||
179 |
// we are interested in the document's height changes |
|
180 |
connect(mEditorWidget->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)), this, |
|
181 |
SLOT(setEditorContentHeight()), Qt::QueuedConnection); |
|
182 |
||
48 | 183 |
// listen to the parent's (NmEditorView) size changes which happen eg. when VKB is opened/closed |
184 |
connect(parent(), SIGNAL(sizeChanged()), this, SLOT(ensureCursorVisibility()), |
|
185 |
Qt::QueuedConnection); |
|
51 | 186 |
|
187 |
// Listen scroll posion change signals for header reposition. |
|
188 |
connect(mScrollArea, SIGNAL(scrollPositionChanged(QPointF)), |
|
62 | 189 |
this, SLOT(repositHeader(QPointF))); |
190 |
||
51 | 191 |
// Listen content change signal for body widget width adjustment. |
192 |
connect(mEditorWidget->document(), SIGNAL(contentsChanged()), this, |
|
193 |
SLOT(setEditorContentWidth()), Qt::QueuedConnection); |
|
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
194 |
} |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
195 |
|
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
196 |
/*! |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
197 |
Return pointer to the email body text edit widget |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
198 |
*/ |
47 | 199 |
NmEditorTextEdit *NmEditorContent::editor() const |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
200 |
{ |
43 | 201 |
NM_FUNCTION; |
202 |
||
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
203 |
return mEditorWidget; |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
204 |
} |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
205 |
|
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
206 |
/*! |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
207 |
Return pointer to the header widget |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
208 |
*/ |
47 | 209 |
NmEditorHeader *NmEditorContent::header() const |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
210 |
{ |
43 | 211 |
NM_FUNCTION; |
212 |
||
48 | 213 |
return mHeader; |
18
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
214 |
} |
578830873419
Revision: 201011
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
diff
changeset
|
215 |
|
47 | 216 |
/*! |
217 |
This slot is called when header widget height has been changed. Function performs |
|
218 |
the repositioning of the body field and resizing of the editor and content area. |
|
219 |
*/ |
|
220 |
void NmEditorContent::setEditorContentHeight() |
|
221 |
{ |
|
222 |
NM_FUNCTION; |
|
223 |
||
66 | 224 |
HbStyle* style = mScrollAreaContents->style(); |
225 |
||
226 |
if (style) { |
|
227 |
// the height of the margin between the title bar and the header |
|
228 |
qreal topMargin = 0; |
|
229 |
style->parameter("hb-param-margin-gene-top", topMargin); |
|
230 |
||
231 |
// header height |
|
232 |
qreal headerHeight = mHeader->headerHeight(); |
|
233 |
||
234 |
// body area editor's document height with margins added |
|
235 |
qreal documentHeightAndMargins = mEditorWidget->document()->size().height() + |
|
236 |
(mEditorWidget->document()->documentMargin() * 2); |
|
47 | 237 |
|
66 | 238 |
// chrome height |
239 |
qreal chromeHeight = 0; |
|
240 |
style->parameter("hb-param-widget-chrome-height", chromeHeight); |
|
241 |
||
242 |
// screen height |
|
243 |
qreal screenHeight = mApplication.screenSize().height(); |
|
47 | 244 |
|
66 | 245 |
// set min size for the body area so that at least the screen area is always filled |
246 |
qreal bodyAreaMinSize = screenHeight - chromeHeight - topMargin - headerHeight; |
|
247 |
||
248 |
qreal bodyAreaSize = fmax(bodyAreaMinSize, documentHeightAndMargins); |
|
249 |
||
250 |
mScrollAreaContents->setPreferredHeight(topMargin + headerHeight + bodyAreaSize); |
|
251 |
} |
|
47 | 252 |
} |
253 |
||
254 |
/*! |
|
51 | 255 |
This slot is used to set width for the body field. |
256 |
For some reason HbTextEdit does not set it's width, so we need to se it here. |
|
257 |
This slot can be removed if HbTextEdit is fixed. |
|
258 |
*/ |
|
259 |
void NmEditorContent::setEditorContentWidth() |
|
260 |
{ |
|
261 |
NM_FUNCTION; |
|
262 |
||
263 |
if (mNeedForWidthAdjustment) { |
|
264 |
mNeedForWidthAdjustment = false; |
|
265 |
mScrollAreaContents->setPreferredWidth(mEditorWidget->document()->idealWidth()); |
|
266 |
} |
|
267 |
} |
|
268 |
||
269 |
/*! |
|
48 | 270 |
This slot is called when the cursor visibility has to be ensured ie. the scroll position is |
74 | 271 |
adjusted so that the cursor can be seen. For defining exatcly what area is ensured the |
272 |
same algorithm that HbAbstractEditPrivate::ensurePositionVisible() uses is used here. |
|
48 | 273 |
*/ |
274 |
void NmEditorContent::ensureCursorVisibility() |
|
47 | 275 |
{ |
276 |
NM_FUNCTION; |
|
68 | 277 |
|
278 |
QGraphicsItem *focused = NULL; |
|
279 |
QRectF localRect; // set to empty |
|
48 | 280 |
|
68 | 281 |
// find out which widget has the input focus and get the cursor position ractangle |
282 |
if (mHeader->toEdit() && mHeader->toEdit()->hasInputFocus()) { |
|
283 |
focused = mHeader->toEdit(); |
|
284 |
localRect = mHeader->toEdit()->rectForCursorPosition(); |
|
285 |
} |
|
286 |
else if (mHeader->ccEdit() && mHeader->ccEdit()->hasInputFocus()) { |
|
287 |
focused = mHeader->ccEdit(); |
|
288 |
localRect = mHeader->ccEdit()->rectForCursorPosition(); |
|
289 |
} |
|
290 |
else if (mHeader->bccEdit() && mHeader->bccEdit()->hasInputFocus()) { |
|
291 |
focused = mHeader->bccEdit(); |
|
292 |
localRect = mHeader->bccEdit()->rectForCursorPosition(); |
|
293 |
} |
|
294 |
else if (mHeader->subjectEdit() && mHeader->subjectEdit()->hasInputFocus()) { |
|
295 |
focused = mHeader->subjectEdit(); |
|
296 |
localRect = mHeader->subjectEdit()->rectForCursorPosition(); |
|
297 |
} |
|
298 |
else if (mEditorWidget->hasInputFocus()) { |
|
299 |
focused = mEditorWidget; |
|
300 |
localRect = mEditorWidget->rectForCursorPosition(); |
|
301 |
} |
|
302 |
||
303 |
// ensure that the cursor position is visible |
|
304 |
if (focused && !localRect.isEmpty()) { |
|
74 | 305 |
QRectF rect = focused->mapRectToItem(mScrollAreaContents, localRect); |
306 |
mScrollArea->ensureVisible(rect.center(), rect.width(), rect.height() / 2 ); |
|
47 | 307 |
} |
308 |
} |
|
309 |
/*! |
|
310 |
Removes embedded images from the message body |
|
311 |
*/ |
|
312 |
void NmEditorContent::removeEmbeddedImages(QString &bodyContent) |
|
313 |
{ |
|
314 |
NM_FUNCTION; |
|
315 |
||
316 |
QRegExp regExp(NMUI_EDITOR_REMOVE_EMBD_IMAGES_REG, Qt::CaseInsensitive); |
|
317 |
bodyContent.remove(regExp); |
|
48 | 318 |
} |
62 | 319 |
|
320 |
/*! |
|
321 |
This slot is called when scroll position has been changed. |
|
322 |
Function create translation object which is used to set new position for |
|
323 |
header so that header stays visible when body is scrolled horizontally. |
|
324 |
*/ |
|
325 |
void NmEditorContent::repositHeader(const QPointF &scrollPosition) |
|
326 |
{ |
|
327 |
NM_FUNCTION; |
|
328 |
||
329 |
// Get the layout's left margin |
|
330 |
qreal margin = 0; |
|
66 | 331 |
HbInstance::instance()->style()->parameter("hb-param-margin-gene-left", margin); |
332 |
||
62 | 333 |
// Calculate header width. (Screen width minus left and right margins. |
334 |
qreal headerWidth = mApplication.screenSize().width() - margin - margin; |
|
335 |
||
336 |
// Create translation object for header position adjustment. |
|
337 |
QRectF editorBodyRect = mEditorWidget->geometry(); |
|
338 |
QTransform tr; |
|
74 | 339 |
|
340 |
qreal bodyWidth = editorBodyRect.width(); |
|
341 |
if ( bodyWidth < mApplication.screenSize().width() ) { |
|
342 |
bodyWidth = mApplication.screenSize().width(); |
|
343 |
} |
|
344 |
||
345 |
qreal leftMovementThreshold( bodyWidth - headerWidth); |
|
346 |
||
62 | 347 |
if (scrollPosition.x() < 0) { |
348 |
// Left side positioning. Allow left side baunch effect. |
|
349 |
tr.translate(editorBodyRect.topLeft().x() - margin ,0); |
|
350 |
} |
|
351 |
else if (scrollPosition.x() >= 0 && scrollPosition.x() < leftMovementThreshold) { |
|
352 |
// Middle area positioning |
|
353 |
tr.translate(scrollPosition.x() ,0); |
|
354 |
} |
|
355 |
else { |
|
356 |
// Right side positioning. Allow right side baunch effect. |
|
357 |
tr.translate(editorBodyRect.topLeft().x() + leftMovementThreshold - margin ,0); |
|
358 |
} |
|
359 |
// Call header to perform the translation which moves hader to new position. |
|
360 |
mHeader->repositHeader(tr); |
|
361 |
} |
|
362 |
||
68 | 363 |
/*! |
364 |
Removes body bgcolor tag from content and creates DIV from it. |
|
365 |
*/ |
|
366 |
void NmEditorContent::convertBodyStylesToDivision(QString &bodyContent) |
|
367 |
{ |
|
368 |
NM_FUNCTION; |
|
369 |
convertBGColorToStyle(bodyContent); |
|
370 |
||
371 |
// Make division from the head style body tag |
|
372 |
createDivisionFromHead(bodyContent); |
|
373 |
} |
|
374 |
||
375 |
/*! |
|
376 |
* Creates div.reply from the html header styles (if there is any) and applies this |
|
377 |
* style to the message by surrounding the message with the div.reply element. |
|
378 |
* |
|
379 |
* Example: |
|
380 |
* <html><head> |
|
381 |
* <style type="text/css"> |
|
382 |
* body { |
|
383 |
* color: #FF0000; |
|
384 |
* background-color: #ffffff } |
|
385 |
* h3{ color: blue } |
|
386 |
* </style></head> |
|
387 |
* <body> |
|
388 |
* <h3>This is bigger text.</h3> |
|
389 |
* This is the body text. |
|
390 |
* </body></html> |
|
391 |
* |
|
392 |
* ----> |
|
393 |
* |
|
394 |
* <html><head> |
|
395 |
* <style type="text/css"> |
|
396 |
* div.reply { |
|
397 |
* color: #FF0000; |
|
398 |
* background-color: #ffffff } |
|
399 |
* h3 { color: blue } |
|
400 |
* </style></head> |
|
401 |
* <body> |
|
402 |
* <div class="reply"> |
|
403 |
* <h3>This is bigger text.</h3> |
|
404 |
* This is the body text. |
|
405 |
* </div></body></html> |
|
406 |
* |
|
407 |
*/ |
|
408 |
void NmEditorContent::createDivisionFromHead(QString &bodyContent) |
|
409 |
{ |
|
410 |
NM_FUNCTION; |
|
411 |
||
412 |
// Regular expression string for searching <head> part that contains <style> |
|
413 |
QString bodyStyleDefined( |
|
414 |
"<head" |
|
415 |
"(\\s)*" // 0-* white spaces, browsers seem to accept this too. |
|
416 |
">" |
|
417 |
"(.)*" // 0-* any characters |
|
418 |
"<style" |
|
419 |
"(.)*" // 0-* any characters |
|
420 |
"</head" |
|
421 |
"(\\s)*" // 0-* white spaces |
|
422 |
">"); |
|
423 |
QRegExp bodyStyleDefinedRegExp(bodyStyleDefined, Qt::CaseInsensitive); |
|
424 |
bodyStyleDefinedRegExp.setMinimal(true); |
|
425 |
||
426 |
QString bodyStartReplacement("<body>\n<div"); |
|
427 |
||
74 | 428 |
if (bodyContent.contains(bodyStyleDefinedRegExp)) { |
68 | 429 |
QString headPartString = bodyStyleDefinedRegExp.cap(0); |
430 |
QString headBodyStyleString("body(\\s)*"); |
|
431 |
QRegExp bodyStyleReplacementRegExp(headBodyStyleString, Qt::CaseInsensitive); |
|
432 |
||
74 | 433 |
if (headPartString.contains(bodyStyleReplacementRegExp)) { |
68 | 434 |
headPartString.replace(bodyStyleReplacementRegExp, "div.reply "); |
435 |
bodyContent.replace(bodyStyleDefinedRegExp, headPartString); |
|
436 |
||
437 |
bodyStartReplacement = "<body>\n<div class=\"reply\""; |
|
438 |
} |
|
439 |
} |
|
440 |
||
441 |
convertBodyToDiv(bodyContent, bodyStartReplacement); |
|
442 |
} |
|
443 |
||
444 |
/*! |
|
445 |
* Renames <body...></body> to <div...></div> and creates new <body> element. |
|
446 |
* |
|
447 |
* Example: |
|
448 |
* <body style="background: #00ff00; color: red; border: solid"> |
|
449 |
* This is the body text. |
|
450 |
* </body> |
|
451 |
* |
|
452 |
* ----> |
|
453 |
* |
|
454 |
* <body> |
|
455 |
* <div style="background: #00ff00; color: red; border: solid"> |
|
456 |
* This is the body text. |
|
457 |
* </div> |
|
458 |
* </body> |
|
459 |
*/ |
|
460 |
void NmEditorContent::convertBodyToDiv(QString &bodyContent, const QString &replacementString) |
|
461 |
{ |
|
462 |
NM_FUNCTION; |
|
463 |
||
464 |
QString bodyStart("<body"); |
|
465 |
QString bodyEnd("</body>"); |
|
466 |
QString bodyEndReplacement("</div></body>"); |
|
467 |
QRegExp bodyStartRegExp(bodyStart, Qt::CaseInsensitive); |
|
468 |
QRegExp bodyEndRegExp(bodyEnd, Qt::CaseInsensitive); |
|
469 |
||
470 |
bodyContent.replace(bodyStartRegExp, replacementString); |
|
471 |
bodyContent.replace(bodyEndRegExp, bodyEndReplacement); |
|
472 |
} |
|
473 |
||
474 |
/*! |
|
475 |
* Converts "body bgcolor=#color" attribute to "body style=background: #color". |
|
476 |
* |
|
477 |
* Example: |
|
478 |
* <body bgcolor="blue"></body> |
|
479 |
* |
|
480 |
* -----> |
|
481 |
* |
|
482 |
* <body style="background:blue"></div></body> |
|
483 |
*/ |
|
484 |
void NmEditorContent::convertBGColorToStyle(QString &bodyContent) |
|
485 |
{ |
|
486 |
NM_FUNCTION; |
|
487 |
||
74 | 488 |
QString bgColorInBodyFetchString("<body" |
489 |
"[^<]+" // 1...* any character except '<' |
|
490 |
"(bgcolor" |
|
491 |
"(\\s|)" // White space or nothing |
|
492 |
"=" |
|
493 |
"(\\s|)" // White space or nothing |
|
494 |
"(\"|)" // '"' or nothing |
|
495 |
"(#|))" // '#' or nothing |
|
496 |
"*>"); // 0...* Any character + > |
|
68 | 497 |
QRegExp bgColorInBodyRegExp(bgColorInBodyFetchString, Qt::CaseInsensitive); |
498 |
||
74 | 499 |
if (bodyContent.contains(bgColorInBodyRegExp)) { |
68 | 500 |
// There can be only one meaningful bgcolor, the first one. |
501 |
QString bgColorString = bgColorInBodyRegExp.cap(0); |
|
502 |
||
503 |
// Extract the color code from the string |
|
504 |
QString colorCode(bgColorString); |
|
505 |
QRegExp removeBeginningRegExp( |
|
506 |
"<body" |
|
507 |
"[^<]+" // 1...* any character except '<' |
|
508 |
"bgcolor" |
|
509 |
"(\\s|)" // White space or nothing |
|
510 |
"=" |
|
511 |
"(\\s|)" // White space or nothing |
|
512 |
"(\"|)" // '"' or nothing |
|
513 |
"(#|)", // '#' or nothing |
|
514 |
Qt::CaseInsensitive); |
|
74 | 515 |
|
68 | 516 |
colorCode.remove(removeBeginningRegExp); |
517 |
||
518 |
QRegExp removeEndRegExp("" |
|
519 |
"((\"|\\s)" // '"' or white space |
|
520 |
"([^<]*)" // 0...* any characters except '<' |
|
521 |
">)" // '>' |
|
522 |
"|>"); // ... or nothing before this, just '>' |
|
74 | 523 |
|
68 | 524 |
colorCode.remove(removeEndRegExp); |
525 |
||
74 | 526 |
QString plainBgColorFetchString("bgcolor" |
527 |
"(\\s|)*" // 0...* White space or nothing |
|
528 |
"=" |
|
529 |
"(\\s|)*" // 0...* White space or nothing |
|
530 |
"[^\\s]+" // 1...* any character except white space |
|
531 |
"(\\s|(?=>))"); // White space or follower by '>' |
|
532 |
||
68 | 533 |
QString bgColorReplacement("style=\"background: #"+colorCode+"\" "); |
534 |
QRegExp plainBgColorFetchRegExp(plainBgColorFetchString, Qt::CaseInsensitive); |
|
535 |
||
536 |
// Create temporary string for bgcolor |
|
537 |
bgColorString.replace(plainBgColorFetchRegExp, bgColorReplacement); |
|
538 |
||
539 |
// Copy the contents of the temporary string to the message |
|
540 |
bodyContent.replace(bgColorInBodyRegExp, bgColorString); |
|
541 |
} |
|
542 |
} |
|
74 | 543 |
|
544 |
/*! |
|
545 |
* Listen to the input method events (eg. cursor position changes, preedit text changes etc.) and |
|
546 |
* invoke ensureCursorVisibility. Qt FW does not automatically ensure the visiblity of a text in a |
|
547 |
* edit widget in our custom scroll area. Filtering events is the only way to get events of the |
|
548 |
* preedit text changes. |
|
549 |
*/ |
|
550 |
bool NmEditorContent::eventFilter(QObject *obj, QEvent *event) |
|
551 |
{ |
|
552 |
// let the FW handle the event first |
|
553 |
bool ret = QObject::eventFilter(obj, event); |
|
554 |
||
555 |
if (event && event->type() == QEvent::InputMethod) { |
|
556 |
QMetaObject::invokeMethod(this, "ensureCursorVisibility", Qt::QueuedConnection); |
|
557 |
} |
|
558 |
||
559 |
return ret; |
|
560 |
} |
|
561 |