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

mainwindow.cpp

/* This file is part of the KDE project

   Copyright (C) 2006-2007 Omat Holding B.V. <info@omat.nl>
   Copyright (C) 2006-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.
*/


// Own
#include "mainwindow.h"
#include "mainwindowadaptor.h"
#include "messagedata.h"
#include "headerwidget.h"
#include "headerview.h"
#include "headerproxy.h"
#include "messageview.h"
#include "setup.h"
#include "tooltip.h"
#include "global.h"
#include "quickreplywidget.h"
#include "composer.h"
#include "database.h"
#include "systemtray.h"
#include "tabwidget.h"

// akonadi
#include <akonadi/control.h>
#include <akonadi/collection.h>
#include <akonadi/collectionview.h>
#include <akonadi/collectionmodel.h>
#include <akonadi/collectionstatisticsmodel.h>
#include <akonadi/collectionfilterproxymodel.h>
#include <akonadi/collectionstatisticsdelegate.h>
#include <akonadi/agentmanager.h>
#include <akonadi/itemmodifyjob.h>
#include <akonadi/item.h>
#include <akonadi/standardactionmanager.h>
#include <akonadi/kmime/messagemodel.h>

// System
#include <sys/time.h>

// Qt
#include <QDockWidget>
#include <QSplitter>
#include <QToolButton>
#include <QTimer>

// KDE
#include <KActionCollection>
#include <KActionMenu>
#include <KApplication>
#include <KCmdLineArgs>
#include <KCodecs>
#include <KFileDialog>
#include <KVBox>
#include <KHTMLView>
#include <KMenu>
#include <KMessageBox>
#include <KNotifyConfigWidget>
#include <KSqueezedTextLabel>
#include <kstdaccel.h>
#include <KStatusBar>
#include <KToggleAction>

#include <kstatusbarofflineindicator.h>
#include <kpimidentities/identity.h>

using namespace Mailody;
using namespace Akonadi;

00085 MainWindow::MainWindow( )
        : KXmlGuiWindow( 0 ), m_idlePossible( false ), m_online( false )
{
    Akonadi::Control::start();
    QProcess::startDetached( "akonaditray" );

    // D-Bus
    new MainwindowAdaptor( this );
    QDBusConnection dbus = QDBusConnection::sessionBus();
    dbus.registerObject( "/mailody", this );

    // First do a check for resouced. If not go to the settings dialog...
    // TODO: check if there are resources we use, not in general....
    AgentManager *manager = AgentManager::self();
    if ( manager->instances().isEmpty() )
        startupSetup(); // do not refresh mb list now...

    KConfigGroup configGeneral = KGlobal::config()->group( "General" );
    QString hp = configGeneral.readEntry( "homePage", "http://www.mailody.net" );

    m_db = Database::dbinstance();
    connect( Akonadi::AgentManager::self(), SIGNAL( instanceStatusChanged( const Akonadi::AgentInstance & ) ),
             SLOT( slotAgentInstanceStatusChanged( const Akonadi::AgentInstance & ) ) );
    connect( Akonadi::AgentManager::self(), SIGNAL( instanceProgressChanged( const Akonadi::AgentInstance & ) ),
             SLOT( slotAgentInstanceProgressChanged( const Akonadi::AgentInstance & ) ) );

    QDockWidget* mailboxDock = new QDockWidget( i18n( "Folders" ), this );
    mailboxDock->setObjectName( "mailboxDock" );

    // collection list (mailboxlist)
    m_collectionView = new Akonadi::CollectionView( this );
    connect( m_collectionView, SIGNAL( clicked( const Akonadi::Collection ) ),
             SLOT( collectionClicked( const Akonadi::Collection ) ) );
    m_collectionModel = new Akonadi::CollectionStatisticsModel( this );
    QSortFilterProxyModel *sortModel = new QSortFilterProxyModel( this );
    sortModel->setDynamicSortFilter( true );
    sortModel->setSortCaseSensitivity( Qt::CaseInsensitive );
    sortModel->setSourceModel( m_collectionModel );
    m_collectionView->setItemDelegate(
        new Akonadi::CollectionStatisticsDelegate( m_collectionView ) );

    // filter
    m_collectionProxyModel = new Akonadi::CollectionFilterProxyModel( this );
    m_collectionProxyModel->setSourceModel( sortModel );
    QStringList list;
    list << "message/news" << "message/rfc822";
    m_collectionProxyModel->addMimeTypeFilters( list );
    m_collectionView->setModel( m_collectionProxyModel );

    mailboxDock->setWidget( m_collectionView );
    mailboxDock->setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable );
    addDockWidget( Qt::LeftDockWidgetArea, mailboxDock );
    actionCollection()->addAction( "toggle_mailboxdock", mailboxDock->toggleViewAction() );


    /* TODO: Reimplement this.
    m_nextUnreadAction = new KAction(this);
    m_nextUnreadAction->setText(i18n("Next Unread"));
    m_nextUnreadAction->setIcon(KIcon("go-down-search"));
    m_nextUnreadAction->setShortcut(Qt::Key_Space);
    actionCollection()->addAction("next_unread", m_nextUnreadAction);
    connect(m_nextUnreadAction, SIGNAL(triggered(bool)),
                            SLOT(slotNextUnread()));
    */

    m_selectAllAction = new KAction( this );
    m_selectAllAction->setText( i18n( "Select All Messages" ) );
    m_selectAllAction->setIcon( KIcon( "edit-select-all" ) );
    m_selectAllAction->setShortcut( KStandardShortcut::selectAll() );
    actionCollection()->addAction( "select_all_msg", m_selectAllAction );
    connect( m_selectAllAction, SIGNAL( triggered( bool ) ),
             SLOT( slotSelectAllMessages() ) );

    /* TODO: where are my threads??
    m_childSortAction = new KToggleAction( this );
    m_childSortAction->setText( i18n( "Sort on Youngest Child" ) );
    m_childSortAction->setIcon( KIcon( "view-sort-ascending" ) );
    actionCollection()->addAction( "sort_youngest_child", m_childSortAction );
    connect( m_childSortAction, SIGNAL( triggered( bool ) ),
             SLOT( slotSortOnYoungestChild() ) );
    */

    m_hideDeletedAction = new KToggleAction( this );
    m_hideDeletedAction->setText( i18n( "Hide Deleted Messages" ) );
    actionCollection()->addAction( "hide_deleted", m_hideDeletedAction );
    connect( m_hideDeletedAction, SIGNAL( triggered( bool ) ),
             SLOT( slotHideDeleted() ) );

    m_headerAndViewer = new QSplitter( this );
    m_headerAndViewer->setOrientation( Qt::Vertical );

    QWidget *widg = new QWidget( m_headerAndViewer );
    QGridLayout *gbox = new QGridLayout( widg );
    m_headerWidget = new Mailody::HeaderWidget( this );

    connect( m_headerWidget->view(), SIGNAL( scrollDown() ),
             SLOT( slotTabScrollDown() ) );
    connect( m_headerWidget->view(), SIGNAL( scrollUp() ),
             SLOT( slotTabScrollUp() ) );
    connect( m_headerWidget->view(), SIGNAL( scrollPageDown() ),
             SLOT( slotTabScrollPageDown() ) );
    connect( m_headerWidget->view(), SIGNAL( scrollPageUp() ),
             SLOT( slotTabScrollPageUp() ) );

    connect( m_headerWidget,
             SIGNAL( selectMessageLeft( Akonadi::Item ) ),
             SLOT( slotShowMessage( Akonadi::Item ) ) );
    connect( m_headerWidget->view(),
             SIGNAL( selectMessageRight( Akonadi::Item ) ),
             SLOT( slotContextMenuHeaders( Akonadi::Item ) ) );
    connect( m_headerWidget->view(),
             SIGNAL( selectMessageMiddle( Akonadi::Item ) ),
             SLOT( slotMiddleClickInHeaders( Akonadi::Item ) ) );

    gbox->addWidget( m_headerWidget, 1, 0 );
    m_right = new KVBox( m_headerAndViewer );

    // ---------------- Tab Widget -------------------//

    m_tabWidget = new TabWidget( m_right );
    connect( m_tabWidget, SIGNAL( clicked() ), SLOT( slotNewTab() ) );
    connect( m_tabWidget, SIGNAL( contextMenu( QWidget*, const QPoint & ) ),
             SLOT( slotContextMenuTab( QWidget*, const QPoint & ) ) );
    connect( m_tabWidget, SIGNAL( closeRequest( QWidget* ) ),
             SLOT( slotDeleteTab( QWidget* ) ) );
    connect( m_tabWidget, SIGNAL( currentChanged( int ) ),
             SLOT( slotCurrentTabChanged( int ) ) );

    m_closeAction = new KAction( this );
    m_closeAction->setText( i18n( "Close Tab" ) );
    m_closeAction->setShortcut( Qt::CTRL + Qt::Key_W );
    actionCollection()->addAction( "close_tab", m_closeAction );
    connect( m_closeAction, SIGNAL( triggered( bool ) ),
             SLOT( slotDeleteTab() ) );

    // Do not load the favorite website yet, first setup all the actions.
    m_tabWidget->show();

    // -------------------Quick Reply Widget -----------------//

    m_quickReplyWidget = new QuickReplyWidget( m_right );
    connect( m_quickReplyWidget, SIGNAL( finished() ), SLOT( slotQuickReply() ) );
    m_quickReplyWidget->setVisible( false );
    m_quickReplyWidget->setEnabled( false );

    // ------------------ Load settings ----------------------//

    KConfigGroup configMain = KGlobal::config()->group( "MainWindowSizes" );
