Logo Search packages:      
Sourcecode: mailody version File versions  Download package

composer.cpp

/* This file is part of the KDE project

   Copyright (C) 2006-2007 KovoKs <info@kovoks.nl>
   Copyright (C) 2007 Frode M. Døving <frode@lnix.net>

   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.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   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, USA.
*/

#include <qtextcodec.h>
#include <qcheckbox.h>
#include <qlabel.h>
#include <qcursor.h>
#include <qlayout.h>
#include <qsplitter.h>
#include <qpushbutton.h>
#include <qpopupmenu.h>

#include "../libkmime/kmime_headers.h"
#include "../libkmime/kmime_message.h"

#include <kaction.h>
#include <kaboutdata.h>
#include <kcursor.h>
#include <kmdcodec.h>
#include <kdebug.h>
#include <klineedit.h>
#include <klocale.h>
#include <kinstance.h>
#include <kiconloader.h>
#include <kiconview.h>
#include <kabc/stdaddressbook.h>
#include <kapplication.h>
#include <kmessagebox.h>
#include <krun.h>
#include <ktextedit.h>
#include <kinputdialog.h>
#include <kmimetype.h>
#include <kfileitem.h>
#include <kfileiconview.h>

#include "setup.h"
#include "sidebar.h"
#include "tooltip.h"
#include "imapmanager.h"
#include "global.h"
#include "linklocator.h"
#include "filebrowser.h"
#include "composertextedit.h"
#include "datalistview.h"
#include "addresslineedit.h"
#include "addressbook.h"
#include "mailodybaselistview.h"
#include "composer.h"
#include "db.h"
#include "smtp.h"
#include "messagedata.h"

