--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingapp/msgui/unifiededitor/src/msgunifiededitorlineedit.cpp Fri Apr 16 14:56:15 2010 +0300
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:
+ *
+ */
+
+#include <QGraphicsSceneMouseEvent>
+#include "msgunifiededitorlineedit.h"
+
+const QRegExp expr("[,;\n]$");
+const QRegExp sepAtEnd("; $");
+const QRegExp sepAtMiddle("; ");
+
+const QString replacementStr("; ");
+const QString labelSeperator(": ");
+
+const int fadedAlpha(125);
+const int solidAlpha(255);
+
+const int SNAP_DELAY = 350;
+
+MsgUnifiedEditorLineEdit::MsgUnifiedEditorLineEdit(const QString& label,QGraphicsItem *parent):
+HbLineEdit(parent),
+mSelectionStart(-1),
+mSelectionEnd(-1)
+{
+ QTextCursor cursor(this->textCursor());
+ QTextCharFormat colorFormat(cursor.charFormat());
+
+ QColor fgColor = colorFormat.foreground().color();
+ fgColor.setAlpha(fadedAlpha);
+ colorFormat.setForeground(fgColor);
+ cursor.insertText(label , colorFormat);
+
+ fgColor.setAlpha(solidAlpha);
+ colorFormat.setForeground(fgColor);
+
+ cursor.insertText(" ",colorFormat);
+
+ mLabelExpr.setPattern(QString("^"+label+" $"));
+ mLabel = label+" ";
+
+ connect(this,SIGNAL(selectionChanged(QTextCursor,QTextCursor)),
+ this,SLOT(selectionChanged(QTextCursor,QTextCursor)));
+ connect(this, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
+}
+
+MsgUnifiedEditorLineEdit::~MsgUnifiedEditorLineEdit()
+{
+}
+
+void MsgUnifiedEditorLineEdit::inputMethodEvent(QInputMethodEvent *event)
+{
+ if (!event->commitString().isEmpty() || event->replacementLength())
+ {
+ if (event->commitString().contains(expr))
+ {
+ if(this->text().isEmpty() || this->text().contains(sepAtEnd) || this->text().contains(mLabelExpr))
+ {
+ event->accept();
+ return;
+ }
+
+ this->setCursorPosition(this->text().length());
+
+ QString str = event->commitString();
+ str.replace(expr, replacementStr);
+
+ event->setCommitString(str, event->replacementStart(), event->replacementLength());
+ }
+ else if(this->hasSelectedText())
+ {// all user inputs get appended at the end
+ this->setCursorPosition(this->text().length());
+ }
+
+ HbAbstractEdit::inputMethodEvent(event);
+ event->accept();
+ }
+}
+
+void MsgUnifiedEditorLineEdit::keyPressEvent(QKeyEvent *event)
+{
+ QString str = event->text();
+
+ if(event->key()== Qt::Key_Enter || event->key()== Qt::Key_Return)
+ {
+ if(this->text().isEmpty() || this->text().contains(sepAtEnd) || this->text().contains(mLabelExpr))
+ {
+ event->accept();
+ return;
+ }
+ this->setCursorPosition(this->text().length());
+ str = replacementStr;
+ QKeyEvent eve(event->type(), Qt::Key_Any, event->modifiers(), str);
+ HbAbstractEdit::keyPressEvent(&eve);
+ event->accept();
+ return;
+ }
+
+ if(event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete )
+ {
+ int pos = this->cursorPosition();
+ bool pbkContact = true;
+
+ if(!this->hasSelectedText())
+ {
+ this->setCursorPosition(pos-2);
+ pbkContact = this->textCursor().charFormat().fontUnderline();
+ this->setCursorPosition(pos);
+ }
+
+ QString text = this->text();
+ text = text.left(pos);
+
+ if(text.contains(mLabelExpr))
+ {
+ event->accept();
+ return;
+ }
+
+ if(pbkContact)
+ {
+ //if already selected delete it.
+ if(this->hasSelectedText())
+ {
+ HbLineEdit::keyPressEvent(event);
+ event->accept();
+
+ //delete seperator (i.e."; ").
+ QKeyEvent eve(event->type(), Qt::Key_Delete, Qt::NoModifier);
+ HbLineEdit::keyPressEvent(&eve);
+ HbLineEdit::keyPressEvent(&eve);
+
+ }
+ else //make it selected
+ {
+ this->setCursorPosition(pos-3);
+ setHighlight(pos-3);
+ }
+ }
+ else
+ {
+ QString str = text.right(2);
+ if(str == replacementStr)
+ {
+ //delete seperator (i.e."; ").
+ QKeyEvent eve(event->type(), Qt::Key_Backspace, Qt::NoModifier);
+ HbLineEdit::keyPressEvent(&eve);
+ HbLineEdit::keyPressEvent(&eve);
+ }
+ else
+ {
+ HbLineEdit::keyPressEvent(event);
+ }
+ event->accept();
+ }
+
+ event->accept();
+ return;
+
+ }
+
+ if (event->key() == Qt::Key_Left )
+ {
+ bool selectedText = this->hasSelectedText();
+
+ //look ahead left.
+ int pos = this->cursorPosition();
+
+ QString text = this->text();
+ text = text.left(pos);
+
+ //no text other than label;
+ if(text.contains(mLabelExpr))
+ {
+ event->accept();
+ return;
+ }
+
+ //look for next seperator while going left.
+ int newPos = text.lastIndexOf(sepAtMiddle);
+
+ if(newPos < 0 && selectedText)
+ {
+ event->accept();
+ return;
+ }
+
+ bool pbkContact = true;
+
+ if(!selectedText)
+ {
+ this->setCursorPosition(pos-2);
+ pbkContact = this->textCursor().charFormat().fontUnderline();
+ this->setCursorPosition(pos);
+ }
+ else
+ {
+ this->setCursorPosition(newPos);
+ pbkContact = this->textCursor().charFormat().fontUnderline();
+ this->setCursorPosition(pos);
+ }
+
+
+ if(pbkContact && newPos >0)
+ {
+
+ setHighlight(newPos-1);
+ }
+ else
+ {
+ //move left, char by char. if seperator met jump over it.
+ if( (newPos > 0 && selectedText) || (pos-2 == newPos))
+ {
+ this->setCursorPosition(newPos+1);
+ }
+
+ HbLineEdit::keyPressEvent(event);
+
+ }
+ event->accept();
+ return;
+ }
+
+ if (event->key() == Qt::Key_Right)
+ {
+ bool selectedText = this->hasSelectedText();
+
+ //look ahead.
+ int pos = this->cursorPosition();
+ this->setCursorPosition(pos+3);
+ bool pbkContact = this->textCursor().charFormat().fontUnderline();
+ this->setCursorPosition(pos);
+
+ //look for next seperator.
+ QString text = this->text();
+ int newPos = text.indexOf(sepAtMiddle,pos+2);
+
+ if(pbkContact && newPos >0)
+ {
+ this->setCursorPosition(newPos-1);
+ setHighlight(newPos-1);
+ }
+ else
+ {
+ int seperatorPos = text.indexOf(sepAtMiddle,pos);
+
+ if(selectedText || seperatorPos == pos)
+ {
+ this->setCursorPosition(pos+1);
+ this->deselect();
+ }
+ HbAbstractEdit::keyPressEvent(event);
+ }
+ event->accept();
+ return;
+ }
+
+ if(!str.isEmpty())
+ {
+ if (str.contains(expr))
+ {
+ if(this->text().isEmpty() || this->text().contains(sepAtEnd) || this->text().contains(mLabelExpr))
+ {
+ event->accept();
+ return;
+ }
+
+ // auto-complete the last incomplete word
+ int contentLength = this->text().length();
+ int pos = this->cursorPosition();
+ QString incompleteWord(this->text().right(contentLength-(pos-1)));
+ if(!incompleteWord.contains(sepAtMiddle))
+ {
+ this->setCursorPosition(this->text().length());
+ }
+
+ str.replace(expr, replacementStr);
+ QKeyEvent eve(event->type(), event->key(), event->modifiers(), str);
+ HbAbstractEdit::keyPressEvent(&eve);
+ }
+ else
+ {
+ HbAbstractEdit::keyPressEvent(event);
+ event->accept();
+ return;
+ }
+ }
+}
+
+void MsgUnifiedEditorLineEdit::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
+{
+ HbAbstractEdit::mouseReleaseEvent(event);
+
+ int currentPos = this->cursorPosition();
+
+ QString txt = this->text();
+
+ QString tempTxt = txt.left(currentPos+2);
+ int seperatorPos = tempTxt.lastIndexOf(sepAtMiddle,currentPos);
+
+ txt = txt.right(txt.length() - currentPos);
+ int labelPos = txt.indexOf(labelSeperator);
+
+ if(labelPos >= 0 )//pressed on label.
+ {
+ this->setCursorPosition(currentPos + labelPos + 2);
+ }
+ else if(seperatorPos == currentPos-1 || seperatorPos == currentPos)//pressed just on seperator.
+ {
+ this->setCursorPosition(seperatorPos+2);
+ }
+ else
+ {
+ this->setCursorPosition(currentPos+1);
+ bool pbkContact = this->textCursor().charFormat().fontUnderline();
+ if(pbkContact)
+ {
+ setHighlight(currentPos);
+ }
+ }
+
+ this->update();
+ event->accept();
+}
+
+void MsgUnifiedEditorLineEdit::setText(const QString& text)
+{
+ QInputMethodEvent e;
+ //make sure previous text is complete.
+ e.setCommitString(";");
+ this->inputMethodEvent(&e);
+ this->setCursorPosition(this->text().length());
+
+ QTextCursor cursor(this->textCursor());
+ QTextCharFormat colorFormat(cursor.charFormat());
+ QColor fgColor = colorFormat.foreground().color();
+ fgColor.setAlpha(fadedAlpha);
+ colorFormat.setUnderlineColor(fgColor);
+
+ colorFormat.setFontUnderline(true);
+ cursor.insertText(text , colorFormat);
+ colorFormat.setFontUnderline(false);
+
+ cursor.insertText(replacementStr,colorFormat);
+
+ this->setCursorVisibility(Hb::TextCursorHidden);
+}
+
+QStringList MsgUnifiedEditorLineEdit::addresses()
+{
+ QString text = this->text();
+ text = text.remove(mLabel);
+ QStringList list = text.split(replacementStr,QString::SkipEmptyParts);
+ //list.removeDuplicates();
+ return list;
+}
+
+void MsgUnifiedEditorLineEdit::focusInEvent(QFocusEvent* event)
+{
+ HbAbstractEdit::focusInEvent(event);
+ this->setCursorVisibility(Hb::TextCursorVisible);
+}
+
+void MsgUnifiedEditorLineEdit::setHighlight(int currentPos)
+{
+ QString txt = this->text();
+
+ int endPos = qMax(txt.indexOf(sepAtMiddle,currentPos),
+ txt.indexOf(labelSeperator,currentPos));
+
+ int startPos = qMax(txt.lastIndexOf(sepAtMiddle,currentPos),
+ txt.lastIndexOf(labelSeperator,currentPos));
+
+ disconnect(this,SIGNAL(selectionChanged(QTextCursor,QTextCursor)),
+ this,SLOT(selectionChanged(QTextCursor,QTextCursor)));
+
+ //highlight if pbk contact.
+ if(startPos > 0 && endPos > 0 && startPos != endPos)
+ {
+ this->setSelection(startPos + 2, endPos - startPos - 2);
+ this->update();
+ }
+ else
+ {
+ this->deselect();
+ }
+
+ this->update();
+
+ connect(this,SIGNAL(selectionChanged(QTextCursor,QTextCursor)),
+ this,SLOT(selectionChanged(QTextCursor,QTextCursor)));
+}
+
+void MsgUnifiedEditorLineEdit::cut()
+{
+ HbLineEdit::cut();
+ //after cut delete seperator (i.e."; ").
+ QKeyEvent eve(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier);
+ HbLineEdit::keyPressEvent(&eve);
+ HbLineEdit::keyPressEvent(&eve);
+}
+
+void MsgUnifiedEditorLineEdit::selectAll()
+{
+ //don't allow user to select every thing.
+ //do nothing.
+}
+
+void MsgUnifiedEditorLineEdit::selectionChanged(const QTextCursor &oldCursor, const QTextCursor& newCursor)
+{
+
+ if(mSelectionSnapTimer.isActive())
+ {
+ mSelectionSnapTimer.stop();
+ }
+
+ if(newCursor.selectionStart() < mLabel.length())
+ {
+ this->setTextCursor(oldCursor);
+ return;
+ }
+
+ mSelectionStart = newCursor.selectionStart();
+ mSelectionEnd = newCursor.selectionEnd();
+
+ if(mSelectionStart == mSelectionEnd )
+ {
+ return;
+ }
+
+ mSelectionSnapTimer.start(SNAP_DELAY,this);
+
+}
+
+void MsgUnifiedEditorLineEdit::timerEvent(QTimerEvent *event)
+{
+ //passing event to base class.
+ HbLineEdit::timerEvent(event);
+
+ if (event->timerId() == mSelectionSnapTimer.timerId())
+ {
+ mSelectionSnapTimer.stop();
+
+ disconnect(this,SIGNAL(selectionChanged(QTextCursor,QTextCursor)),
+ this,SLOT(selectionChanged(QTextCursor,QTextCursor)));
+
+ QString txt = this->text();
+
+ int startPos = qMax(txt.lastIndexOf(sepAtMiddle,mSelectionStart),
+ txt.lastIndexOf(labelSeperator,mSelectionStart));
+
+ int endPos = qMax(txt.indexOf(sepAtMiddle,mSelectionEnd),
+ txt.indexOf(labelSeperator,mSelectionEnd));
+
+ if(endPos < 0 )
+ {
+ endPos = mSelectionEnd;
+ }
+
+ this->setSelection(startPos + 2, endPos - startPos - 2);
+
+ connect(this,SIGNAL(selectionChanged(QTextCursor,QTextCursor)),
+ this,SLOT(selectionChanged(QTextCursor,QTextCursor)));
+
+ event->accept();
+ }
+}
+
+void MsgUnifiedEditorLineEdit::onTextChanged(const QString& text)
+{
+ const QString changedText = const_cast<QString&>(text).remove(mLabel);
+ emit addressTextChanged(changedText);
+}
+
+// eof