//X     configMain = KGlobal::config()->group( "MainWindowSizes" );
    QList<int> defaultsize2 = configMain.readEntry( "hsplitter", QList<int>() );
    if ( defaultsize2.isEmpty() ) {
        defaultsize2.append( 300 );
        defaultsize2.append( 400 );
    }

    m_headerAndViewer->setSizes( defaultsize2 );

    QList<int> collectionSizes = configMain.readEntry( "collectionSizes", QList<int>() );
    for ( int i = 0; i < collectionSizes.size(); ++i )
        m_collectionView->setColumnWidth( i, collectionSizes.at( i ) );

    // -------------------- Create actions --------------------//
    StandardActionManager *stdActionMgr = new StandardActionManager( actionCollection(), this );
    stdActionMgr->setCollectionSelectionModel( m_collectionView->selectionModel() );
    stdActionMgr->createAllActions();
    /*
    actMgr->createAction( Akonadi::StandardActionManager::CreateCollection );
    actMgr->createAction( Akonadi::StandardActionManager::DeleteCollections );
    actMgr->createAction( Akonadi::StandardActionManager::CollectionProperties );
    */

    KStandardAction::preferences( this,
                                  SLOT( slotSetup() ), actionCollection() );
    KStandardAction::configureNotifications( this,
            SLOT( slotNotifications() ), actionCollection() );

    KAction *quit = new KAction( this );
    quit->setText( i18n( "Quit" ) );
    quit->setIcon( KIcon( "application-exit" ) );
    quit->setShortcut( KStandardShortcut::quit() );
    actionCollection()->addAction( "mailody_quit", quit );
    connect( quit, SIGNAL( triggered( bool ) ),
             SLOT( slotQuit() ) );

    KAction *sync_all = new KAction( this );
    sync_all->setText( i18n( "Sync Folder List (all accounts)" ) );
    actionCollection()->addAction( "sync_mblists", sync_all );
    connect( sync_all, SIGNAL( triggered( bool ) ),
             SLOT( slotSyncAllFolderLists() ) );

    m_syncResource = new KAction( this );
    m_syncResource->setText( i18n( "Sync Folder List (this account)" ) );
    actionCollection()->addAction( "sync_mblist", m_syncResource );
    connect( m_syncResource, SIGNAL( triggered( bool ) ),
             SLOT( slotSyncFolderList() ) );

    KAction *getmail = new KAction( this );
    getmail->setText( i18n( "Check for Mail Now" ) );
    getmail->setShortcut( Qt::CTRL + Qt::Key_L );
    getmail->setIcon( KIcon( "mail-receive" ) );
    actionCollection()->addAction( "check_mail", getmail );
    connect( getmail, SIGNAL( triggered( bool ) ),
             SLOT( slotCheckMail() ) );

    m_msgSaveAction = new KAction( this );
    m_msgSaveAction->setText( i18n( "Save as..." ) );
    m_msgSaveAction->setShortcut( KStandardShortcut::save() );
    m_msgSaveAction->setIcon( KIcon( "document-save-as" ) );
    actionCollection()->addAction( "mailody_save", m_msgSaveAction );
    connect( m_msgSaveAction, SIGNAL( triggered( bool ) ),
             SLOT( slotSave() ) );

    m_msgPrintAction = new KAction( this );
    m_msgPrintAction->setText( i18n( "Print..." ) );
    m_msgPrintAction->setShortcut( KStandardShortcut::print() );
    m_msgPrintAction->setIcon( KIcon( "document-print" ) );
    actionCollection()->addAction( "mailody_print", m_msgPrintAction );
    connect( m_msgPrintAction, SIGNAL( triggered( bool ) ),
             SLOT( slotPrint() ) );

    m_msgZoomInAction = new KAction( this );
    m_msgZoomInAction->setText( i18n( "Zoom In" ) );
    m_msgZoomInAction->setShortcut( KStandardShortcut::zoomIn() );
    m_msgZoomInAction->setIcon( KIcon( "zoom-in" ) );
    actionCollection()->addAction( "mailody_zoom_in", m_msgZoomInAction );
    connect( m_msgZoomInAction, SIGNAL( triggered( bool ) ),
             SLOT( slotZoomIn() ) );

    m_msgZoomOutAction = new KAction( this );
    m_msgZoomOutAction->setText( i18n( "Zoom Out" ) );
    m_msgZoomOutAction->setShortcut( KStandardShortcut::zoomOut() );
    m_msgZoomOutAction->setIcon( KIcon( "zoom-out" ) );
    actionCollection()->addAction( "mailody_zoom_out", m_msgZoomOutAction );
    connect( m_msgZoomOutAction, SIGNAL( triggered( bool ) ),
             SLOT( slotZoomOut() ) );

    m_plainTextAction = new KToggleAction( this );
    m_plainTextAction->setText( i18n( "Show as Text" ) );
    m_plainTextAction->setShortcut( Qt::Key_F10 );
    actionCollection()->addAction( "toggle_html", m_plainTextAction );
    connect( m_plainTextAction, SIGNAL( triggered( bool ) ),
             SLOT( slotToggleHTML() ) );

    m_sourceAction = new KToggleAction( this );
    m_sourceAction->setText( i18n( "Show Source" ) );
    m_sourceAction->setShortcut( Qt::Key_V );
    actionCollection()->addAction( "toggle_source", m_sourceAction );
    connect( m_sourceAction, SIGNAL( triggered( bool ) ),
             SLOT( slotToggleSource() ) );

    m_fixedfontAction = new KToggleAction( this );
    m_fixedfontAction->setText( i18n( "Use Fixed Font" ) );
    m_fixedfontAction->setShortcut( Qt::Key_X );
    actionCollection()->addAction( "toggle_fixedfont", m_fixedfontAction );
    connect( m_fixedfontAction, SIGNAL( triggered( bool ) ),
             SLOT( slotToggleFixedFont() ) );

    m_externalImageAction = new KToggleAction( this );
    m_externalImageAction->setText( i18n( "Load External Images" ) );
    actionCollection()->addAction( "toggle_externalimage", m_externalImageAction );
    connect( m_externalImageAction, SIGNAL( triggered( bool ) ),
             SLOT( slotToggleExternalImage() ) );

    m_msgDelAction = new KToggleAction( this );
    m_msgDelAction->setText( i18n( "Message Deleted" ) );
    m_msgDelAction->setIcon( KIcon( "edit-delete" ) );
    m_msgDelAction->setShortcut( Qt::Key_Delete );
    actionCollection()->addAction( "delete_message", m_msgDelAction );
    connect( m_msgDelAction, SIGNAL( triggered( bool ) ),
             SLOT( slotToggleDelete() ) );

    m_purgeAction = new KAction( this );
    m_purgeAction->setText( i18n( "Remove Deleted Messages" ) );
    m_purgeAction->setIcon( KIcon( "trash-empty" ) );
    actionCollection()->addAction( "purge_collection", m_purgeAction );
    connect( m_purgeAction, SIGNAL( triggered( bool ) ),
             SLOT( slotPurge() ) );

    m_msgNewAction = new KAction( this );
    m_msgNewAction->setText( i18n( "New" ) );
    m_msgNewAction->setIcon( KIcon( "mail-message-new" ) );
    m_msgNewAction->setShortcut( KStandardShortcut::openNew() );
    m_msgNewAction->setEnabled( true );
    actionCollection()->addAction( "compose_new_message", m_msgNewAction );
    connect( m_msgNewAction, SIGNAL( triggered( bool ) ),
             SLOT( slotNewMessage() ) );

    m_msgNewActionMenu = new KActionMenu( i18n( "New" ), 0 );
    m_msgNewActionMenu->setIcon( KIcon( "mail-message-new" ) );
    m_msgNewActionMenu->setEnabled( true );
    actionCollection()->addAction( "compose_new_messageMenu", m_msgNewActionMenu );

    connect( m_msgNewActionMenu,
             SIGNAL( triggered( Qt::MouseButtons,Qt::KeyboardModifiers ) ),
             SLOT( slotNewMessage() ) );
    connect( m_msgNewActionMenu->menu(), SIGNAL( aboutToShow() ),
             SLOT( slotNewMessageMenu() ) );
    connect( m_msgNewActionMenu->menu(), SIGNAL( triggered( QAction* ) ),
             SLOT( slotNewMessageMenuSelected( QAction* ) ) );

    m_msgReplyAction = new KAction( this );
    m_msgReplyAction->setText( i18n( "Reply" ) );
    m_msgReplyAction->setIcon( KIcon( "mail-reply-all" ) );
    m_msgReplyAction->setShortcut( Qt::CTRL + Qt::Key_R );
    actionCollection()->addAction( "reply_message", m_msgReplyAction );
    connect( m_msgReplyAction, SIGNAL( triggered( bool ) ),
             SLOT( slotReplyMessage() ) );

    m_msgReEditAction = new KAction( this );
    m_msgReEditAction->setText( i18n( "Re-Edit" ) );
    m_msgReEditAction->setIcon( KIcon( "document-properties" ) );
    m_msgReEditAction->setShortcut( Qt::CTRL + Qt::Key_T );
    actionCollection()->addAction( "reedit_message", m_msgReEditAction );
    connect( m_msgReEditAction, SIGNAL( triggered( bool ) ),
             SLOT( slotReEditMessage() ) );

    m_msgForwardAction = new KAction( this );
    m_msgForwardAction->setText( i18n( "Forward" ) );
    m_msgForwardAction->setIcon( KIcon( "mail-forward" ) );
    m_msgForwardAction->setShortcut( Qt::CTRL + Qt::Key_F );
    actionCollection()->addAction( "forward_message", m_msgForwardAction );
    connect( m_msgForwardAction, SIGNAL( triggered( bool ) ),
             SLOT( slotForwardMessage() ) );
    m_msgForwardActionMenu = new KActionMenu( this );
    m_msgForwardActionMenu->setText( i18n( "Forward" ) );
    m_msgForwardActionMenu->setIcon( KIcon( "mail-forward" ) );
    actionCollection()->addAction( "forward_messageMenu", m_msgForwardActionMenu );

    connect( m_msgForwardActionMenu,
             SIGNAL( triggered( Qt::MouseButtons,Qt::KeyboardModifiers ) ),
             SLOT( slotForwardMessage() ) );
    connect( m_msgForwardActionMenu->menu(), SIGNAL( aboutToShow() ),
             SLOT( slotForwardMessageMenu() ) );
    connect( m_msgForwardActionMenu->menu(), SIGNAL( triggered( QAction* ) ),
             SLOT( slotForwardMessageMenuSelected( QAction* ) ) );

    m_msgUser0Action = new KAction( this );
    m_msgUser0Action->setText( i18n( "No Label" ) );
    m_msgUser0Action->setShortcut( Qt::Key_0 );
    actionCollection()->addAction( "tag_0", m_msgUser0Action );
    connect( m_msgUser0Action, SIGNAL( triggered( bool ) ),
             SLOT( slotUser0() ) );

    m_msgUser1Action = new KAction( this );
    m_msgUser1Action->setText( i18n( "Label &1" ) );
    m_msgUser1Action->setIcon( KIcon( "label1" ) );
    m_msgUser1Action->setShortcut( Qt::Key_1 );
    actionCollection()->addAction( "tag_1", m_msgUser1Action );
    connect( m_msgUser1Action, SIGNAL( triggered( bool ) ),
             SLOT( slotUser1() ) );

    m_msgUser2Action = new KAction( this );
    m_msgUser2Action->setText( i18n( "Label &2" ) );
    m_msgUser2Action->setIcon( KIcon( "label2" ) );
    m_msgUser2Action->setShortcut( Qt::Key_2 );
    actionCollection()->addAction( "tag_2", m_msgUser2Action );
    connect( m_msgUser2Action, SIGNAL( triggered( bool ) ),
             SLOT( slotUser2() ) );

    m_msgUser3Action = new KAction( this );
    m_msgUser3Action->setText( i18n( "Label &3" ) );
    m_msgUser3Action->setIcon( KIcon( "label3" ) );
    m_msgUser3Action->setShortcut( Qt::Key_3 );
    actionCollection()->addAction( "tag_3", m_msgUser3Action );
    connect( m_msgUser3Action, SIGNAL( triggered( bool ) ),
             SLOT( slotUser3() ) );

    m_msgUser4Action = new KAction( this );
    m_msgUser4Action->setText( i18n( "Label &4" ) );
    m_msgUser4Action->setIcon( KIcon( "label4" ) );
    m_msgUser4Action->setShortcut( Qt::Key_4 );
    actionCollection()->addAction( "tag_4", m_msgUser4Action );
    connect( m_msgUser4Action, SIGNAL( triggered( bool ) ),
             SLOT( slotUser4() ) );

    m_msgUser5Action = new KAction( this );
    m_msgUser5Action->setText( i18n( "Label &5" ) );
    m_msgUser5Action->setIcon( KIcon( "label5" ) );
    m_msgUser5Action->setShortcut( Qt::Key_5 );
    actionCollection()->addAction( "tag_5", m_msgUser5Action );
    connect( m_msgUser5Action, SIGNAL( triggered( bool ) ),
             SLOT( slotUser5() ) );

    // -------------- statusbar ------------------------------------//

    m_statusText = new KSqueezedTextLabel( this );
    m_statusText->setMargin( 1 );
    m_statusText->setText( i18n( "Ready" ) );
    statusBar()->addWidget( m_statusText,10 );
    statusBar()->insertItem( i18n( "Quick Reply" ), 2, 2 );
    statusBar()->insertItem( i18n( "Plain" ), 3, 1 );
    statusBar()->insertItem( i18nc( "Short for no ext. images",
                                    "No ext." ), 4, 1 );
    connect( statusBar(), SIGNAL( pressed( int ) ),
             SLOT( slotStatusBarClicked( int ) ) );

    m_statusTimer = new QTimer( this );
    m_statusTimer->setSingleShot( true );
    connect( m_statusTimer, SIGNAL( timeout() ), SLOT( slotStatusBarReady() ) );

    KStatusBarOfflineIndicator *nsi =
        new KStatusBarOfflineIndicator( this );
    statusBar()->addWidget( nsi );

    // -------- set the actions according to the settings ----------//

    KConfigGroup configToggle = KGlobal::config()->group( "ToggleStates" );
    m_plainTextAction->setChecked(
        configToggle.readEntry( "plaintext", true ) );
    m_sourceAction->setChecked(
        configToggle.readEntry( "source", false ) );
    m_fixedfontAction->setChecked(
        configToggle.readEntry( "fixed", false ) );
    m_externalImageAction->setChecked(
        configToggle.readEntry( "externalimage", false ) );
    /*m_childSortAction->setChecked(
        configToggle.readEntry( "sort_youngest", false ) ); */
    m_hideDeletedAction->setChecked(
        configToggle.readEntry( "hide_deleted", false ) );
    slotHideDeleted();

    //this also calls setActionStates();
    kDebug() << "Connectio n possible: " << Global::connectionPossible();
    slotOpenURLInNewTab( hp );
    slotToggleHTML();

    m_headerAndViewer->show();
    setCentralWidget( m_headerAndViewer );
    setupGUI( QSize( 900, 600 ), Keys | StatusBar | ToolBar | Create | Save );
    setMinimumSize( QSize( 200, 100 ) );
    setAutoSaveSettings( "MainWindow", true );

    // -----------------prep Tooltip and checkmail timer ------------//