namespace Mailody {

//---------- Composer --------------------------//
00073 Composer::Composer( QWidget* parent, const QString& mb )
  : KMainWindow( parent, "composer#"),
    m_lastState(To),
    m_smtp(0),
    m_close(false),
    m_dirty(false)
{
    setCaption(i18n("Composer"));
    m_mailbox = mb;
    kdDebug() << "Message will be stored in " << mb << endl;

    QHBox* box = new QHBox(this);

    // ------------- Split it in two columns ---------------//
    m_sidebar = new SideBar::Sidebar(box, "SideBarSettings",
                                  Sidebar::Left, true);

    m_hsplitter = new QSplitter(box);

    m_sidebar->setSplitter(m_hsplitter);
    m_hsplitter->setOrientation(Qt::Horizontal);

    m_addressbook = new KListView(0);
    m_addressbook->addColumn(i18n("Name"));
    m_addressbook->addColumn(i18n("Email"));
    m_addressbook->setShowSortIndicator(true);
    connect(m_addressbook,
            SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
            SLOT(slotAddAddressFromAddressBook(QListViewItem*)));
    connect(m_addressbook,
            SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint &)),
            SLOT(slotContextMenuAddressBook(KListView*, QListViewItem*,
                 const QPoint &)));

    m_filebrowser = new FileBrowserNS::FileBrowser(0,"FileView");
    m_filebrowser->readConfig(kapp->config(), "FileViewSettings");
    connect(m_filebrowser->dirOperator(),
            SIGNAL(fileSelected(const KFileItem*)),
            this,SLOT(slotAddFile(const KFileItem*)));

    m_recentbook = new MailodyBaseListView(0);
    m_recentbook->addColumn(i18n("Email"));
    m_recentbook->addColumn(i18n("Name"));
    m_recentbook->addColumn(i18n("Amount"));
    m_recentbook->addColumn(i18n("Last"));
    m_recentbook->setColumnAlignment(2, Qt::AlignRight);
    m_recentbook->setSortColumn(3);
    m_recentbook->setSortOrder(Qt::Descending);
    m_recentbook->setShowSortIndicator(true);
    connect(m_recentbook,
            SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
            SLOT(slotAddAddressFromRecentBook(QListViewItem*)));
    connect(m_recentbook,
            SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint &)),
            SLOT(slotContextMenuRecentBook(KListView*, QListViewItem*,
                 const QPoint &)));
    connect(m_recentbook,
            SIGNAL(onItem(QListViewItem*)),
            SLOT(slotShowRecentDetails(QListViewItem*)));
    connect(m_recentbook, SIGNAL(leftWidget()), SLOT(slotHideRecentDetails()));
    connect(m_recentbook, SIGNAL(onViewport()), SLOT(slotHideRecentDetails()));

    m_sidebar->appendTab(m_addressbook, SmallIcon("kaddressbook"),
                         i18n("Addressbook"));
    m_sidebar->appendTab(m_recentbook, SmallIcon("fork"),
                         i18n("Recent"));
    m_sidebar->appendTab(m_filebrowser, SmallIcon("folder"),
                         i18n("Add Attachment"));
    m_sidebar->loadViewState();

    // -------------- The second column is split in two rows ----//
    m_vsplitter = new QSplitter(m_hsplitter);
    m_vsplitter->setOrientation(Qt::Vertical);

    // and the top part is in two parts....
    m_vhsplitter = new QSplitter(m_vsplitter);
    m_vhsplitter->setOrientation(Qt::Horizontal);

    QWidget* widg = new QWidget(m_vhsplitter);
    QGridLayout* grid = new QGridLayout(widg,2,2,6,6);

    QLabel* identitylabel = new QLabel(i18n("Identity:")+' ', widg);
    m_identityBox = new KComboBox(widg);
    identitylabel->setBuddy(m_identityBox);
    m_identityBox->insertStringList(Global::identities());
    connect(m_identityBox,SIGNAL(activated(const QString&)),
            SLOT(slotReplaceSignature(const QString&)));

    QLabel* tolabel = new QLabel(i18n("Recipient:")+' ', widg);
    m_edit = new AddressLineEdit( widg );
    tolabel->setBuddy(m_edit);
    connect(m_edit,SIGNAL(shiftAddress()), SLOT(slotShiftAddress()));
    connect(m_edit,SIGNAL(addAddress(const QString&)),
            SLOT(slotAddAddress(const QString&)));
    connect(m_edit,SIGNAL(addAddress(const QString&)),
            SLOT(slotSetDirty()));

    m_add = new QPushButton(i18n("Add"), widg);
    connect(m_add, SIGNAL(clicked()), SLOT(slotAddClicked()));
    connect(m_add, SIGNAL(clicked()), SLOT(slotSetDirty()));

    m_lv = new DataListView(widg,0,5);
    m_lv->setColumnText(0, i18n("Address"));
    m_lv->setColumnText(1, i18n("To"));
    m_lv->setColumnText(2, i18n("Cc"));
    m_lv->setColumnText(3, i18n("Bcc"));
    m_lv->setColumnText(4, i18n("Del"));
    connect(m_lv, SIGNAL(clicked(QListViewItem*, const QPoint&, int)),
            SLOT(slotEditAddress(QListViewItem*, const QPoint&, int)));
    connect(m_lv, SIGNAL(selectionChanged()), SLOT(slotUpdateLineEdit()));
    connect(m_lv,
            SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint &)),
            SLOT(slotContextMenuAddressList(KListView*, QListViewItem*,
                 const QPoint &)));

    m_alabel = new QLabel(i18n("Attached:")+' ', widg);
    m_attachview = new KFileIconView(widg, "attachview");
    m_attachview->setArrangement(QIconView::LeftToRight);
    m_attachview->hide();
    m_alabel->setBuddy(m_attachview);
    m_alabel->hide();

    KFileViewSignaler *sig = m_attachview->signaler();
    connect(sig, SIGNAL(fileSelected(const KFileItem*)),
            this, SLOT(slotShowFile(const KFileItem*)));
    connect(sig, SIGNAL(activatedMenu(const KFileItem*, const QPoint&)),
            this, SLOT(slotContextMenuAttachedFile(const KFileItem*,
                       const QPoint&)));

    QLabel* label = new QLabel(i18n("Subject:")+' ', widg);
    m_subject = new KLineEdit( widg, "subject" );
    label->setBuddy(m_subject);
    connect(m_subject, SIGNAL(textChanged( const QString & )),
            SLOT(slotSetDirty()));

    grid->addWidget(identitylabel,0,0, Qt::AlignRight);
    grid->addMultiCellWidget(m_identityBox,0,0,1,2);
    grid->addWidget(tolabel,1,0, Qt::AlignRight);
    grid->addWidget(m_edit,1,1);
    grid->addWidget(m_add,1,2);
    grid->addMultiCellWidget(m_lv,2,2,1,2);
    grid->addWidget(label,3,0, Qt::AlignRight);
    grid->addMultiCellWidget(m_subject,3,3,1,2);
    grid->addWidget(m_alabel,4,0, Qt::AlignRight);
    grid->addMultiCellWidget(m_attachview,4,4,1,2);
    grid->setColStretch(1,10);

    //--------------------------------------------------------

    QWidget* widg2 = new QWidget(m_vsplitter);
    QGridLayout* grid2 = new QGridLayout(widg2,3,2,5,5);

    m_text = new ComposerTextEdit(widg2);
    m_text->setCheckSpellingEnabled(true);
    connect(m_text, SIGNAL(textChanged()), SLOT(slotSetDirty()));
    connect(m_text, SIGNAL(addAttachment(const KURL&)),
            SLOT(slotAddFile(const KURL&)));

    QPushButton* send = new QPushButton(i18n("Send"), widg2);
    send->setIconSet(SmallIcon("mail_send"));
    connect(send, SIGNAL(clicked()), SLOT(slotSend()));
    new KAction( i18n("Send Email"), Qt::CTRL + Qt::Key_Return,
                                  this, SLOT(slotSend()),
                                  actionCollection(),"send_message");

    QPushButton* save = new QPushButton(i18n("Save"), widg2);
    save->setIconSet(SmallIcon("filesave"));
    connect(save, SIGNAL(clicked()), SLOT(slotSave()));
    new KAction( i18n("Save Email"), Qt::CTRL + Qt::Key_S,
                                  this, SLOT(slotSave()),
                                  actionCollection(), "composer_save_message");

    QCheckBox* ff = new QCheckBox(i18n("Fixed Font"), widg2);
    connect(ff, SIGNAL(toggled( bool )), SLOT(slotFixedFont( bool )));

    grid2->addMultiCellWidget(m_text,0,0,0,3);
    grid2->addWidget(send,1,3);
    grid2->addWidget(save,1,2);
    grid2->addWidget(ff,1,1);
    grid2->setColStretch(1,10);

    //--------------------------------------------------------

    box->show();
    setCentralWidget(box);
    setMinimumSize(QSize(800,600));
    setAutoSaveSettings("Composer", true);

    KConfig *config = kapp->config();
    config->setGroup("ComposerSplitterSize");

    QValueList<int> defaultsize1 = config->readIntListEntry("hsplitter");
    if (!defaultsize1.count())
    {
        defaultsize1.append(24);
        defaultsize1.append(1);
        defaultsize1.append(475);
    }

    QValueList<int> defaultsize2 = config->readIntListEntry("vsplitter");
    if (!defaultsize2.count())
    {
        defaultsize2.append(200);
        defaultsize2.append(400);
    }

    QValueList<int> defaultsize3 = config->readIntListEntry("vhsplitter");
    if (!defaultsize3.count())
    {
        defaultsize3.append(275);
        defaultsize3.append(1);
        defaultsize3.append(125);
    }

    m_hsplitter->setSizes(defaultsize1);
    m_vsplitter->setSizes(defaultsize2);
    m_vhsplitter->setSizes(defaultsize3);

    m_lv->restoreLayout(config,"ComposerAddressListSize");
    m_lv->setSorting(500, false); // override sorting method
    m_attachview->readConfig(config,"ComposerAttachViewSize");
    m_edit->setFocus();

    // When we have time, load the addressess from ab
    QTimer::singleShot(0, this, SLOT(slotLoadAddressBook()));
    QTimer::singleShot(0, this, SLOT(slotLoadRecentBook()));
    m_tip = new ToolTip(this);
    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), SLOT(slotShowRecentDetailsDoIt()));

    // default values
    m_sigPos = 0;
    m_newpos = 0;
}

