mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-24 02:42:51 +00:00
201 lines
6.9 KiB
C++
201 lines
6.9 KiB
C++
/*
|
|
* mailreader.cpp
|
|
*
|
|
* Copyright (C) 2008 Andras Mantia <amantia@kde.org>
|
|
*/
|
|
#include "mailreader.h"
|
|
|
|
#include <akonadi/changerecorder.h>
|
|
#include <akonadi/entitytreemodel.h>
|
|
#include <akonadi/entitytreeview.h>
|
|
#include <akonadi/itemfetchjob.h>
|
|
#include <akonadi/itemfetchscope.h>
|
|
#include <akonadi/entitymimetypefiltermodel.h>
|
|
#include <akonadi/session.h>
|
|
#include <libkdepim/misc/statisticsproxymodel.h>
|
|
#include <akonadi/kmime/messageparts.h>
|
|
|
|
#include <KDE/KAction>
|
|
#include <KDE/KConfigDialog>
|
|
#include <KDE/KActionCollection>
|
|
#include <KDE/KLocale>
|
|
#include <KDE/KStandardAction>
|
|
#include <KDE/KStatusBar>
|
|
|
|
#include <QDockWidget>
|
|
#include <QSortFilterProxyModel>
|
|
|
|
#include <messagelist/pane.h>
|
|
|
|
|
|
#include "mailreaderview.h"
|
|
#include "settings.h"
|
|
|
|
|
|
mailreader::mailreader()
|
|
: KXmlGuiWindow(),
|
|
m_view(new mailreaderView(this))
|
|
{
|
|
// accept dnd
|
|
setAcceptDrops(true);
|
|
|
|
// tell the KXmlGuiWindow that this is indeed the main widget
|
|
setCentralWidget(m_view);
|
|
|
|
setupDocks();
|
|
|
|
// then, setup our actions
|
|
setupActions();
|
|
|
|
// add a status bar
|
|
statusBar()->show();
|
|
|
|
// a call to KXmlGuiWindow::setupGUI() populates the GUI
|
|
// with actions, using KXMLGUI.
|
|
// It also applies the saved mainwindow settings, if any, and ask the
|
|
// mainwindow to automatically save settings if changed: window size,
|
|
// toolbar position, icon size, etc.
|
|
setupGUI();
|
|
|
|
}
|
|
|
|
mailreader::~mailreader()
|
|
{
|
|
}
|
|
|
|
void mailreader::setupDocks()
|
|
{
|
|
// Setup the core model
|
|
Akonadi::Session *session = new Akonadi::Session( "AkonadiMailReader", this );
|
|
|
|
Akonadi::ChangeRecorder *monitor = new Akonadi::ChangeRecorder( this );
|
|
monitor->setSession(session);
|
|
monitor->setCollectionMonitored( Akonadi::Collection::root() );
|
|
monitor->fetchCollection( true );
|
|
monitor->setMimeTypeMonitored( QLatin1String("message/rfc822"), true );
|
|
monitor->itemFetchScope().fetchPayloadPart( Akonadi::MessagePart::Header );
|
|
|
|
Akonadi::EntityTreeModel *entityModel = new Akonadi::EntityTreeModel( monitor, this );
|
|
entityModel->setItemPopulationStrategy( Akonadi::EntityTreeModel::LazyPopulation );
|
|
|
|
// Create the collection view
|
|
Akonadi::EntityTreeView *collectionView = new Akonadi::EntityTreeView( 0, this );
|
|
collectionView->setSelectionMode( QAbstractItemView::ExtendedSelection );
|
|
|
|
// Setup the message folders collection...
|
|
Akonadi::EntityMimeTypeFilterModel *collectionFilter = new Akonadi::EntityMimeTypeFilterModel( this );
|
|
collectionFilter->setSourceModel( entityModel );
|
|
collectionFilter->addMimeTypeInclusionFilter( Akonadi::Collection::mimeType() );
|
|
collectionFilter->setHeaderGroup( Akonadi::EntityTreeModel::CollectionTreeHeaders );
|
|
|
|
// ... with statistics...
|
|
KPIM::StatisticsProxyModel *statisticsProxyModel = new KPIM::StatisticsProxyModel( this );
|
|
statisticsProxyModel->setToolTipEnabled( true );
|
|
statisticsProxyModel->setExtraColumnsEnabled( false );
|
|
statisticsProxyModel->setSourceModel( collectionFilter );
|
|
|
|
// ... and sortable
|
|
QSortFilterProxyModel *sortModel = new QSortFilterProxyModel( this );
|
|
sortModel->setDynamicSortFilter( true );
|
|
sortModel->setSortCaseSensitivity( Qt::CaseInsensitive );
|
|
sortModel->setSourceModel( statisticsProxyModel );
|
|
|
|
// Use the model
|
|
collectionView->setModel( sortModel );
|
|
|
|
// Now make the message list multi-tab pane
|
|
m_messagePane = new MessageList::Pane( true, entityModel, collectionView->selectionModel(), this );
|
|
connect( m_messagePane, SIGNAL(messageSelected(Akonadi::Item)),
|
|
this, SLOT(slotMessageSelected(Akonadi::Item)) );
|
|
|
|
// Dock the message list view
|
|
QDockWidget *messageListDock = new QDockWidget( i18n("Messages"), this );
|
|
messageListDock->setObjectName( QLatin1String("Messages") );
|
|
messageListDock->setWidget( m_messagePane );
|
|
messageListDock->setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
|
|
addDockWidget( Qt::TopDockWidgetArea, messageListDock );
|
|
|
|
// Dock the folder tree view
|
|
QDockWidget *folderDock = new QDockWidget( i18n("Folders"), this );
|
|
folderDock->setObjectName( QLatin1String("Folders") );
|
|
folderDock->setWidget( collectionView );
|
|
folderDock->setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
|
|
addDockWidget( Qt::LeftDockWidgetArea, folderDock );
|
|
|
|
// Fine tuning on the dock policy (nesting + corners)
|
|
setDockNestingEnabled( true );
|
|
setCorner( Qt::TopLeftCorner, Qt::LeftDockWidgetArea );
|
|
setCorner( Qt::BottomLeftCorner, Qt::LeftDockWidgetArea );
|
|
setCorner( Qt::TopRightCorner, Qt::RightDockWidgetArea );
|
|
setCorner( Qt::BottomRightCorner, Qt::RightDockWidgetArea );
|
|
}
|
|
|
|
void mailreader::setupActions()
|
|
{
|
|
KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollection());
|
|
KStandardAction::preferences(m_view, SLOT(slotConfigure()), actionCollection());
|
|
|
|
KAction *createTab = new KAction(KIcon(QLatin1String("tab-new")),
|
|
i18n("Open a new tab"),
|
|
this);
|
|
actionCollection()->addAction(QLatin1String("new_tab"), createTab);
|
|
connect(createTab, SIGNAL(triggered(bool)),
|
|
m_messagePane, SLOT(createNewTab()));
|
|
|
|
|
|
m_previousMessage = new KAction(i18n("Previous Message"), this);
|
|
actionCollection()->addAction(QLatin1String("previous_message"), m_previousMessage);
|
|
connect(m_previousMessage, SIGNAL(triggered(bool)), SLOT(slotPreviousMessage()));
|
|
m_nextMessage = new KAction(i18n("Next Message"), this);
|
|
actionCollection()->addAction(QLatin1String("next_message"), m_nextMessage);
|
|
connect(m_nextMessage, SIGNAL(triggered(bool)), SLOT(slotNextMessage()));
|
|
}
|
|
|
|
void mailreader::slotMessageSelected( const Akonadi::Item &item )
|
|
{
|
|
// TODO: Use ETM/PartFetcher to cache fetched items.
|
|
|
|
Akonadi::ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob( item, this );
|
|
itemFetchJob->fetchScope().fetchFullPayload( true );
|
|
|
|
connect( itemFetchJob, SIGNAL(itemsReceived(Akonadi::Item::List)), SLOT(itemsReceived(Akonadi::Item::List)) );
|
|
connect( itemFetchJob, SIGNAL(result(KJob*)), SLOT(itemFetchDone(KJob*)) );
|
|
|
|
m_view->showItem( item );
|
|
}
|
|
|
|
void mailreader::itemsReceived(const Akonadi::Item::List &list )
|
|
{
|
|
Q_ASSERT( list.size() == 1 );
|
|
|
|
Akonadi::Item item = list.first();
|
|
|
|
kDebug() << item.payloadData() << item.hasPayload<KMime::Message::Ptr>();
|
|
|
|
if ( !item.hasPayload<KMime::Message::Ptr>() )
|
|
return;
|
|
|
|
m_view->showItem( item );
|
|
}
|
|
|
|
void mailreader::itemFetchDone(KJob *job)
|
|
{
|
|
if (job->error())
|
|
kDebug() << job->errorString();
|
|
}
|
|
|
|
|
|
void mailreader::slotPreviousMessage()
|
|
{
|
|
m_messagePane->selectPreviousMessageItem( MessageList::Core::MessageTypeAny,
|
|
MessageList::Core::ClearExistingSelection,
|
|
true, true );
|
|
}
|
|
|
|
void mailreader::slotNextMessage()
|
|
{
|
|
m_messagePane->selectNextMessageItem( MessageList::Core::MessageTypeAny,
|
|
MessageList::Core::ClearExistingSelection,
|
|
true, true );
|
|
}
|
|
|