//X     m_tooltip = new ToolTip(this,"notification");
//X     connect(m_tooltip, SIGNAL(leftClicked(const QString&)),
//X             SLOT(slotSelectMB(const QString&)));

    // Commandline stuff - for now only catch mailto: thingies, so I can
    // use mailody as default mua. It also assumes an INBOX.
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
    if ( args ) {
        for ( int i=0; i < args->count(); i++ ) {
            QString argument = args->arg( i );
            if ( argument.startsWith( "mailto:" ) )
                slotNewMessage( argument );
        }
    }

    /* TODO: where is the total unread count signal?
    m_systemTray = new SystemTray( this );
    m_systemTray->setVisible( true );
    connect( m_collectionModel, SIGNAL( unreadCountChanged( int ) ),
             m_systemTray, SLOT( unreadCountChanged( int ) ) );
    */

    setAcceptDrops( false );
    slotSyncAllFolderLists();
}

MainWindow::~MainWindow()
{
    // If quickReply is open, close it before saving splitter sizes.
    if ( m_quickReplyWidget->isEnabled() ) {
        slotQuickReply();
    }

    KConfigGroup configMain =
        KGlobal::config()->group( "MainWindowSizes" );
    configMain.writeEntry( "hsplitter", m_headerAndViewer->sizes() );

    QList<int> sizes;
    for ( int i = 0; i < m_collectionModel->columnCount(); ++i )
        sizes.append( m_collectionView->columnWidth( i ) );
    configMain.writeEntry( "collectionSizes", sizes );
    configMain.sync();

    KConfigGroup configToggle = KGlobal::config()->group( "ToggleStates" );
    configToggle.writeEntry( "plaintext", m_plainTextAction->isChecked() );
    configToggle.writeEntry( "source", m_sourceAction->isChecked() );
    configToggle.writeEntry( "fixed", m_fixedfontAction->isChecked() );
    configToggle.writeEntry( "externalimage", m_externalImageAction->isChecked() );
    //configToggle.writeEntry( "sort_youngest", m_childSortAction->isChecked() );
    configToggle.writeEntry( "hide_deleted", m_hideDeletedAction->isChecked() );
    configToggle.sync();

    delete m_db;
}