00308 Composer::~Composer()
{
    m_filebrowser->writeConfig(kapp->config(), "FileViewSettings");

    KConfig *config = kapp->config();
    config->setGroup("ComposerSplitterSize");
    config->writeEntry("hsplitter", m_hsplitter->sizes());
    config->writeEntry("vsplitter", m_vsplitter->sizes());
    config->writeEntry("vhsplitter", m_vhsplitter->sizes());
    m_lv->saveLayout(config,"ComposerAddressListSize");
    m_attachview->writeConfig(config,"ComposerAttachViewSize");
    config->sync();

    delete m_addressbook;
    delete m_recentbook;
    delete m_filebrowser;
}

00326 void Composer::setDirty(bool dirty)
{
    m_dirty = dirty;
}

QString Composer::compileMessage(bool send)
{
    kdDebug() << "compiling message" << endl;
    using KMime::Message;
    using KMime::Content;

    kdDebug() << "check settings" << endl;
    QString sendWith = m_identityBox->text(m_identityBox->currentItem());
    KConfig* config = kapp->config();
    config->setGroup("identity_" + sendWith);
    QString smtp_server = config->readEntry("smtpServer");
    QString name = config->readEntry("fullName");
    QString email = config->readEntry("emailAddress");
    int sendhtmlPart = config->readNumEntry("htmlPart");

    while (smtp_server.isEmpty() || name.isEmpty() || email.isEmpty())
    {
        int i = KMessageBox::warningContinueCancel(this,
                                i18n("Settings are not complete, "
                                     "complete them and try again..."),
                                i18n("Settings"));
        if (i == KMessageBox::Continue)
        {
            Setup setup(0,"Setup");
            if (setup.exec() != QDialog::Accepted)
                return QString::null;

            KConfig* config = kapp->config();
            config->setGroup("identity_" + sendWith);
            smtp_server = config->readEntry("smtpServer");
            name = config->readEntry("fullName");
            email = config->readEntry("emailAddress");
            sendhtmlPart = config->readNumEntry("htmlPart");
        }
        else
            return QString::null;
    }

    m_main = new Message();
    m_main->contentType()->setMimeType("multipart/mixed");
    m_main->contentType()->setBoundary(KMime::multiPartBoundary());

    KMime::Headers::From* fromAddress = new KMime::Headers::From;
    fromAddress->setName( KMime::encodeRFC2047String(name, encoding(name)) );
    fromAddress->setEmail( email.latin1() );
    m_main->setHeader( fromAddress );

    KMime::Headers::To* toAddress = new KMime::Headers::To(m_main);
    KMime::Headers::CC* ccAddress = new KMime::Headers::CC(m_main);
    KMime::Headers::BCC* bccAddress = new KMime::Headers::BCC(m_main);

    DB* conn = DB::dbinstance();
    QListViewItemIterator it( m_lv );
    while ( it.current() ) {
        QListViewItem* item = it.current();

        KMime::Headers::AddressField Address;
        Address.fromUnicodeString( item->text(0),encoding(item->text(0)));

        conn->addToRecentList(Address.email(), Address.name());
        m_tos.append(Address.email());

        if (item->pixmap(1))
            toAddress->addAddress(Address);
        else if (item->pixmap(2))
            ccAddress->addAddress(Address);
        else if (item->pixmap(3))
            bccAddress->addAddress(Address);
        ++it;
    }

    if (!m_tos.count() && send)
    {
        KMessageBox::error(this, i18n("There are no recipients..."));
        return QString::null;
    }

    if (!ccAddress->isEmpty())
        m_main->setHeader( ccAddress );
    if (!bccAddress->isEmpty())
        m_main->setHeader( bccAddress );
    if (!toAddress->isEmpty())
        m_main->setHeader( toAddress );

    if (m_subject->text().isEmpty() && send)
    {
        bool ok = false;
        const QString theSubject = KInputDialog::getText(
                    i18n("No subject."),
                    i18n("There is no subject. You can provide one here:"),
                    QString::null, &ok, this);
        if(ok)
            m_subject->setText(theSubject);
        else
            return QString::null;
    }

    KMime::Headers::Subject* Subject = new KMime::Headers::Subject;
    Subject->fromUnicodeString( m_subject->text(), encoding(m_subject->text()));
    m_main->setHeader( Subject );

    KMime::Headers::Date* Date = new KMime::Headers::Date;
    Date->setUnixTime( QDateTime::currentDateTime().toTime_t() );
    m_main->setHeader( Date );

    KMime::Headers::UserAgent* userAgent= new KMime::Headers::UserAgent;
    userAgent->fromUnicodeString( "Mailody-v" + kapp->aboutData()->version(),
                                  "us-ascii");
    m_main->setHeader( userAgent );

    // add a in reply to
    if (!m_replyTo.isEmpty())
    {
        KMime::Headers::Generic* rt= new KMime::Headers::Generic;
        rt->fromUnicodeString(m_replyTo,encoding(m_replyTo));
        rt->setType("In-Reply-To");
        m_main->setHeader( rt );
    }

    // set X-Mailody-Signature and X-Mailody-SP
    if (!send)
    {
        // XMS
        KMime::Headers::Generic* xms = new KMime::Headers::Generic;
        QString sig;
        sig = QString::fromUtf8(KCodecs::base64Encode(m_oldSig.utf8(), true));

        kdDebug() << "CM-sig: " << sig <<endl;
        kdDebug() << "CM-m_oldSig: " << m_oldSig <<endl;

        xms->fromUnicodeString(sig,encoding(sig));
        xms->setType("X-Mailody-Signature");
        m_main->setHeader( xms );

        // XMSP
        KMime::Headers::Generic* xmsp = new KMime::Headers::Generic;
        QString p;
        p = QString::number(m_newpos);

        kdDebug() << "CM-m_newpos: " << m_newpos <<endl;
        kdDebug() << "CM-p: " << p <<endl;

        xmsp->fromUnicodeString(p,encoding(p));
        xmsp->setType("X-Mailody-SP");
        m_main->setHeader( xmsp );
    }

    // add a messageid.
    KMime::Headers::MessageID* mi = new KMime::Headers::MessageID;
    mi->generate( email.mid(email.find("@")+1 ).latin1());
    m_main->setHeader( mi );

    QString theText = m_text->text();

    // plain part.
    Content* c_plain = new Content();
    c_plain->contentType()->from7BitString( "text/plain" );
    c_plain->fromUnicodeString( theText );
    c_plain->assemble();

    if (!sendhtmlPart || !send)
        m_main->addContent(c_plain);
    else
    {
        // Make the html-part of the same message.
        Content* c_html = new Content();
        c_html->contentType()->from7BitString( "text/html" );
        const int flags = LinkLocatorNS::LinkLocator::PreserveSpaces |
                        LinkLocatorNS::LinkLocator::HighlightText;
        c_html->fromUnicodeString( Global::highlightText(
                LinkLocatorNS::LinkLocator::convertToHtml( theText, flags )));
        c_html->assemble();

        // Make a Content* that will hold the plain and html part.
        Content* c_maincontent = new Content();
        c_maincontent->contentType()->setMimeType("multipart/alternative");
        c_maincontent->contentType()->setBoundary(KMime::multiPartBoundary());
        c_maincontent->addContent(c_plain);
        c_maincontent->addContent(c_html);
        c_maincontent->assemble();

        m_main->addContent(c_maincontent);
    }

    // Hook in the attachments
    int totalSize = 0;
    const KFileItemList *vl = m_attachview->items();
    KFileItem* item;
    for ( KFileItemListIterator it2(*vl); (item = it2.current()); ++it2)
    {

        //TODO: network transparency....
        QFile file( item->localPath() );
        if (file.open(IO_ReadOnly))
        {
            QByteArray data(file.size());
            file.readBlock(data.data(),file.size());
            file.close();

            // convert to base64
            QCString final = KCodecs::base64Encode(data, true);

            // Add this part
            Content* c = new Content();
            c->setBody(final+"\n\n");

            // Add a content type / find mime-type
            KMimeType::Ptr type = item->determineMimeType();
            KMime::Headers::ContentType* ctt= new KMime::Headers::ContentType(c);
            ctt->fromUnicodeString(type->name(),encoding(type->name()));
            ctt->setName( item->name(),"");
            c->setHeader( ctt );

            // Set the encoding.
            KMime::Headers::CTEncoding* cte= new KMime::Headers::CTEncoding(c);
            cte->setCte(KMime::Headers::CEbase64);
            cte->setDecoded( false );
            c->setHeader( cte );
            c->assemble();

            // Save the size.
            totalSize += file.size();

            m_main->addContent(c);
        }
    };

    if (totalSize > 2000000)
    {
        int i = KMessageBox::warningContinueCancel(this,
                    i18n("The size of the attachments is %1, are you "
                         "sure you want to continue?")
                           .arg( KIO::convertSize(KIO::filesize_t(totalSize))),
                    i18n("Big attachment"),
                     KStdGuiItem::cont(),
                     "big_attachments_are_ok");
        if (i != KMessageBox::Continue)
            return QString::null;
    }


    m_main->assemble();

//    kdDebug() << "message compiled. " << endl;
    const QString result = m_main->encodedContent(true) + "\r\n";
    return result;
}

