diff -r 4697dfb2d7ad -r 238255e8b033 messagingapp/msgui/unifiededitor/src/msgunifiededitorlineedit.cpp --- /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 +#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(text).remove(mLabel); + emit addressTextChanged(changedText); +} + +// eof