void MainWindow::closeEvent( QCloseEvent *event )
{
    // We want to know if there are dirty composers. If that is the case,
    // don't close the mainwindow.
    bool canClose = true;
    QList<Composer*> l = findChildren<Composer*>();
    for ( int i = 0 ; i < l.count(); i++ ) {
        if ( !( l.at( i ) )->canClose() ) {
            event->ignore();
            canClose = false;
        } else
            delete l.at( i );
    }
    canClose ? event->accept() :  event->ignore();
}

void MainWindow::slotSyncAllFolderLists()
{
    const Akonadi::AgentInstance::List instances = Akonadi::AgentManager::self()->instances();
    foreach( Akonadi::AgentInstance agent, instances ) {

        /* We know we can do a collection-tree-sync-only for imap and nntp */
        if ( agent.identifier() == "akonadi_imaplib_resource" ||
                agent.identifier() == "akonadi_nntp_resource" ) {
            agent.synchronizeCollectionTree();
        } else {
            agent.synchronize();
        }
    }
}

void MainWindow::slotSyncFolderList()
{
    const QString identifier = m_currentCollection.resource();
    Akonadi::AgentInstance agent = Akonadi::AgentManager::self()->instance( identifier );
    if ( agent.isValid() )
        agent.synchronizeCollectionTree();
}

void MainWindow::slotOpenComposer( const QString& address,
                                   const QString& files,
                                   const QString& subject,
                                   const QString& body )
{
    kDebug() << "Trying to find inbox";

    // first iterate throught the resources.
    int totalResources = m_collectionProxyModel->rowCount();
    kDebug() << "Rows: " << totalResources;
    for ( int i = 0; i < totalResources ; ++i ) {
        const QModelIndex resourceIndex = m_collectionProxyModel->index( i, 0 );
        kDebug() << "Evaluating resource:" << m_collectionProxyModel->data( resourceIndex );

        // then iterate through the top level folders of that resource.
        int totalFolders = m_collectionProxyModel->rowCount( resourceIndex );
        kDebug() << "We have " << totalFolders << " folders in there";
        for ( int j = 0 ; j < totalFolders ; ++j ) {
            const QModelIndex folderIndex = m_collectionProxyModel->index( j, 0, resourceIndex );
            const Akonadi::Collection collection = m_collectionProxyModel->data( folderIndex,
                                                   Akonadi::CollectionModel::CollectionRole ).value<Akonadi::Collection>();
            kDebug() << "Found folder: " << collection.remoteId();

            // see if we have the inbox.
            if ( collection.remoteId().toLower() == "inbox" ) {
                kDebug() << "Found the inbox.";
                slotOpenComposer( collection, address, files, subject, body );
            }
        }
    }

    int i = KMessageBox::warningContinueCancel( this,
            i18n( "There is no Inbox found in any resource. Starting a new message "
                  "will cause the message to be lost after you have sent it. You will "
                  "not have a local copy anymore. If you want a copy, make sure you add "
                  "yourself as cc for example. Do you want to continue to start a new message?" ),
            QString(),
            KStandardGuiItem::cont(),
            KStandardGuiItem::cancel(),
            "IWantNoLocalCopyWhenNoInboxIsFound" );
    if ( i == KMessageBox::Continue )
        slotOpenComposer( Akonadi::Collection(), address, files, subject, body );
}