bool Composer::queryClose()
{
    if (m_close)
        return true;

    return canClose();
}

const char * Composer::encoding(const QString& data)
{
    static QTextCodec* local = KGlobal::locale()->codecForEncoding();
    kdDebug() << "user has: " << local->mimeName() << endl;

    if (local->canEncode(data))
        return local->mimeName();
    else
        return "utf-8";
}

00598 bool Composer::canClose()
{
    if (m_dirty)
    {
        int i = KMessageBox::questionYesNo(this,
                       i18n("Are you sure you want to close this window?"));
        return i == KMessageBox::Yes ? true : false;
    }
    else
        return true;
}

00610 void Composer::setRcpt(const QString& address, TypeOfAddress addressType)
{
    m_lastState = addressType;
    addAddress(address);
}

00616 void Composer::setIdentity(const QString& identity)
{
    m_identityBox->setCurrentItem(identity);
}

00621 void Composer::setSubject(const QString& subject)
{
    m_subject->blockSignals(true);
    m_subject->setText(subject);
    m_subject->blockSignals(false);
}

00628 void Composer::setMsg(const QString& msg, bool sign)
{
    QString message = msg;
    if (sign)
        addSignature(message);

    // we do not want to get this dirty
    m_text->blockSignals(true);
    m_text->setText(message);
    m_lv->childCount() ? m_text->setFocus() : m_edit->setFocus();
    m_text->blockSignals(false);
}

