--- a/emailuis/nmailui/src/nmeditorcontent.cpp Wed Jun 23 18:00:21 2010 +0300
+++ b/emailuis/nmailui/src/nmeditorcontent.cpp Tue Jul 06 14:04:34 2010 +0300
@@ -19,26 +19,32 @@
// Layout
static const char *NMUI_EDITOR_BODY = "BodyTextEdit";
+static const char *NMUI_EDITOR_SCROLL_AREA = "scrollArea";
+static const char *NMUI_EDITOR_SCROLL_AREA_CONTENTS = "scrollAreaContents";
+// Regular expression for selecting img tags with "cid" in the mail.
+static const char *NMUI_EDITOR_REMOVE_EMBD_IMAGES_REG =
+ "(<img[^<]+(src\\s*=\\s*)(.{0,1}cid)([^<]+)(>\\s*|/>\\s*|></img>\\s*))";
+
/*!
Constructor
*/
-NmEditorContent::NmEditorContent(QGraphicsItem *parent,
- NmEditorView *parentView,
+NmEditorContent::NmEditorContent(QObject *parent,
HbDocumentLoader *documentLoader,
- QNetworkAccessManager &manager) :
- HbWidget(parent),
- mHeaderWidget(NULL),
- mParentView(parentView),
- mEditorLayout(NULL),
- mMessageBodyType(PlainText),
+ QNetworkAccessManager &manager,
+ NmApplication &application) :
+ QObject(parent),
+ mHeader(NULL),
+ mMessageBodyType(NmPlainText),
mEditorWidget(NULL),
- mBackgroundScrollArea((NmBaseViewScrollArea*)parent)
+ mScrollArea(NULL),
+ mScrollAreaContents(NULL),
+ mApplication(application)
{
NM_FUNCTION;
- // Add header area handling widget into layout
- mHeaderWidget = new NmEditorHeader(documentLoader);
+ // Construct container for the header widgets
+ mHeader = new NmEditorHeader(this, documentLoader);
// Get pointer to body text area handling widget
mEditorWidget = qobject_cast<NmEditorTextEdit *>(documentLoader->findWidget(NMUI_EDITOR_BODY));
@@ -48,14 +54,16 @@
mEditorWidget->setDocument(textDocument);
textDocument->setParent(mEditorWidget); // ownership changes
- mEditorWidget->init(mBackgroundScrollArea);
- // we are interested in the editor widget's height changes
- connect(mEditorWidget, SIGNAL(editorContentHeightChanged()), this,
- SLOT(setEditorContentHeight()));
-
+ mScrollArea = qobject_cast<NmBaseViewScrollArea *>
+ (documentLoader->findWidget(NMUI_EDITOR_SCROLL_AREA));
+ mScrollArea->setScrollDirections(Qt::Vertical | Qt::Horizontal);
+
// Enable style picker menu item.
mEditorWidget->setFormatDialog(new HbFormatDialog());
+ mScrollAreaContents =
+ qobject_cast<HbWidget *>(documentLoader->findWidget(NMUI_EDITOR_SCROLL_AREA_CONTENTS));
+
// Create signal slot connections
createConnections();
}
@@ -66,8 +74,6 @@
NmEditorContent::~NmEditorContent()
{
NM_FUNCTION;
-
- delete mHeaderWidget;
}
/*!
@@ -75,88 +81,83 @@
present, reply header is generated and set to editor. Reply
envelope ownership is not transferred here.
*/
-void NmEditorContent::setMessageData(const NmMessage &originalMessage,
- bool createReplyHeader)
+void NmEditorContent::setMessageData(const NmMessage &originalMessage,
+ NmUiEditorStartMode &editorStartMode)
{
NM_FUNCTION;
QString bodyContent;
- // We create the "reply" header (also for forward message), but not to draft message.
- if (mEditorWidget && createReplyHeader) {
- QTextCursor cursor = mEditorWidget->textCursor();
- cursor.setPosition(0);
- cursor.insertHtml(NmUtilities::createReplyHeader(originalMessage.envelope()));
+ // Create the "reply" header (also for forward message)
+ if (editorStartMode==NmUiEditorReply || editorStartMode==NmUiEditorReplyAll ||
+ editorStartMode==NmUiEditorForward) {
+ bodyContent.append(NmUtilities::createReplyHeader(originalMessage.envelope()));
}
- // Take reply header as html format.
- bodyContent.append(mEditorWidget->toHtml());
// Check which part is present. Html or plain text part. We use the original message parts.
const NmMessagePart *htmlPart = originalMessage.htmlBodyPart();
const NmMessagePart *plainPart = originalMessage.plainTextBodyPart();
- if (htmlPart && mEditorWidget) {
+ if (htmlPart) {
bodyContent.append(htmlPart->textContent());
+ if(editorStartMode==NmUiEditorReply || editorStartMode==NmUiEditorReplyAll ) {
+ removeEmbeddedImages(bodyContent);
+ }
emit setHtml(bodyContent);
- mMessageBodyType = HTMLText;
+ mMessageBodyType = NmHTMLText;
}
else if (plainPart) {
// Plain text part was present, set it to HbTextEdit
bodyContent.append(plainPart->textContent());
emit setPlainText(bodyContent);
- mMessageBodyType = PlainText;
+ mMessageBodyType = NmPlainText;
}
}
/*!
- This method set new height for the editor content when header or body field
- height has been changed.
- */
-void NmEditorContent::setEditorContentHeight()
-{
- NM_FUNCTION;
-
- const QSizeF reso = HbDeviceProfile::current().logicalSize();
- qreal containerHeight = mEditorWidget->contentHeight() + mHeaderWidget->headerHeight();
- if (containerHeight < reso.height()) {
- //Currently content height is too long because Chrome hiding is not supported.
- //Fix this when Chrome works.
- containerHeight = reso.height();
- qreal bodyContentHeight =
- reso.height() - mHeaderWidget->headerHeight();
- mEditorWidget->setPreferredHeight(bodyContentHeight);
- mEditorWidget->setMaximumHeight(bodyContentHeight);
- }
- mParentView->scrollAreaContents()->setMinimumHeight(containerHeight);
- mParentView->scrollAreaContents()->setMaximumHeight(containerHeight);
- mBackgroundScrollArea->setMaximumHeight(containerHeight);
-}
-
-/*!
This method creates all needed signal-slot connections
*/
void NmEditorContent::createConnections()
{
NM_FUNCTION;
- // Body edit widget is also interested about bg scroll position change
- connect(mBackgroundScrollArea, SIGNAL(scrollPositionChanged(QPointF)),
- mEditorWidget, SLOT(updateScrollPosition(QPointF)));
// Signal for setting HbTextEdit widgets html content
connect(this, SIGNAL(setHtml(QString)),
mEditorWidget, SLOT(setHtml(QString)), Qt::QueuedConnection);
+
// Signal for setting HbTextEdit widgets plain text content
connect(this, SIGNAL(setPlainText(QString)),
mEditorWidget, SLOT(setPlainText(QString)), Qt::QueuedConnection);
+
// Inform text edit widget that header height has been changed
- connect(mHeaderWidget, SIGNAL(headerHeightChanged(int)),
- mEditorWidget, SLOT(setHeaderHeight(int)));
+ connect(mHeader, SIGNAL(headerHeightChanged(int)), this, SLOT(setEditorContentHeight()),
+ Qt::QueuedConnection);
+
+ // we are interested in the document's height changes
+ connect(mEditorWidget->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)), this,
+ SLOT(setEditorContentHeight()), Qt::QueuedConnection);
+
+ // We need to update the scroll position according the editor's cursor position
+ connect(mHeader->toEdit(), SIGNAL(cursorPositionChanged(int, int)), this,
+ SLOT(ensureCursorVisibility()), Qt::QueuedConnection);
+ connect(mHeader->ccEdit(), SIGNAL(cursorPositionChanged(int, int)), this,
+ SLOT(ensureCursorVisibility()), Qt::QueuedConnection);
+ connect(mHeader->bccEdit(), SIGNAL(cursorPositionChanged(int, int)), this,
+ SLOT(ensureCursorVisibility()), Qt::QueuedConnection);
+ connect(mHeader->subjectEdit(), SIGNAL(cursorPositionChanged(int, int)), this,
+ SLOT(ensureCursorVisibility()), Qt::QueuedConnection);
+ connect(mEditorWidget, SIGNAL(cursorPositionChanged(int, int)), this,
+ SLOT(ensureCursorVisibility()), Qt::QueuedConnection);
+
+ // listen to the parent's (NmEditorView) size changes which happen eg. when VKB is opened/closed
+ connect(parent(), SIGNAL(sizeChanged()), this, SLOT(ensureCursorVisibility()),
+ Qt::QueuedConnection);
}
/*!
Return pointer to the email body text edit widget
*/
-NmEditorTextEdit* NmEditorContent::editor() const
+NmEditorTextEdit *NmEditorContent::editor() const
{
NM_FUNCTION;
@@ -166,10 +167,100 @@
/*!
Return pointer to the header widget
*/
-NmEditorHeader* NmEditorContent::header() const
+NmEditorHeader *NmEditorContent::header() const
+{
+ NM_FUNCTION;
+
+ return mHeader;
+}
+
+/*!
+ This slot is called when header widget height has been changed. Function performs
+ the repositioning of the body field and resizing of the editor and content area.
+ */
+void NmEditorContent::setEditorContentHeight()
{
NM_FUNCTION;
- return mHeaderWidget;
+ // the height of the margin between the title bar and the header
+ qreal topMargin = 0;
+ HbStyle().parameter("hb-param-margin-gene-top", topMargin);
+
+ // header height
+ qreal headerHeight = mHeader->headerHeight();
+
+ // body area editor's document height with margins added
+ qreal documentHeightAndMargins = mEditorWidget->document()->size().height() +
+ (mEditorWidget->document()->documentMargin() * 2);
+
+ // chrome height
+ qreal chromeHeight = 0;
+ HbStyle().parameter("hb-param-widget-chrome-height", chromeHeight);
+
+ // screen height
+ qreal screenHeight = mApplication.screenSize().height();
+
+ // set min size for the body area so that at least the screen area is always filled
+ qreal bodyAreaMinSize = screenHeight - chromeHeight - topMargin - headerHeight;
+
+ qreal bodyAreaSize = fmax(bodyAreaMinSize, documentHeightAndMargins);
+
+ mScrollAreaContents->setPreferredHeight(topMargin + headerHeight + bodyAreaSize);
}
+/*!
+ This slot is called when the cursor visibility has to be ensured ie. the scroll position is
+ adjusted so that the cursor can be seen.
+*/
+void NmEditorContent::ensureCursorVisibility()
+{
+ NM_FUNCTION;
+
+ // check which of the editors has the focus and get the x/y coordinates for the cursor position
+ QGraphicsWidget *focused = mScrollAreaContents->focusWidget();
+
+ if (focused) {
+ QRectF localRect(0, 0, 0, 0);
+ bool notFound = false;
+
+ if (focused == mHeader->toEdit()) {
+ localRect = mHeader->toEdit()->rectForCursorPosition();
+ }
+ else if (focused == mHeader->ccEdit()) {
+ localRect = mHeader->ccEdit()->rectForCursorPosition();
+ }
+ else if (focused == mHeader->bccEdit()) {
+ localRect = mHeader->bccEdit()->rectForCursorPosition();
+ }
+ else if (focused == mHeader->subjectEdit()) {
+ localRect = mHeader->subjectEdit()->rectForCursorPosition();
+ }
+ else if (focused == mEditorWidget) {
+ localRect = mEditorWidget->rectForCursorPosition();
+ }
+ else {
+ notFound = true;
+ }
+
+ if (!notFound) {
+ QPointF topLeftPos = focused->mapToItem(mScrollAreaContents, localRect.topLeft());
+ QPointF bottomRightPos =
+ focused->mapToItem(mScrollAreaContents, localRect.bottomRight());
+ qreal marginRight = 0;
+ HbStyle().parameter("hb-param-margin-gene-right", marginRight);
+ bottomRightPos.rx() += marginRight;
+ mScrollArea->ensureVisible(topLeftPos);
+ mScrollArea->ensureVisible(bottomRightPos);
+ }
+ }
+}
+/*!
+ Removes embedded images from the message body
+ */
+void NmEditorContent::removeEmbeddedImages(QString &bodyContent)
+{
+ NM_FUNCTION;
+
+ QRegExp regExp(NMUI_EDITOR_REMOVE_EMBD_IMAGES_REG, Qt::CaseInsensitive);
+ bodyContent.remove(regExp);
+}