void MainWindow::slotOpenComposer( const Akonadi::Collection& mb,
                                   const QString& address,
                                   const QString& files,
                                   const QString& subject,
                                   const QString& body )
{
    kDebug() << address << files << subject << body;

    Composer *composer = new Composer( this, mb );
    connect( composer, SIGNAL( showSettings() ), SLOT( slotSetup() ) );

    // emails
    QStringList addrList = address.split( ',',  QString::SkipEmptyParts );
    for ( QStringList::Iterator it = addrList.begin();
            it != addrList.end();
            ++it ) {
        QString a = *it;
        if ( a.startsWith( "mailto:", Qt::CaseInsensitive ) )
            a.remove( 0,7 );
        a.replace( "%40","@" );

        // kDebug() << "Composer requested: " << a << endl;
        if ( !a.isEmpty() )
            composer->setRcpt( a, Composer::To );
    }

    // attachments
    QStringList fileList =  files.split( ";;", QString::SkipEmptyParts );
    for ( QStringList::Iterator it = fileList.begin();
            it != fileList.end();
            ++it ) {
        KUrl url = KUrl( *it );
        if (( url ).isValid() )
            composer->addAttachment( url );
    }
    composer->setSubject( subject );
    composer->setMsg( body );
    composer->show();
}

//---------------------- message --------------------------------//

void MainWindow::setTag( Akonadi::Item item, const QString& tag )
{
    Q_ASSERT( item.isValid() );

    item.setFlag( tag.toLatin1() );
    Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob( item );
    connect( job, SIGNAL( result( KJob* ) ), SLOT( slotResultStoreJob( KJob* ) ) );

// ### please check if the internal change tracking in Item covers this already
#if 0
    bool donesomething = false;
    if ( tag.startsWith( "$label" ) ) {
        for ( int i = 1; i < 6; ++i ) {
            const QString& label = "$label" + QString::number( i );
            if ( tag == label && !item.hasFlag( label.toLatin1() ) ) {
                donesomething = true;
                job->addFlag( tag.toLatin1() );
            } else if ( tag != label && item.hasFlag( label.toLatin1() ) ) {
                donesomething = true;
                job->removeFlag( tag.toLatin1() );
            }
        }
    } else // deleted and ?
        job->addFlag( tag.toLatin1() );

    if ( !donesomething ) {
        delete job; // can i do it this way??
    }
#endif
}

void MainWindow::setUserTag( int tag )
{
    setTag( "$label" + QString::number( tag ) );
}

void MainWindow::setTag( const QString& tag )
{
    kDebug() << tag;
    QList< Akonadi::Item > list = m_headerWidget->currentlySelectedItems();
    foreach( Akonadi::Item item, list )
    setTag( item, tag );
}

void MainWindow::removeSingleTag( Akonadi::Item item, const QString& flag )
{
    item.clearFlag( flag.toLatin1() );
    Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob( item );
    connect( job, SIGNAL( result( KJob* ) ), SLOT( slotResultStoreJob( KJob* ) ) );
}

void MainWindow::removeTag( const QString& tag )
{
    kDebug() << tag;
    QList< Akonadi::Item > list = m_headerWidget->currentlySelectedItems();
    foreach( Akonadi::Item item, list )
    removeSingleTag( item, tag );
}

void MainWindow::slotToggleDelete()
{
    kDebug();
    if ( !m_msgDelAction->isChecked() ) {
        removeTag( "\\Deleted" );
    } else {
        // As deleted items get removed, save the unselected item below first.
        /*
        QModelIndex below =
                m_headerView->indexBelow( m_headerView->currentIndex() );
        while (below.isValid() &&
               m_headerView->selectionModel()->isSelected( below ))
            below = m_headerView->indexBelow( below );

        MessageData *r = 0;
        if (below.isValid())
        {
            HeaderProxy* proxy= static_cast<HeaderProxy*>(m_headerView->model());
            r = static_cast<HeaderModel*>(proxy->sourceModel())
                        ->messageData( proxy->mapToSource(below) );
        }
        */

        // Now delete the item.
        /*bool somethingDeleted = */
        setTag( "\\Deleted" );

        // clear the view.   ????
        slotUpdateTabTitle( i18n( "Message" ) );

        /*
        if ( below.isValid() && (somethingDeleted ||
             !m_headerView->selectionModel()->hasSelection() ) )
        {
            m_headerView->selectionModel()->select(m_headerView->currentIndex(),
                     QItemSelectionModel::Deselect | QItemSelectionModel::Rows);
            m_headerView->selectionModel()->select(below,
                     QItemSelectionModel::Select | QItemSelectionModel::Rows);
            m_headerView->setCurrentIndex( below );
            m_headerView->scrollTo(below,QAbstractItemView::PositionAtCenter);

            slotShowMessage( r );
        }
        */

        // hide deleted...
        if ( m_hideDeletedAction->isChecked() )
            slotHideDeleted();
    }
}

void MainWindow::slotUser0()
{
    // REMOVE all tags...
    setUserTag( 0 );
}

void MainWindow::slotUser1()
{
    setUserTag( 1 );
}

void MainWindow::slotUser2()
{
    setUserTag( 2 );
}

void MainWindow::slotUser3()
{
    setUserTag( 3 );
}

void MainWindow::slotUser4()
{
    setUserTag( 4 );
}

void MainWindow::slotUser5()
{
    setUserTag( 5 );
}

void MainWindow::slotQuickReply()
{
    static QList<int> s_splitterSizes;

    if ( m_quickReplyWidget->isEnabled() ) {
        m_headerAndViewer->setSizes( s_splitterSizes );
        m_quickReplyWidget->setEnabled( false );
        m_quickReplyWidget->setVisible( false );
        return;
    }

    // Save the current layout.
    s_splitterSizes = m_headerAndViewer->sizes();

    // Initialise the widget
    if ( m_tabWidget->currentTabType( TabWidget::Browser ) )
        return;
    TotalView *i =  m_tabWidget->currentTabWidget();
    MessageData *msg = i->msg();
    m_quickReplyWidget->setMessage( msg );

    // Make the headerlist 0 high and make the widget visible.
    QList<int> newSplitterSizes;
    newSplitterSizes << 0 << s_splitterSizes.at( 1 );
    m_headerAndViewer->setSizes( newSplitterSizes );
    m_quickReplyWidget->setEnabled( true );
    m_quickReplyWidget->setVisible( true );
}

void MainWindow::slotToggleHTML()
{
    TotalView *i = m_tabWidget->currentTabWidget();
    i->body()->setHTML( !m_plainTextAction->isChecked() );
    m_fixedfontAction->setEnabled( m_plainTextAction->isChecked() );
    setStatusBarStates();
}

void MainWindow::slotToggleSource()
{
    TotalView *i = m_tabWidget->currentTabWidget();
    m_sourceAction->isChecked() ? i->body()->setViewSource()
    :i->body()->setHTML( !m_plainTextAction->isChecked() );
    m_plainTextAction->setEnabled( !m_sourceAction->isChecked() );
}

void MainWindow::slotToggleFixedFont()
{
    TotalView *i = m_tabWidget->currentTabWidget();
    i->body()->setFixedFont( m_fixedfontAction->isChecked() );
}

void MainWindow::slotToggleExternalImage()
{
    TotalView *tv = m_tabWidget->currentTabWidget();
    if ( m_externalImageAction->isChecked() ) {
        int i = KMessageBox::warningContinueCancel( this,
                i18n( "Loading external images gives spammers the "
                      "acknowledgement that you received this message "
                      "so they will use your email address to spam you. "
                      "So you should only continue for very trusted messages." ),
                QString(),
                KStandardGuiItem::cont(),
                KStandardGuiItem::cancel(),
                "IKnowRisksOfExternalImages" );
        if ( i == KMessageBox::Continue )
            tv->body()->setExternalImage( true );
        else
            m_externalImageAction->setChecked( false );
    } else
        tv->body()->setExternalImage( false );

    setStatusBarStates();
}