00641 void Composer::setOldSig(QString& text)
{
    m_oldSig = text;
}

00646 void Composer::setNewPos(int pos)
{
    m_newpos = pos;
}

00651 void Composer::addAttachment(const KURL& attachment, const QString& name)
{
    m_attachview->show();
    m_alabel->show();
    KMimeType::Ptr type = KMimeType::findByURL(attachment);
    KFileItem *i = new KFileItem(attachment,type->name(),KFileItem::Unknown);

    if (!name.isEmpty())
        i->setName(name);

    m_attachview->insertItem(i);
}

00664 void Composer::inReplyTo(const QString& messageID)
{
    m_replyTo = messageID;
}

void Composer::slotUpdateLineEdit()
{
    // we obiously do not want textChanged() emitted here, which would
    // remove all the text accept the P.
    m_edit->blockSignals(true);

    QListViewItem* selectedItem = m_lv->selectedItems( true ).first();
    if (!selectedItem)
    {
        m_edit->clear();
        return;
    }
    if (selectedItem->pixmap(Cc))
        m_edit->setText(i18n("Press enter to move the address to the bcc-field"));
    else if (selectedItem->pixmap(Bcc))
        m_edit->setText(i18n("Press enter to move the address to the to-field"));
    else if (selectedItem->pixmap(To))
        m_edit->setText(i18n("Press enter to move the address to the cc-field"));

    m_edit->blockSignals(false);

    m_edit->setPaletteForegroundColor(QColor(160,160,160));
    m_edit->setHelp(true);
    m_edit->setCursorPosition(0);
}

