genericcomposer.cpp
来自「Qtopia下的邮件处理程序」· C++ 代码 · 共 459 行
CPP
459 行
/******************************************************************************** Copyright (C) 2000-2006 TROLLTECH ASA. All rights reserved.**** This file is part of the Phone Edition of the Qtopia Toolkit.**** Licensees holding a valid license agreement from Trolltech or any of its** authorized distributors may use this file in accordance with** the License Agreement provided with the Licensed Software.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Trolltech's Commercial License Agreements.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.********** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#ifdef QTOPIA_PHONE#include <qtopia/qsoftmenubar.h>#endif#include <qtopia/qmimetype.h>#ifndef QTOPIA_DESKTOP#include <qtopia/qtopiaapplication.h>#endif#include <QFile>#include <QFileInfo>#include <QKeyEvent>#include <QAction>#include <QTextEdit>#include <QLabel>#include <QLayout>#include <QClipboard>#include <QMenu>#include <QSettings>#include <QTextCursor>#include <QContact>#include "genericcomposer.h"#include "smsclient.h"#ifdef QTOPIA_PHONE#include <qtopiaphone/qgsmcodec.h>#include "templatetext.h"#endif#define SMS_CHAR_LIMIT 459//Qtmail sends either GSM or UCS2 encoded SMS messages //If another encoding is ultimately used to send the message, //these functions will return inaccurate results#ifdef QTOPIA_PHONEvoid GenericComposer::smsLengthInfo(uint& estimatedBytes, bool& isUnicode){ //calculate the number of consumed bytes //considering the gsm charset unsigned short c; unsigned short d; uint count = 0; QString unicodestr = text(); for(int i = 0; i < unicodestr.length(); ++i) { c = unicodestr[i].unicode(); if(c >= 256) { estimatedBytes = unicodestr.length() * 2; isUnicode = true; return; } else { d = QGsmCodec::twoByteFromUnicode(c); if(d >= 256) count += 2; else if(d == 0x10) //0x10 is unrecognised char { estimatedBytes = unicodestr.length() * 2; //non gsm char, so go unicode isUnicode = true; return; } else count += 1; } } isUnicode = false; estimatedBytes = count;}//estimates the number of messages that will be sentint GenericComposer::smsCountInfo(){ bool isUnicode = false; uint numBytes = 0; int numMessages = 0; int len = text().length(); smsLengthInfo(numBytes,isUnicode); if(isUnicode) //all 2 byte UCS2 so ok to use text length { if (len <= 70 ) { numMessages = 1; } else { // 67 = 70 - fragment_header_size (3). numMessages = ( len + 66 ) / 67; } } else { //use byte length instead of text length //as some GSM chars consume 2 bytes if ( numBytes <= 160 ) { numMessages = 1; } else { // 153 = 160 - fragment_header_size (7). numMessages = ( numBytes + 152 ) / 153; } } return numMessages;}#endifclass ComposerTextEdit : public QTextEdit{public: ComposerTextEdit( QWidget *parent, const char *name = 0 ); void limitedInsert( const QString &str);#ifndef QT_NO_CLIPBOARD void limitedPaste();#endifprotected: void keyPressEvent( QKeyEvent *e ); void mousePressEvent( QMouseEvent *e ); void inputMethodEvent( QInputMethodEvent *e );};ComposerTextEdit::ComposerTextEdit( QWidget *parent, const char *name ) : QTextEdit( parent ){ setObjectName( name ); setFrameStyle(NoFrame); setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); setLineWrapMode( QTextEdit::WidgetWidth );}void ComposerTextEdit::keyPressEvent( QKeyEvent *e ){ int charCount = toPlainText().length(); QChar c = e->text()[0]; if( charCount >= SMS_CHAR_LIMIT && (c.isLetterOrNumber() || c.isPunct() || c.isSpace()) ) //e->key() != Key_Back && e->key() != Key_Delete ) return;#ifndef QT_NO_CLIPBOARD if( e->modifiers() & Qt::ControlModifier ) { if( e->key() == Qt::Key_V ) { limitedPaste(); return; } else if( e->key() == Qt::Key_Y ) return; //redo could be redo paste, and that could exceed limit }#endif#ifdef QTOPIA_PHONE if( Qtopia::mousePreferred() && e->key() == Qt::Key_Back ) e->ignore(); else#endif QTextEdit::keyPressEvent( e );}void ComposerTextEdit::limitedInsert( const QString &str){ int curCharCount = toPlainText().length(); if(curCharCount >= SMS_CHAR_LIMIT) return; QString strText = str; int strCharCount = str.length(); while((strCharCount + curCharCount) > SMS_CHAR_LIMIT) { strText = strText.left( strText.length() -1 );; strCharCount = strText.length(); } if( !strText.isEmpty() ) { textCursor().insertText( strText ); ensureCursorVisible(); emit textChanged(); } }#ifndef QT_NO_CLIPBOARDvoid ComposerTextEdit::limitedPaste(){ limitedInsert( QApplication::clipboard()->text() );}#endifvoid ComposerTextEdit::mousePressEvent( QMouseEvent *e ){ if( e->button() == Qt::RightButton ) return; QTextEdit::mousePressEvent( e );}void ComposerTextEdit::inputMethodEvent( QInputMethodEvent *e ){ if ( !e->commitString().isEmpty() ) { // Clear the commit string if it is makes the message longer // than the limit int charCount = toPlainText().length(); if(charCount + e->commitString().length() > SMS_CHAR_LIMIT) { e->setCommitString( QString() ); } } QTextEdit::inputMethodEvent( e );}GenericComposer::GenericComposer( QWidget *parent, const char *name ) : QWidget( parent ), m_vCard( false ), m_vCardData(){ setObjectName( name ); m_showLimitAction = new QAction( tr("Show Sms Limit"), this ); m_showLimitAction->setCheckable( true ); QSettings cfg("Trolltech","qtmail"); cfg.beginGroup( "GenericComposer" ); m_showLimitAction->setChecked( cfg.value( "showSmsLimitIndicator", true ).toBool() ); connect( m_showLimitAction, SIGNAL(triggered(bool)), this, SLOT(updateSmsLimitIndicator()) ); m_templateTextAction = new QAction( tr("Insert Template"), this ); connect( m_templateTextAction, SIGNAL(triggered()), this, SLOT(templateText()) ); QVBoxLayout *l = new QVBoxLayout( this ); m_smsLimitIndicator = new QLabel( this ); l->addWidget( m_smsLimitIndicator ); m_smsLimitIndicator->setAlignment( Qt::AlignRight ); m_textEdit = new ComposerTextEdit( this ); setFocusProxy( m_textEdit ); l->addWidget( m_textEdit );#ifdef QTOPIA4_TODO m_textEdit->setMaxLength( SMS_BYTE_LIMIT );#endif connect( m_textEdit, SIGNAL(textChanged()), this, SIGNAL(contentChanged()) ); connect( m_textEdit, SIGNAL(textChanged()), this, SLOT(updateSmsLimitIndicator()) );#ifdef QTOPIA_PHONE QMenu *menu = QSoftMenuBar::menuFor( m_textEdit, QSoftMenuBar::AnyFocus ); menu->addSeparator(); menu->insertAction(menu->actions().count() ? menu->actions()[0] : 0, m_showLimitAction); menu->insertAction(m_showLimitAction, m_templateTextAction); menu->addSeparator(); QSoftMenuBar::addMenuTo( this, menu );#endif updateSmsLimitIndicator();}GenericComposer::~GenericComposer(){ QSettings cfg("Trolltech","qtmail"); cfg.beginGroup( "GenericComposer" ); cfg.setValue( "showSmsLimitIndicator", m_showLimitAction->isChecked() );}void GenericComposer::updateSmsLimitIndicator(){ if ( m_showLimitAction->isChecked() && !m_vCard ) { if( m_smsLimitIndicator->isHidden() ) m_smsLimitIndicator->show(); } else { if( !m_smsLimitIndicator->isHidden() ) m_smsLimitIndicator->hide(); return; } int numMessages = 1; int charCount = text().length();#ifdef QTOPIA_PHONE numMessages = smsCountInfo();#else numMessages = 1;#endif m_smsLimitIndicator->setText( QString(tr("%1/%2 ","e.g. 5/7")) .arg( SMS_CHAR_LIMIT - charCount ) .arg( numMessages ) );}void GenericComposer::templateText(){#ifdef QTOPIA_PHONE TemplateTextDialog *templateTextDialog = new TemplateTextDialog();#ifdef QTOPIA_DESKTOP templateTextDialog->exec();#else QtopiaApplication::execDialog( templateTextDialog );#endif ComposerTextEdit *composer = qobject_cast<ComposerTextEdit *>( m_textEdit ); if (templateTextDialog->result() && composer) composer->limitedInsert( templateTextDialog->text() ); delete templateTextDialog;#endif }void GenericComposer::setText( const QString &t ){ if ( t.startsWith( SmsClient::vCardPrefix() ) ) { QString copy = t; QList<QContact> contacts = QContact::readVCard( copy.remove( SmsClient::vCardPrefix() ).toLatin1() ); if ( contacts.count() == 0 ) { // Invalid VCard data, so just show raw data m_textEdit->setPlainText( t ); } else if ( contacts.count() == 1 ) { QString name = tr( "Message contains vCard for %1" ); if ( !contacts[0].nickname().isEmpty() ) { m_textEdit->setPlainText( name.arg( contacts[0].nickname() ) ); } else if ( !contacts[0].firstName().isEmpty() && !contacts[0].lastName().isEmpty() ) { m_textEdit->setPlainText( name.arg( contacts[0].firstName() + " " + contacts[0].lastName() ) ); } else if ( !contacts[0].firstName().isEmpty() ) { m_textEdit->setPlainText( name.arg( contacts[0].firstName() ) ); } else { m_textEdit->setPlainText( tr( "Message contains vCard for a contact" ) ); } m_vCard = true; m_vCardData = t; } else if ( contacts.count() > 1 ) { m_textEdit->setPlainText( tr( "Message contains vCard for multiple contacts" ) ); m_vCard = true; m_vCardData = t; } } else { m_textEdit->setPlainText( t ); } // Update GUI state m_templateTextAction->setVisible( !m_vCard ); m_textEdit->setReadOnly( m_vCard ); m_textEdit->setEditFocus( !m_vCard ); if ( m_vCard ) { setFocusProxy( 0 ); } else { setFocusProxy( m_textEdit ); } updateSmsLimitIndicator();}QString GenericComposer::text() const{ if ( m_vCard ) return m_vCardData; else return m_textEdit->toPlainText();}GenericComposerInterface::GenericComposerInterface( QObject *parent, const char *name ) : TextComposerInterface( parent, name ){ QWidget *par = 0; if( parent && parent->isWidgetType() ) par = (QWidget *)parent; m_composer = new GenericComposer( par, name ); connect( m_composer, SIGNAL(contentChanged()), this, SIGNAL(contentChanged()) );}GenericComposerInterface::~GenericComposerInterface(){ delete m_composer;}/*QCString GenericComposerInterface::id(){ QCString t = QString::number( type() ).toLatin1(); return t + "-Default"; // default sms/email composer}ComposerInterface::ComposerType GenericComposerInterface::type(){ return ComposerInterface::SMS | ComposerInterface::Email;}QString GenericComposerInterface::displayName(){ return tr("SMS/Email");}*/bool GenericComposerInterface::hasContent() const{ return !m_composer->text().trimmed().isEmpty();}void GenericComposerInterface::setMailMessage( Email &mail ){ setText( mail.plainTextBody() );}void GenericComposerInterface::getContent( MailMessage &mail ) const{ if( !hasContent() ) return; mail.setPlainTextBody( m_composer->text() ); mail.setType( MailMessage::SMS | MailMessage::Email );}void GenericComposerInterface::clear(){ m_composer->setText( QString() );}void GenericComposerInterface::setText( const QString &txt ){ m_composer->setText( txt );}QWidget *GenericComposerInterface::widget() const{ return m_composer;}void GenericComposerInterface::attach( const QContent & ){ qWarning("Unimplemented function called %s %d, %s", __FILE__, __LINE__, __FUNCTION__ );}void GenericComposerInterface::attach( const QString & ){ qWarning("Unimplemented function called %s %d, %s", __FILE__, __LINE__, __FUNCTION__ );}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?