void MainWindow::slotShowMessage( Akonadi::Item item )
{
    showMessage( item, m_currentCollection );
}

void MainWindow::slotMiddleClickInHeaders( Akonadi::Item item )
{
    Q_ASSERT( item.hasPayload() );
    slotNewTab();
    showMessage( item, m_currentCollection );
}

void MainWindow::showMessage( const Akonadi::Item &item, const Akonadi::Collection &collection )
{
    if ( !item.hasPayload() )
        return;

    m_tabWidget->setCurrentTabType( TabWidget::Message );

    TotalView *tv = m_tabWidget->currentTabWidget();
    // Disable loading of external images.
    m_externalImageAction->setChecked( false );
    tv->body()->setExternalImage( false, false );
    tv->setMsg( item, collection );
    int i = m_tabWidget->indexOf( tv );
    m_tabWidget->setTabText( i, tv->msg()->sender() );

    // If quickReply is activated, set the message.
    if ( m_quickReplyWidget->isEnabled() ) {
        m_quickReplyWidget->setMessage( tv->msg() );
    }

    setActionStates();
}

void MainWindow::slotSelectAllMessages()
{
    m_headerWidget->view()->selectAll();
}

void MainWindow::slotSortOnYoungestChild()
{
    // m_headerWidget->setSortOnChild( m_childSortAction->isChecked() );
}

void MainWindow::slotHideDeleted()
{
    m_headerWidget->setHideDeleted( m_hideDeletedAction->isChecked() );
}


//------------------------ Tabs --------------------------------//
void MainWindow::slotNewTab()
{
    TotalView *widget = new TotalView( m_tabWidget );
    m_tabWidget->addMessageTab( widget, i18n( "Message" ) );
    widget->body()->setHTML( !m_plainTextAction->isChecked() );
    if ( m_sourceAction->isChecked() )
        widget->body()->setViewSource();
    widget->body()->setFixedFont( m_fixedfontAction->isChecked() );
    widget->body()->setExternalImage( m_externalImageAction->isChecked() );

    connect( widget->body(), SIGNAL( onURL( const QString& ) ),
             SLOT( slotSimpleMessageStatusBar( const QString& ) ) );
    connect( widget->body(), SIGNAL( openInTab( const QString& ) ),
             SLOT( slotOpenURLInNewTab( const QString& ) ) );
    connect( widget->body(), SIGNAL( openComposer( const Akonadi::Collection&, const QString& ) ),
             SLOT( slotOpenComposer( const Akonadi::Collection&, const QString& ) ) );
    connect( widget->body(), SIGNAL( pageTitle( const QString& ) ),
             SLOT( slotUpdateTabTitle( const QString& ) ) );
    connect( widget->headers(),
             SIGNAL( openComposer( const Akonadi::Collection&, const QString& ) ),
             SLOT( slotOpenComposer( const Akonadi::Collection&, const QString& ) ) );
}

void MainWindow::slotDeleteTab()
{
    m_tabWidget->slotDeleteCurrentWidget();
    slotCurrentTabChanged( m_tabWidget->currentIndex() );
}

void MainWindow::slotDeleteTab( QWidget *tb )
{
    m_tabWidget->slotDeleteWidget( tb );
}

void MainWindow::slotCurrentTabChanged( int i )
{
    Q_UNUSED( i );
    /* TODO: Handle the the reselection the Collection and
     * item in the headerview
     *
    bool message = m_tabWidget->currentWidgetType( TabWidget::Message );
    TotalView *tb;
    if ( message )
        tb = m_tabWidget->currentTabWidget();

    m_mailboxList->blockSignals(true);
    slotSelectMB(tb->msg()->mb());
    m_mailboxList->blockSignals(false);
    */
    setActionStates();
}

void MainWindow::slotTabScrollUp()
{
    TotalView *tb = m_tabWidget->currentTabWidget();
    tb->body()->view()->scrollBy( 0, -10 );
}
void MainWindow::slotTabScrollDown()
{
    TotalView *tb = m_tabWidget->currentTabWidget();
    tb->body()->view()->scrollBy( 0, 10 );
}

void MainWindow::slotTabScrollPageUp()
{
    TotalView *tb = m_tabWidget->currentTabWidget();
    tb->body()->view()->scrollBy( 0, -( int )( 0.85*tb->body()->view()->height() ) );
}

void MainWindow::slotTabScrollPageDown()
{
    TotalView *tb = m_tabWidget->currentTabWidget();
    tb->body()->view()->scrollBy( 0, ( int )( 0.85*tb->body()->view()->height() ) );
}


//---------------------- Menus ---------------------------------//

void MainWindow::slotContextMenuTab( QWidget*, const QPoint &point )
{
    if ( m_tabWidget->count() != 1 ) {
        QMenu *p = new QMenu( this );
        p->addAction( m_closeAction );
        p->popup( point );
    }
}

void MainWindow::slotContextMenuHeaders( const Akonadi::Item& )
{
    QMenu *p = new QMenu( this );

    p->addAction( m_msgReplyAction );
    p->addAction( m_msgForwardAction );
    p->addAction( m_msgReEditAction );
    p->addAction( m_msgDelAction );
    p->addSeparator();
    p->addAction( m_msgUser0Action );
    p->addAction( m_msgUser1Action );
    p->addAction( m_msgUser2Action );
    p->addAction( m_msgUser3Action );
    p->addAction( m_msgUser4Action );
    p->addAction( m_msgUser5Action );
    p->popup( QCursor::pos() );
}

//------------------------- Setup & Quit --------------------------//

void MainWindow::slotSetup()
{
    kDebug();
    Setup setup( 0,"Setup" );
    if ( setup.exec() != QDialog::Accepted )
        return;

    // For the composer, to know when the settings are changed and a new delivery can be made if
    // needed.
    emit setupFinished();

    // Maybe there was a change in the auto saving attachment, so notify the tabs...
    for ( int o = 0; o < m_tabWidget->count() ; ++o )
        m_tabWidget->tabWidget( o )->autoSaveAttachments() ;

    slotSyncFolderList();
}

01091 void MainWindow::slotNewMessage( const QString &to )
{
    if ( m_currentCollection.isValid() )
        slotOpenComposer( m_currentCollection, to );
    else
        slotOpenComposer( to );
}

void MainWindow::slotNewMessageMenu()
{
    messageMenu( m_msgNewActionMenu );
}

void MainWindow::slotNewMessageMenuSelected( QAction *i )
{
    slotNewMessage( i->text() );
}

void MainWindow::slotReplyMessage()
{
    TotalView *i =  m_tabWidget->currentTabWidget();

    MessageData *msg = i->msg();

    Composer *composer = new Composer( this, msg->collection() );
    if ( !msg->replyTo().isEmpty() ) {
        if ( !Global::myEmail( msg->replyTo() ) )
            composer->setRcpt( msg->replyTo(), Composer::To );
    } else {
        if ( !Global::myEmail( msg->sender() ) )
            composer->setRcpt( msg->sender_full( false /* no company*/ ),
                               Composer::To );
    }

    QStringList list = msg->to_list();
    if ( !list.isEmpty() ) {
        QStringList::Iterator it=list.begin();
        for ( ; it!=list.end(); ++it )
            if ( !Global::myEmail(( *it ) ) )
                composer->setRcpt(( *it ), Composer::To );
            else
                composer->setIdentity( Global::getIdentityForEmail( *it ) );
    }

    list = msg->cc_list();
    if ( !list.isEmpty() ) {
        QStringList::Iterator it=list.begin();
        for ( ; it!=list.end(); ++it )
            if ( !Global::myEmail(( *it ) ) )
                composer->setRcpt(( *it ), Composer::Cc );
            else
                composer->setIdentity( Global::getIdentityForEmail( *it ) );
    }

    composer->inReplyTo( msg->messageID() );

    if ( msg->subject().startsWith( "Re:", Qt::CaseInsensitive ) )
        composer->setSubject( msg->subject() );
    else
        composer->setSubject( "Re: " + msg->subject() );

    QString toQuote;
    if ( i->body()->hasSelection() )
        toQuote = i->body()->selectedText();
    else
        toQuote = msg->raw();

    composer->setMsgAndQuote( toQuote, msg->body() );
    composer->show();
}