void Composer::slotShiftAddress()
{
    QListViewItem* selectedItem = m_lv->selectedItems( true ).first();
    if (!selectedItem)
        return;
    if (selectedItem->pixmap(To))
        slotEditAddress(selectedItem,QPoint(),Cc);
    else if (selectedItem->pixmap(Cc))
        slotEditAddress(selectedItem,QPoint(),Bcc);
    else if (selectedItem->pixmap(Bcc))
        slotEditAddress(selectedItem,QPoint(),To);
    slotUpdateLineEdit();
}

void Composer::slotAddAddress(const QString& text)
{
    addAddress(text);
}

void Composer::slotAddClicked()
{
    if (m_edit->help())
        slotShiftAddress();
    else
        addAddress(m_edit->text());
}

00722 void Composer::addSignature(QString& text)
{
    QString signWith = m_identityBox->text(m_identityBox->currentItem());
    KConfig* config = kapp->config();
    config->setGroup("identity_" + signWith);
    QString sig = config->readEntry("signature");
    int pos = config->readNumEntry("sigPos");
    if (config->readBoolEntry("sigEnabled", false))
    {
        if (sig.find("\n-- \n") == -1 && !sig.startsWith("-- \n"))
            sig.prepend("\n-- \n");
        if (sig.startsWith("-- \n"))
            sig.prepend("\n");

        if (pos == 1)
        {
            sig.append("\n\n");
            text.prepend(sig);
        }
        else
            text.append(sig);

        m_oldSig = sig;
    }
}

void Composer::slotReplaceSignature(const QString& signWith)
{
    KConfig* config = kapp->config();
    config->setGroup("identity_" + signWith);
    QString newsig = config->readEntry("signature");
    QString msg = m_text->text();
    int m_newpos = config->readNumEntry("sigPos");
    if (config->readBoolEntry("sigEnabled", false))
    {

        if (newsig.find("\n-- \n") == -1 && !newsig.startsWith("-- \n"))
            newsig.prepend("\n-- \n");
        if (newsig.startsWith("-- \n"))
            newsig.prepend("\n");

        if (m_newpos != m_sigPos)
        {
            msg.remove(m_oldSig);
            if (m_newpos == 1)
            {
               if (!newsig.endsWith("\n\n"))
                    newsig.append("\n\n");
                msg.prepend(newsig);
            }
            else
                msg.append(newsig);

            m_sigPos = m_newpos;
        }
        else if (msg.contains(m_oldSig) > 0)
                msg.replace(m_oldSig, newsig);
            else
                msg.append(newsig);
    }
    else if (!m_oldSig.isEmpty())
            msg.remove(m_oldSig);

    m_oldSig = newsig;
    m_text->blockSignals(true);
    m_text->setText(msg);
    m_text->blockSignals(false);
}

void Composer::addAddress(const QString& text)
{
    if (text.isEmpty() || text.contains("@") != 1)
        return;

    // Check for dups.
    QListViewItemIterator it( m_lv );
    while ( it.current() )
    {
        QListViewItem* item = it.current();
        if (item->text(0).find(text) != -1)
               return;
        ++it;
    }

    m_lastInserted = new KListViewItem(m_lv, text.stripWhiteSpace());
    m_lastInserted->setRenameEnabled(0,true);
    m_lastInserted->setPixmap(m_lastState,
                    KGlobal::iconLoader()->loadIcon("button_ok",KIcon::Small));
    m_lastInserted->setPixmap(4,
                    KGlobal::iconLoader()->loadIcon("cancel",KIcon::Small));
    m_lastInserted->moveItem(m_lv->lastItem());
    m_lv->ensureItemVisible(m_lastInserted);
    m_lv->setSelected(m_lastInserted, true);
    m_edit->clear();
    m_edit->setFocus();
    slotUpdateLineEdit();
}

