kde-playground/kdepim/knode/kncomposerview.cpp
2015-04-14 21:49:29 +00:00

502 lines
13 KiB
C++

/*
KNode, the KDE newsreader
Copyright (c) 1999-2007 the KNode authors.
See file AUTHORS for details
Copyright (c) 2010 Olivier Trichet <nive@nivalis.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
*/
#include "kncomposerview.h"
#include "kncomposereditor.h"
#include "knglobals.h"
#include "settings.h"
#include <KLocale>
#include <KPIMIdentities/IdentityCombo>
#include <KPIMIdentities/Identity>
#include <KPIMIdentities/IdentityManager>
#include <KPIMUtils/Email>
namespace KNode {
namespace Composer {
View::View( KNComposer *composer )
: QSplitter( Qt::Vertical, composer ),
mAttachmentSetup( false )
{
setupUi( this );
setChildrenCollapsible( false );
mAttachmentWidget->hide();
//From
mFromEdit->setView( this );
mFromEdit->enableCompletion( false );
mEdtList.append( mFromEdit );
showFrom( false );
//To
mToEdit->setView( this );
mToEdit->enableCompletion( true );
mEdtList.append( mToEdit );
connect( mToButton, SIGNAL(clicked(bool)),
parent(), SLOT(slotToBtnClicked()) );
//Newsgroups
mGroupsEdit->setView( this );
mGroupsEdit->enableCompletion( false );
mEdtList.append( mGroupsEdit );
connect( mGroupsEdit, SIGNAL(editingFinished()),
this, SLOT(slotGroupsChanged()) );
connect( mGroupsButton, SIGNAL(clicked()),
parent(), SLOT(slotGroupsBtnClicked()) );
//Followup-to
connect( mFollowuptoEdit, SIGNAL(focused()),
this, SLOT(hideFollowuptoHint()) );
//subject
mSubjectEdit->setView( this );
mSubjectEdit->enableCompletion( false );
mEdtList.append( mSubjectEdit );
connect( mSubjectEdit, SIGNAL(textChanged(QString)),
parent(), SLOT(slotSubjectChanged(QString)) );
//Editors
mEditor->switchToPlainText();
mEditor->setMinimumHeight(50);
connect( mExternalKillSwitch, SIGNAL(clicked(bool)),
this, SIGNAL(closeExternalEditor()) );
hideExternalNotification();
mExternalKillSwitch->setIcon( KIcon( "application-exit" ) );
// Identities
connect( mIdentitySelector, SIGNAL(identityChanged(uint)),
this, SLOT(slotIdentityChanged(uint)) );
setIdentity( KNGlobals::self()->identityManager()->defaultIdentity().uoid() );
}
View::~View()
{
if ( mAttachmentsList->topLevelItemCount() > 0 ) { // The attachment view was visible
KConfigGroup conf( knGlobals.config(), "POSTNEWS");
conf.writeEntry("Att_Splitter",sizes()); // save splitter pos
QList<int> lst; // save header sizes
QHeaderView *h = mAttachmentsList->header();
for ( int i = 0 ; i < h->count() ; ++i ) {
lst << h->sectionSize(i);
}
conf.writeEntry("Att_Headers",lst);
}
}
void View::completeSetup( bool firstEdit, KNComposer::MessageMode mode )
{
if ( firstEdit ) {
// now we place the cursor at the end of the quoted text / below the attribution line
if ( KNGlobals::self()->settings()->cursorOnTop() ) {
// FIXME: hack: counting the number of \n\n to catch end of introduction (see KNArticleFactory::createReply())
int dbleLfCount = KNGlobals::self()->settings()->intro().count( "%L%L" );
const QString text = mEditor->textOrHtml();
int pos = 0;
while ( dbleLfCount >= 0 ) {
pos = text.indexOf( QLatin1String( "\n\n" ), pos );
pos += 2;
--dbleLfCount;
}
mEditor->setCursorPositionFromStart( pos - 1 );
} else {
mEditor->setCursorPositionFromStart( mEditor->document()->characterCount() - 1 );
}
if ( knGlobals.settings()->appendOwnSignature() ) {
appendSignature();
}
} else {
mEditor->setCursorPositionFromStart( 0 );
}
mEditor->document()->setModified( false );
setMessageMode( mode );
// Focus
mEditor->setFocus();
if ( mSubjectEdit->text().length() == 0 ) {
mSubjectEdit->setFocus();
}
if ( mGroupsEdit->text().length() == 0 && mode == KNComposer::news ) {
mGroupsEdit->setFocus();
}
if ( mToEdit->text().length() == 0 && mode == KNComposer::mail ) {
mToEdit->setFocus();
}
}
void View::focusNextPrevEdit( const QWidget *aCur, bool aNext )
{
QList<QWidget*>::Iterator it;
if ( !aCur ) {
it = --( mEdtList.end() );
} else {
for ( QList<QWidget*>::Iterator it2 = mEdtList.begin(); it2 != mEdtList.end(); ++it2 ) {
if ( (*it2) == aCur ) {
it = it2;
break;
}
}
if ( it == mEdtList.end() )
return;
if ( aNext )
++it;
else {
if ( it != mEdtList.begin() )
--it;
else
return;
}
}
if ( it != mEdtList.end() ) {
if ( (*it)->isVisible() )
(*it)->setFocus();
} else if ( aNext )
mEditor->setFocus();
}
void View::setComposingFont( const QFont &font )
{
mSubjectEdit->setFont( font );
mToEdit->setFont( font );
mGroupsEdit->setFont( font );
mFollowuptoEdit->setFont( font );
mEditor->setFontForWholeText( font );
}
void View::setMessageMode( KNComposer::MessageMode mode )
{
showTo( mode != KNComposer::news );
showGroups( mode != KNComposer::mail );
showFollowupto( mode != KNComposer::mail );
}
uint View::selectedIdentity() const
{
return mIdentitySelector->currentIdentity();
}
void View::setIdentity( uint uoid )
{
mIdentitySelector->setCurrentIdentity( uoid );
// mIdentitySelector will emit its identityChanged(uint) signal
// that is connected to slotIdentityChanged(uint)
}
void View::slotIdentityChanged( uint uoid )
{
KPIMIdentities::IdentityManager *im = KNGlobals::self()->identityManager();
KPIMIdentities::Identity identity = im->identityForUoid( uoid );
setFrom( identity.fullEmailAddr() );
if ( KPIMUtils::isValidAddress( from() ) != KPIMUtils::AddressOk ) {
showFrom( true );
}
}
const QString View::from()
{
return mFromEdit->text();
}
void View::setFrom( const QString& from )
{
mFromEdit->setText( from );
}
const QStringList View::groups() const
{
const QRegExp r = QRegExp( "\\s*,\\s*", Qt::CaseInsensitive, QRegExp::RegExp2 );
return mGroupsEdit->text().split( r, QString::SkipEmptyParts );
}
void View::setGroups( const QString &groups )
{
mGroupsEdit->setText( groups );
slotGroupsChanged(); // update the followup-to
}
void View::slotGroupsChanged()
{
QStringList groupsList = groups();
int groupsCount = groupsList.size();
groupsList.append( QString() );
const QString currFup2 = mFollowuptoEdit->currentText();
int i = groupsList.indexOf( currFup2 );
if ( i == -1 ) {
groupsList.prepend( currFup2 );
} else {
groupsList.move( i, 0 );
}
mFollowuptoEdit->clear();
mFollowuptoEdit->addItems( groupsList );
// Display an hint about fu2
if ( groupsCount > 1 ) {
displayFollowuptoHint();
} else {
hideFollowuptoHint();
}
}
const QString View::emailRecipient() const
{
return mToEdit->text();
}
void View::setEmailRecipient( const QString& to )
{
mToEdit->setText( to );
}
const QStringList View::followupTo() const
{
const QRegExp r = QRegExp( "\\s*,\\s*", Qt::CaseInsensitive, QRegExp::RegExp2 );
return mFollowuptoEdit->currentText().split( r, QString::SkipEmptyParts );
}
void View::setFollowupTo( const QString &followupTo )
{
hideFollowuptoHint();
mFollowuptoEdit->setEditText( followupTo );
}
void View::displayFollowuptoHint()
{
const QString hint = i18nc( "@info/plain This message is place, as an inactive text, in the Followup-To "
"line edit of the message composer when the user select more than one "
"group to post his/her message.",
"Choose an appropriate group to redirect replies..." );
if ( mFollowuptoEdit->currentText().isEmpty() ) {
QLineEdit *l = mFollowuptoEdit->lineEdit();
QPalette palette = l->palette();
KColorScheme::adjustForeground( palette, KColorScheme::InactiveText );
l->setPalette( palette );
l->setText( hint );
}
}
void View::hideFollowuptoHint()
{
const QString hint = i18nc( "@info/plain This message is place, as an inactive text, in the Followup-To "
"line edit of the message composer when the user select more than one "
"group to post his/her message.",
"Choose an appropriate group to redirect replies..." );
if ( mFollowuptoEdit->currentText() == hint ) {
QLineEdit *l = mFollowuptoEdit->lineEdit();
QPalette palette = l->palette();
KColorScheme::adjustForeground( palette, KColorScheme::NormalText );
l->setPalette( palette );
l->setText( QString() );
}
}
const QString View::subject() const
{
return mSubjectEdit->text();
}
void View::setSubject( const QString &subject )
{
mSubjectEdit->setText( subject );
}
KNComposerEditor * View::editor() const
{
return mEditor;
}
void View::appendSignature()
{
KPIMIdentities::IdentityManager *im = KNGlobals::self()->identityManager();
KPIMIdentities::Identity identity = im->identityForUoid( selectedIdentity() );
identity.signature().insertIntoTextEdit( KPIMIdentities::Signature::End,
KPIMIdentities::Signature::AddSeparator,
mEditor );
}
void View::showIdentity( bool show )
{
mIdentitySelectorLabel->setVisible( show );
mIdentitySelector->setVisible( show );
}
void View::showFrom( bool show )
{
mFromLabel->setVisible( show );
mFromEdit->setVisible( show );
}
void View::showTo( bool show )
{
mToLabel->setVisible( show );
mToEdit->setVisible( show );
mToButton->setVisible( show );
}
void View::showGroups( bool show )
{
mGroupsLabel->setVisible( show );
mGroupsEdit->setVisible( show );
mGroupsButton->setVisible( show );
}
void View::showFollowupto( bool show )
{
mFollowuptoLabel->setVisible( show );
mFollowuptoEdit->setVisible( show );
}
void View::showSubject( bool show )
{
mSubjetLabel->setVisible( show );
mSubjectEdit->setVisible( show );
}
void View::showAttachmentView()
{
if ( !mAttachmentSetup ) {
mAttachmentSetup = true;
//connections
connect( mAttachmentsList, SIGNAL(itemSelectionChanged()),
this, SLOT(slotAttachmentSelectionChanged()) );
connect( mAttachmentsList, SIGNAL(contextMenuRequested(QPoint)),
parent(), SLOT(slotAttachmentPopup(QPoint)) );
connect( mAttachmentsList, SIGNAL(deletePressed()),
this, SLOT(removeCurrentAttachment()) );
connect( mAttachmentsList, SIGNAL(attachmentRemoved(KNAttachment::Ptr,bool)),
parent(), SLOT(slotAttachmentRemoved(KNAttachment::Ptr,bool)) );
connect( mAttachmentsList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
mAttachmentsList, SLOT(editCurrentAttachment()) );
connect( mAttachmentsList, SIGNAL(returnPressed()),
mAttachmentsList, SLOT(editCurrentAttachment()) );
connect( mAttachmentsList, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
parent(), SLOT(slotAttachmentChanged()) );
//buttons
connect( mAttachmentAddButton, SIGNAL(clicked()),
parent(), SLOT(slotAttachFile()) );
mAttachmentRemoveButton->setEnabled( false );
connect( mAttachmentRemoveButton, SIGNAL(clicked()),
this, SLOT(removeCurrentAttachment()) );
mAttachmentPropertiesButton->setEnabled( false );
connect( mAttachmentPropertiesButton, SIGNAL(clicked()),
mAttachmentsList, SLOT(editCurrentAttachment()) );
}
if ( !mAttachmentWidget->isVisible() ) {
mAttachmentWidget->show();
KConfigGroup conf(knGlobals.config(), "POSTNEWS");
QList<int> lst = conf.readEntry("Att_Splitter",QList<int>());
if(lst.count()!=2)
lst << 267 << 112;
setSizes(lst);
lst=conf.readEntry("Att_Headers",QList<int>());
QHeaderView *h = mAttachmentsList->header();
if ( lst.count() == h->count() ) {
for( int i = 0 ; i < h->count() ; ++i) {
h->resizeSection( i, lst[ i ] );
}
}
}
}
void View::hideAttachmentView()
{
mAttachmentWidget->hide();
}
void View::addAttachment( KNAttachment::Ptr attachment )
{
AttachmentViewItem *item = new AttachmentViewItem( mAttachmentsList, attachment );
mAttachmentsList->addTopLevelItem( item );
}
const QList<KNAttachment::Ptr> View::attachments() const
{
return mAttachmentsList->attachments();
}
void View::removeCurrentAttachment()
{
mAttachmentsList->removeCurrentAttachment();
}
void View::editCurrentAttachment()
{
mAttachmentsList->editCurrentAttachment();
}
void View::slotAttachmentSelectionChanged()
{
bool e = !mAttachmentsList->selectedItems().isEmpty();
mAttachmentRemoveButton->setEnabled( e );
mAttachmentPropertiesButton->setEnabled( e );
}
void View::showExternalNotification()
{
mEditorsStack->setCurrentWidget( mExternalEditorNotification );
}
void View::hideExternalNotification()
{
mEditorsStack->setCurrentWidget( mEditor );
}
} // namespace Composer
} // namespace KNode