void MainWindow::slotForwardMessage( const QString &to )
{
    TotalView *i = m_tabWidget->currentTabWidget();

    MessageData *msg = i->msg();
    Composer *composer = new Composer( this, msg->collection() );
    composer->setSubject( "Fwd: " + msg->subject() );

    QString toQuote;
    if ( i->body()->hasSelection() )
        toQuote = i->body()->selectedText();
    else
        toQuote = msg->raw();

    QString text = i18n( "At %1, %2 wrote:\n",
                         KGlobal::locale()->formatDateTime( msg->date(),
                                                            KLocale::LongDate ),
                         msg->sender_full( false /* no company */ ) )
                   + Global::quote( toQuote, false /*leave sig in there*/ ) + '\n';
    composer->setMsg( text );

    if ( !to.isEmpty() )
        composer->setRcpt( to, Composer::To );

    // try to find the right identitiy to forward with...
    QStringList list = msg->to_list();
    if ( !list.isEmpty() ) {
        QStringList::Iterator it=list.begin();
        for ( ; it!=list.end(); ++it )
            if ( Global::myEmail(( *it ) ) )
                composer->setIdentity( Global::getIdentityForEmail( *it ) );
    }

    list = msg->cc_list();
    if ( !list.isEmpty() ) {
        QStringList::Iterator it=list.begin();
        for ( ; it!=list.end(); ++it )
            if ( Global::myEmail(( *it ) ) )
                composer->setIdentity( Global::getIdentityForEmail( *it ) );
    }

    // set the attachments...
    QHash<KUrl,QString> list2 = msg->attachments();
    QHash<KUrl,QString>::Iterator ita;
    for ( ita = list2.begin(); ita != list2.end(); ++ita )
        composer->addAttachment( ita.key(), ita.value() );
    composer->show();
}

void MainWindow::slotForwardMessageMenu()
{
    messageMenu( m_msgForwardActionMenu );
}

void MainWindow::slotReEditMessage( const QString& to )
{
    TotalView *i = m_tabWidget->currentTabWidget();

    MessageData *msg = i->msg();
    Composer *composer = new Composer( this, msg->collection() );
    composer->setSubject( msg->subject() );
    composer->inReplyTo( msg->inreplyto() );

    KPIMIdentities::Identity id = Global::getIdentityForEmail( msg->sender_email() );
    if ( id != KPIMIdentities::Identity::null() ) {
        composer->setIdentity( id );
    }

    QString t = QString();
    if ( i->body()->hasSelection() )
        t = i->body()->selectedText();
    else {
        t = msg->raw();
    }
    composer->setMsg( t, false );

    if ( !to.isEmpty() )
        composer->setRcpt( to, Composer::To );
    else
        composer->setRcpt( msg->to(), Composer::To );

    QHash<KUrl,QString> list2 = msg->attachments();
    QHash<KUrl,QString>::Iterator ita;
    for ( ita = list2.begin(); ita != list2.end(); ++ita )
        composer->addAttachment( ita.key(), ita.value() );

    Item item( msg->item() );
    item.setFlag( "\\Deleted" );
    Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob( msg->item() );
    connect( job, SIGNAL( result( KJob* ) ), SLOT( slotResultStoreJob( KJob* ) ) );

    composer->setDirty();
    composer->show();
}

void MainWindow::slotPurge()
{
    // use dbus to call the resource asking to slotPurge() the collection.
    kDebug() << "CollectionName: " << m_currentCollection.name() << endl;
    kDebug() << "CollectionResource " << m_currentCollection.resource() << endl;
    kDebug() << "CollectionRemoteId: " << m_currentCollection.remoteId() << endl;
    QString dbusstr = "org.kde.Akonadi.Resource.";
    dbusstr.append( m_currentCollection.resource() );
    QDBusInterface dbus( dbusstr, "/Actions",
                         "org.kde.Akonadi.Imaplib.Resource" );
    dbus.call( QLatin1String( "slotPurge" ), m_currentCollection.remoteId() );
}


void MainWindow::slotResultStoreJob( KJob *job )
{
    if ( job->error() ) {
        kWarning() << "Failed: " << job->errorString();
    } else
        kDebug() << "Item stored successfully";
}

void MainWindow::messageMenu( KActionMenu *am )
{
    am->menu()->clear();

    // add them from the current message.
    TotalView *i = m_tabWidget->currentTabWidget();
    QStringList values;
    bool sep = false;
    if ( i && i->msg() && i->headers()->isVisible() ) {
        MessageData *msg = i->msg();

        if ( !msg->replyTo().isEmpty() ) {
            values.append( msg->replyTo() );
            values.append( msg->replyTo() );
            sep = true;
        }

        if ( !msg->sender().isEmpty() ) {
            values.append( msg->sender() );
            values.append( msg->sender_email() );
            sep = true;
        }

        QStringList list = msg->to_list();
        if ( !list.isEmpty() ) {
            QStringList::Iterator it=list.begin();
            for ( ; it!=list.end(); ++it ) {
                values.append( *it );
                values.append( *it );
                sep = true;
            }
        }

        list = msg->cc_list();
        if ( !list.isEmpty() ) {
            QStringList::Iterator it=list.begin();
            for ( ; it!=list.end(); ++it ) {
                values.append( *it );
                values.append( *it );
                sep = true;
            }
        }
    }

    // add top 10
    QStringList values2;
    m_db->getTopTenRecentList( values2 );

    if ( sep && values.count() > 0 ) {
        values.append( "-" );
        values.append( "-" );
    }

    QStringList::iterator it = values2.begin();
    while ( it != values2.end() ) {
        QString name = ( *it );
        ++it;
        QString email = ( *it );
        ++it;

        if ( !values.contains( email ) ) {
            values.append( name );
            values.append( email );
        }
    }

    // make the menu
    it = values.begin();
    while ( it != values.end() ) {
        QString name = ( *it );
        ++it;
        QString email = ( *it );
        ++it;

        if ( name.isEmpty() )
            name = email;

        if ( name == "-" )
            am->menu()->addSeparator();
        else
            am->menu()->addAction( name );
    }

    // still nothing???
    if ( values.isEmpty() ) {
        // change after messagefreeze
        QAction *i = am->menu()->addTitle( i18n( "None" ) );
        i->setEnabled( false );
    }
}

void MainWindow::slotForwardMessageMenuSelected( QAction *i )
{
    slotForwardMessage( i->text() );
}

void MainWindow::slotSelectMessage()
{
    /*    TotalView *tb = static_cast<TotalView*>(m_tabWidget->currentWidget());
        MessageData *hi = tb->msg();
        HeaderProxy *proxy= static_cast<HeaderProxy*>(m_headerView->model());

        // Iterate over all headers to find the message.
        QModelIndex start = m_headerView->indexAt(QPoint(0,0));
        while (start.isValid())
        {
            MessageData *md =
                    static_cast<HeaderModel*>(proxy->sourceModel())
                    ->messageData( proxy->mapToSource(start) );

            if ( md->uid() == hi->uid() && md->mb() == hi->mb() )
            {
                // We do not want to emit signals, just select the item...
                m_headerView->blockSignals(true);
                m_headerView->setCurrentIndex( start );
                m_headerView->scrollTo( start,QAbstractItemView::PositionAtCenter );
                m_headerView->blockSignals(false);
                setActionStates();
                break;
            }
            start = m_headerView->indexBelow( start );
        }

        kDebug() << "Eiks, not found" << endl;*/
}