void Composer::slotAddFile(const KFileItem*)
{
    // partly from Kate
    const KFileItemList *list=m_filebrowser->dirOperator()->selectedItems();
    KFileItem *tmp;
    for (KFileItemListIterator it(*list); (tmp = it.current()); ++it)
    {
        kdDebug() << tmp->url().path() << endl;
        kdDebug() << "attach count: " << m_attachview->QIconView::count() << endl;

        // find existing one
        bool exists = false;
        const KFileItemList *vl = m_attachview->items();
        KFileItem* item;
        for ( KFileItemListIterator it2(*vl); (item = it2.current()); ++it2)
            if (item->url().path() == tmp->url().path())
                exists = true;

        if (exists)
            continue;

       // Add it...
        m_dirty = true; // do it here, as forward message does not come here
        addAttachment(tmp->url());
        m_filebrowser->dirOperator()->view()->setSelected(tmp,false);
        }
}

void Composer::slotAddFile(const KURL& file)
{
       m_dirty = true;
       addAttachment(file);
}

void Composer::slotEditAddress(QListViewItem* lvi, const QPoint&, int c )
{
    if (!lvi)
        return;

    if (!c)
        return;

    if (c == 4)
    {
        delete lvi;
        return;
    }

    lvi->setPixmap(To,QPixmap());
    lvi->setPixmap(Cc,QPixmap());
    lvi->setPixmap(Bcc,QPixmap());
    lvi->setPixmap(c,KGlobal::iconLoader()->loadIcon("button_ok",KIcon::Small));
    m_lastState=c;
}

void Composer::slotContextMenuAttachedFile(const KFileItem* ivi, const QPoint& point)
{
    if (!ivi)
        return;

    QPopupMenu* p = new QPopupMenu(this);
    int open = p->insertItem(i18n("Open"));
    p->insertSeparator();
    int remove = p->insertItem(i18n("Remove"));
    int choice = p->exec(point);

    if (choice == remove)
    {
        m_attachview->removeItem(ivi);

        if (m_attachview->QIconView::count() == 0)
        {
            m_attachview->hide();
            m_alabel->hide();
        }
    }
    else if (choice == open)
        new KRun(ivi->localPath());
}

void Composer::slotShowFile(const KFileItem* ivi)
{
    if (!ivi)
        return;
    new KRun(ivi->localPath());
}

void Composer::slotSetAddress(const QString& address)
{
    m_edit->setText(address);
}

// -------------- addressbook ---------------------------

void Composer::slotAddAddressFromAddressBook(QListViewItem* lvi)
{
    if (!lvi)
        return;

    addAddress( m_abMap[lvi] );
}

void Composer::slotLoadAddressBook()
{
    m_ab = Addressbook::instance()->getAddressbookPointer();
    connect(m_ab, SIGNAL(addressBookChanged(AddressBook*)),
            SLOT(slotLoadAddresses(AddressBook*)));
    slotLoadAddresses(m_ab);
}

void Composer::slotLoadAddresses(KABC::AddressBook* ab)
{
    // kdDebug() << "Loading Addresses from Addressbook" << endl;
    m_abMap.clear();
    m_addressbook->clear();
    m_edit->completion()->clear();
    KABC::AddressBook::Iterator it;
    for ( it = ab->begin(); it != ab->end(); ++it )
    {
        // For the completion object, i want all addresses....
        QString realName = (*it).realName();
        QStringList list = (*it).emails();
        QStringList::Iterator its=list.begin();
        for(; its!=list.end(); ++its)
            m_edit->completion()->addItem(realName + " <" + (*its) + '>');

        // In the addressbook only show the preferred address...
        m_abMap[new KListViewItem(m_addressbook,
                                  (*it).formattedName(),
                                  (*it).preferredEmail(),
                                  (*it).uid())] = (*it).fullEmail();
    }
}

void Composer::slotContextMenuAddressBook(KListView*, QListViewItem* lvi,
                                       const QPoint &point)
{
    using namespace KABC;

    if (!lvi)
        return;

    QPopupMenu* p = new QPopupMenu(this);
    int open = p->insertItem(i18n("Open KDE Address Book"));
    int del = p->insertItem(i18n("Delete from KDE Address Book"));
    int choice = p->exec(point);

    if (choice == del)
    {
        int i = KMessageBox::questionYesNo(this,
                    i18n("Do you really want to delete %1 from your KDE "
                         "Address Book?").arg(lvi->text(0)));
        if (i == KMessageBox::Yes)
        {
            Addressee a(m_ab->findByUid(lvi->text(2)));
            if (!a.isEmpty())
            {
                m_ab->removeAddressee(a);
                KABC::Ticket *ticket = m_ab->requestSaveTicket( a.resource() );
                if ( ticket )
                    m_ab->save( ticket );
            }
            else
                kdDebug() << "Address not found!!!" << lvi->text(2) << endl;
        }
    }
    else if (choice == open)
    {
        KRun::runCommand("kaddressbook --uid " + lvi->text(2));
    }
}

void Composer::slotContextMenuAddressList(KListView*, QListViewItem* lvi,
                                          const QPoint &point)
{
    using namespace KABC;

    if (!lvi)
        return;

    QPopupMenu* p = new QPopupMenu(this);
    int add = p->insertItem(i18n("Add to KDE Addressbook"));
    int choice = p->exec(point);

    if (choice == add)
        Addressbook::instance()->add(lvi->text(0));
}

// ---------------------- recent -----------------------//

void Composer::slotLoadRecentBook()
{
    m_recentbook->clear();

    DB* conn = DB::dbinstance();
    QStringList values;
    conn->getRecentList( values );

    QStringList::Iterator its = values.begin();
    while (its != values.end())
    {
        QString email = (*its);
        ++its;
        QString name = (*its);
        ++its;
        QDateTime t;
        t.setTime_t((*its).toInt());
        ++its;
        QString amount = (*its);
        ++its;

        m_edit->completion()->addItem(name + " <" + email + '>');
        MailodyBaseListViewItem * i = new MailodyBaseListViewItem(m_recentbook);
        i->setText(0, email);
        i->setText(1, name);
        i->setText(2, amount);
        i->setFancyDate(3, t);
    }
}

void Composer::slotAddAddressFromRecentBook(QListViewItem* lvi)
{
    if (!lvi)
        return;

    addAddress( lvi->text(0) + " <" + lvi->text(1) + ">" );
}

void Composer::slotContextMenuRecentBook(KListView*, QListViewItem* lvi,
                 const QPoint& point)
{
    if (!lvi)
        return;

    QPopupMenu* p = new QPopupMenu(this);
    int del = p->insertItem(i18n("Delete"));
    int choice = p->exec(point);

    if (choice == del)
    {
        DB* conn = DB::dbinstance();
        conn->deleteFromRecentList(lvi->text(0));
        delete lvi;
    }
}

void Composer::slotShowRecentDetails(QListViewItem* lvi)
{
    m_currentItem = lvi;
    m_timer->start(500, true);
}

void Composer::slotShowRecentDetailsDoIt()
{
    if (!m_currentItem)
        return;

    QString text = "<table style=\"margin-right: 20px;\" ";
    text.append("cellpadding=0 cellspacing=0 width=\"100%\">");
    text.append("<tr><td colspan=2><b><nobr>" + m_currentItem->text(1)
            + "</nobr></b></td></tr>");
    text.append("<tr><td><nobr>"+i18n("Last mailed at:")
            + "</nobr></td><td><nobr>" + m_currentItem->text(3)
            + "</nobr></td><tr>");
    text.append("<tr><td><nobr>"+i18n("Total amount of mails sent:")
            + "</nobr></td><td><nobr>" + m_currentItem->text(2)
            + "</nobr></td></tr>");
    text.append("</table>");

    m_tip->setText(QCursor::pos(), text);
}

void Composer::slotHideRecentDetails()
{
    m_timer->stop();
    m_tip->hide();
}

// ---------------------- send -------------------------//

void Composer::slotSend()
{
    kdDebug() << "start slotSend" << endl;
    setCursor(KCursor::waitCursor());
    const QString cmsg = compileMessage(true); // send = true.

    if (cmsg.isEmpty())
        return;
    ImapManager* im = ImapManager::instance();
    im->saveMessage(m_mailbox, cmsg);

    if (m_smtp)
        delete m_smtp;

    m_smtp = new SMTP(this, "SMTP");
    connect(m_smtp, SIGNAL(error(const QString&)),
            SLOT(slotError(const QString&)));
    connect(m_smtp, SIGNAL(done()),SLOT(slotDone()));

    m_smtp->send(m_identityBox->text(m_identityBox->currentItem()),
                m_tos, cmsg);
}

void Composer::slotSave()
{
    kdDebug() << "start slotSave" << endl;
    setCursor(KCursor::waitCursor());
    const QString cmsg = compileMessage(false); // false = don't prepare for sending.
    const QString flags = "\\Draft";

    if (cmsg.isEmpty())
        return;
    ImapManager* im = ImapManager::instance();
    im->saveMessage(m_mailbox, cmsg, flags);

    connect(im, SIGNAL(saveDone()), SLOT(slotDone()));
}

void Composer::slotFixedFont( bool toggle )
{
    toggle ? m_text->setFont(KGlobalSettings::fixedFont())
        : m_text->setFont(KGlobalSettings::generalFont());
}

void Composer::slotSetDirty()
{
    m_dirty = true;
}

void Composer::slotDone()
{
    m_close = true;
    close();
}

void Composer::slotError(const QString& error)
{
    setCursor(KCursor::arrowCursor());
    KMessageBox::information(this, error);
}

}

#include "composer.moc"

Generated by  Doxygen 1.6.0   Back to index