void MainWindow::startupSetup()
{
    Setup setup( 0,"Setup" );
    setup.exec();
}

void MainWindow::slotNotifications()
{
    KNotifyConfigWidget::configure( this );
}

void MainWindow::slotSave()
{
    TotalView *tb = m_tabWidget->currentTabWidget();
    kDebug() << ":save" << tb->msg()->subject() << endl;
    QString filename = KFileDialog::getSaveFileName( tb->msg()->subject(),
                       "*.eml|Email File\n*.txt|Text File", this, i18n( "Save as..." ) );
    tb->save( filename );
}

void MainWindow::slotPrint()
{
    TotalView *tb = m_tabWidget->currentTabWidget();
    tb->print();
}

void MainWindow::slotZoomIn()
{
    TotalView *tb = m_tabWidget->currentTabWidget();
    tb->body()->increaseZoomLevel();
}

void MainWindow::slotZoomOut()
{
    TotalView *tb = m_tabWidget->currentTabWidget();
    tb->body()->decreaseZoomLevel();
}

void MainWindow::slotCheckMail()
{
    kDebug() << "Implement me!";
}

void MainWindow::setActionStates()
{
    // Determine if a message is shown...
    bool message = m_tabWidget->currentTabType( TabWidget::Message );
    TotalView *tb = m_tabWidget->currentTabWidget();

    // Enable the actions.
    m_externalImageAction->setEnabled( Global::connectionPossible() );  // for websites and messages.
    m_plainTextAction->setEnabled( message );
    m_fixedfontAction->setEnabled( message );
    m_msgDelAction->setEnabled( message );
    m_msgSaveAction->setEnabled( message );
    m_msgPrintAction->setEnabled( message );
    m_msgZoomInAction->setEnabled( message );
    m_msgZoomOutAction->setEnabled( message );
    m_msgForwardAction->setEnabled( message );
    m_msgForwardActionMenu->setEnabled( message );
    m_msgReplyAction->setEnabled( message );
    m_msgReEditAction->setEnabled( message );
    m_sourceAction->setEnabled( message );
    m_msgUser0Action->setEnabled( message );
    m_msgUser1Action->setEnabled( message );
    m_msgUser2Action->setEnabled( message );
    m_msgUser3Action->setEnabled( message );
    m_msgUser4Action->setEnabled( message );
    m_msgUser5Action->setEnabled( message );

    // Set the state of the toggle icons.
    if ( message ) {
        m_plainTextAction->setEnabled( !m_sourceAction->isChecked() );
        m_fixedfontAction->setEnabled( m_plainTextAction->isChecked() );
        m_externalImageAction->setEnabled( !m_plainTextAction->isChecked()
                                           && Global::connectionPossible() );
        m_msgDelAction->setChecked( tb->msg()->isDeleted() );
        setStatusBarStates();
    }

    // And now for the mailbox actions.
    bool somethingSelected = m_collectionView->selectionModel()->hasSelection();
    m_syncResource->setEnabled( somethingSelected );
    m_purgeAction->setEnabled( somethingSelected );
    m_selectAllAction->setEnabled( somethingSelected );
    //m_childSortAction->setEnabled( somethingSelected );
    m_hideDeletedAction->setEnabled( somethingSelected );
}

void MainWindow::slotAgentInstanceStatusChanged( const Akonadi::AgentInstance &instance )
{
    kDebug() << instance.identifier() << instance.status() << instance.statusMessage();
    slotSimpleMessageStatusBar( i18nc( "Status message: first is the account, second the message shown",
                                       "[%1] %2", instance.name(), instance.statusMessage() ) );
}

void MainWindow::slotAgentInstanceProgressChanged( const Akonadi::AgentInstance &instance )
{
    kDebug() << instance.identifier() << instance.progress() << instance.statusMessage();
}

void MainWindow::setStatusBarStates()
{
    if ( m_plainTextAction->isChecked() )
        statusBar()->changeItem( i18nc( "Short for text-mode", "Plain" ), 3 );
    else
        statusBar()->changeItem( i18nc( "Short for html-mode", "HTML" ), 3 );


    if ( m_externalImageAction->isChecked() )
        statusBar()->changeItem( i18nc( "Short for external images", "Ext." ), 4 );
    else
        statusBar()->changeItem( i18nc( "Short for no ext. images", "No ext." ), 4 );
}

void MainWindow::slotUpdateStatusBar( const QString &text )
{
    //kDebug() << "status: " << text << endl;
    m_statusTimer->stop();
    m_lastMessage = text;
    m_statusText->setText( text );
}

void MainWindow::slotUpdateStatusBarRestoreMouse( const QString &text )
{
    //kDebug() << "status: " << text << endl;
    m_statusText->setText( text );
    QApplication::restoreOverrideCursor();
    kapp->processEvents();
    m_statusTimer->start( 3000 );
}

void MainWindow::slotClearStatusBar()
{
    m_statusText->setText(
        i18nc( "task done","%1 [completed]", m_lastMessage ) );
    QApplication::restoreOverrideCursor();
    m_statusTimer->start( 1000 );
}

void MainWindow::slotSimpleMessageStatusBar( const QString &text )
{
    m_statusText->setText( text );
}

void MainWindow::slotStatusBarReady()
{
    m_statusText->setText( i18n( "Ready" ) );
}

void MainWindow::slotStatusBarClicked( int i )
{
    if ( i == 2 ) {
        slotQuickReply();
    } else if ( i == 3 ) {
        m_plainTextAction->setChecked( !m_plainTextAction->isChecked() );
        slotToggleHTML();
    } else if ( i == 4 ) {
        m_externalImageAction->setChecked( !m_externalImageAction->isChecked() );
        slotToggleExternalImage();
    }
}

void MainWindow::slotScrollBottom()
{
    m_headerWidget->view()->setUpdatesEnabled( false );
    m_headerWidget->view()->scrollToBottom();
    m_headerWidget->view()->setUpdatesEnabled( true );
}

void MainWindow::slotOpenURLInNewTab( const QString &page )
{
    KUrl kurl( page );
    QString title = kurl.hasHost() ? kurl.host() : i18n( "Site" );
    slotNewTab();

    TotalView *tb = m_tabWidget->currentTabWidget();
    slotUpdateTabTitle( title );
    tb->headers()->hide();
    tb->body()->setExternalImage( true );
    m_externalImageAction->setChecked( true );
    tb->body()->setOpenLinksDirectly( true );
    m_tabWidget->setCurrentTabType( TabWidget::Browser );
    if ( !page.isEmpty() )
        tb->body()->openUrl( page );
    setActionStates();
}

void MainWindow::slotUpdateTabTitle( const QString &title )
{
    if ( title.isEmpty() )
        return;
    m_tabWidget->setTabText( m_tabWidget->currentIndex(), title );
}

void MainWindow::slotCapableResult( const QString &something, bool possible )
{
    kDebug() << something << possible << endl;
    if ( something == "idle" && possible )
        m_idlePossible = true;
}

void MainWindow::collectionClicked( const Akonadi::Collection &collection )
{
    kDebug() << collection.remoteId();
    m_currentCollection = collection;
    m_headerWidget->messageModel()->setCollection( collection );
    setActionStates();
}

void MainWindow::slotQuit()
{
    exit( 0 );
}

#include "mainwindow.moc"


Generated by  Doxygen 1.6.0   Back to index