25 #include "util/mailutil.h"
26 #include "mailcommon/kernel/mailkernel.h"
27 #include "mailcommon/folder/foldertreeview.h"
28 #include "mailcommon/collectionpage/newmailnotifierattribute.h"
30 #include <kiconloader.h>
31 #include <kcolorscheme.h>
32 #include <kwindowsystem.h>
37 #include <KActionMenu>
38 #include <KActionCollection>
42 #include <Akonadi/ChangeRecorder>
43 #include <Akonadi/EntityTreeModel>
44 #include <Akonadi/CollectionModel>
46 using namespace MailCommon;
60 KMSystemTray::KMSystemTray(
QObject *parent)
62 mDesktopOfMainWin( 0 ),
65 mShowUnreadMailCount( true ),
66 mIconNotificationsEnabled( true ),
67 mNewMessagesPopup( 0 ),
70 kDebug() <<
"Initting systray";
71 setToolTipTitle( i18n(
"KMail") );
72 setToolTipIconByName( QLatin1String(
"kmail") );
73 setIconByName( QLatin1String(
"kmail") );
74 mIcon = KIcon( QLatin1String(
"mail-unread-new") );
78 QWidget * mainWin = mainWidget->window();
80 mDesktopOfMainWin = KWindowSystem::windowInfo( mainWin->winId(),
81 NET::WMDesktop ).desktop();
86 connect(
this, SIGNAL(activateRequested(
bool,QPoint)),
87 this, SLOT(slotActivated()) );
88 connect( contextMenu(), SIGNAL(aboutToShow()),
89 this, SLOT(slotContextMenuAboutToShow()) );
91 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)), SLOT(slotCollectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)) );
93 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)),
this, SLOT(initListOfCollection()) );
94 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionRemoved(Akonadi::Collection)),
this, SLOT(initListOfCollection()) );
95 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionSubscribed(Akonadi::Collection,Akonadi::Collection)),SLOT(initListOfCollection()) );
96 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionUnsubscribed(Akonadi::Collection)),SLOT(initListOfCollection()) );
98 initListOfCollection();
102 bool KMSystemTray::buildPopupMenu()
109 if ( !contextMenu() ) {
110 setContextMenu(
new KMenu() );
113 contextMenu()->clear();
115 contextMenu()->addTitle(qApp->windowIcon(), i18n(
"KMail"));
117 if ( ( action = mainWidget->
action(QLatin1String(
"check_mail")) ) )
118 contextMenu()->addAction( action );
119 if ( ( action = mainWidget->
action(QLatin1String(
"check_mail_in")) ) )
120 contextMenu()->addAction( action );
123 contextMenu()->addAction( mSendQueued );
126 contextMenu()->addSeparator();
127 if ( ( action = mainWidget->
action(QLatin1String(
"new_message")) ) )
128 contextMenu()->addAction( action );
129 if ( ( action = mainWidget->
action(QLatin1String(
"kmail_configure_kmail")) ) )
130 contextMenu()->addAction( action );
131 contextMenu()->addSeparator();
132 if ( (action = mainWidget->
action(QLatin1String(
"akonadi_work_offline")) ) )
133 contextMenu()->addAction( action );
134 contextMenu()->addSeparator();
136 if ( ( action = actionCollection()->action(QLatin1String(
"file_quit")) ) )
137 contextMenu()->addAction( action );
148 if (mShowUnreadMailCount == showUnreadCount)
150 mShowUnreadMailCount = showUnreadCount;
156 if (newMode == mMode)
159 kDebug() <<
"Setting systray mMode to" << newMode;
163 case GlobalSettings::EnumSystemTrayPolicy::ShowAlways:
164 setStatus( KStatusNotifierItem::Active );
166 case GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread:
167 setStatus( mCount > 0 ? KStatusNotifierItem::Active : KStatusNotifierItem::Passive );
170 kDebug() <<
"Unknown systray mode" << mMode;
184 void KMSystemTray::updateCount()
186 if (mCount == 0 || !mIconNotificationsEnabled) {
187 setIconByName( QLatin1String(
"kmail") );
190 if (mShowUnreadMailCount) {
191 const int overlaySize = KIconLoader::SizeSmallMedium;
193 const QString countString = QString::number( mCount );
194 QFont countFont = KGlobalSettings::generalFont();
195 countFont.setBold(
true);
199 float countFontSize = countFont.pointSizeF();
200 QFontMetrics qfm( countFont );
201 const int width = qfm.width( countString );
202 if ( width > (overlaySize - 2) ) {
203 countFontSize *= float( overlaySize - 2 ) / float( width );
204 countFont.setPointSizeF( countFontSize );
208 QPixmap overlayPixmap( overlaySize, overlaySize );
209 overlayPixmap.fill( Qt::transparent );
211 QPainter p( &overlayPixmap );
212 p.setFont( countFont );
213 KColorScheme scheme( QPalette::Active, KColorScheme::View );
215 p.setBrush( Qt::NoBrush );
216 p.setPen( scheme.foreground( KColorScheme::LinkText ).color() );
218 p.drawText( overlayPixmap.rect(),Qt::AlignCenter, countString );
221 QPixmap iconPixmap = mIcon.pixmap(overlaySize, overlaySize);
223 QPainter pp(&iconPixmap);
224 pp.drawPixmap(0, 0, overlayPixmap);
227 setIconByPixmap( iconPixmap );
229 setIconByPixmap( mIcon );
235 if ( enabled != mIconNotificationsEnabled ) {
236 mIconNotificationsEnabled = enabled;
245 void KMSystemTray::slotActivated()
251 QWidget *mainWin = mainWidget->window();
255 KWindowInfo cur = KWindowSystem::windowInfo( mainWin->winId(), NET::WMDesktop );
257 const int currentDesktop = KWindowSystem::currentDesktop();
258 const bool wasMinimized = cur.isMinimized();
261 mDesktopOfMainWin = cur.desktop();
263 if (wasMinimized && (currentDesktop != mDesktopOfMainWin) && ( mDesktopOfMainWin == NET::OnAllDesktops ))
264 KWindowSystem::setOnDesktop(mainWin->winId(), currentDesktop);
266 if ( mDesktopOfMainWin == NET::OnAllDesktops )
267 KWindowSystem::setOnAllDesktops( mainWin->winId(), true );
269 KWindowSystem::activateWindow( mainWin->winId() );
275 void KMSystemTray::slotContextMenuAboutToShow()
279 if ( !buildPopupMenu() ) {
283 if ( mNewMessagesPopup != 0 ) {
284 contextMenu()->removeAction( mNewMessagesPopup->menuAction() );
285 delete mNewMessagesPopup;
286 mNewMessagesPopup = 0;
288 mNewMessagesPopup =
new KMenu();
289 fillFoldersMenu( mNewMessagesPopup,
kmkernel->treeviewModelSelection() );
291 connect( mNewMessagesPopup, SIGNAL(triggered(QAction*)),
this,
292 SLOT(slotSelectCollection(QAction*)) );
296 mNewMessagesPopup->setTitle( i18n(
"New Messages In") );
297 contextMenu()->insertAction( mSendQueued, mNewMessagesPopup->menuAction() );
301 void KMSystemTray::fillFoldersMenu(
QMenu *menu,
const QAbstractItemModel *model,
const QString &parentName,
const QModelIndex &parentIndex )
303 const int rowCount = model->rowCount( parentIndex );
304 for (
int row = 0; row < rowCount; ++row ) {
305 const QModelIndex index = model->index( row, 0, parentIndex );
306 const Akonadi::Collection collection = model->data( index, Akonadi::CollectionModel::CollectionRole ).value<Akonadi::Collection>();
308 if ( !excludeFolder( collection ) ) {
309 Akonadi::CollectionStatistics statistics = collection.statistics();
310 count = qMax( 0LL, statistics.unreadCount() );
312 if (ignoreNewMailInFolder(collection)) {
319 QString label = parentName.isEmpty() ? QString() : QString(parentName + QLatin1String(
"->"));
320 label += model->data( index ).toString();
321 label.replace( QLatin1Char(
'&' ), QLatin1String(
"&&" ) );
324 QAction* action = menu->addAction( label );
325 action->setData( collection.id() );
327 if ( model->rowCount( index ) > 0 ) {
328 fillFoldersMenu( menu, model, label, index );
338 QWidget *mainWin = mainWidget->window();
341 mDesktopOfMainWin = KWindowSystem::windowInfo( mainWin->winId(),
342 NET::WMDesktop ).desktop();
344 KWindowSystem::minimizeWindow( mainWin->winId() );
349 void KMSystemTray::initListOfCollection()
352 const QAbstractItemModel *model =
kmkernel->entityTreeModel();
353 if (model->rowCount() == 0) {
354 QTimer::singleShot(1000,
this,SLOT(initListOfCollection()));
359 if ( mMode == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread ) {
360 if (status() == KStatusNotifierItem::Passive && (mCount > 0)) {
361 setStatus( KStatusNotifierItem::Active );
362 }
else if ( status() == KStatusNotifierItem::Active && (mCount == 0) ) {
363 setStatus( KStatusNotifierItem::Passive );
371 void KMSystemTray::unreadMail(
const QAbstractItemModel *model,
const QModelIndex& parentIndex )
373 const int rowCount = model->rowCount( parentIndex );
374 for (
int row = 0; row < rowCount; ++row ) {
375 const QModelIndex index = model->index( row, 0, parentIndex );
376 const Akonadi::Collection collection = model->data( index, Akonadi::CollectionModel::CollectionRole ).value<Akonadi::Collection>();
378 if ( !excludeFolder( collection ) ) {
380 const Akonadi::CollectionStatistics statistics = collection.statistics();
381 const qint64 count = qMax( 0LL, statistics.unreadCount() );
384 if (!ignoreNewMailInFolder(collection)) {
389 if ( model->rowCount( index ) > 0 ) {
390 unreadMail( model, index );
394 setToolTipSubTitle( mCount == 0 ? i18n(
"There are no unread messages")
395 : i18np(
"1 unread message",
396 "%1 unread messages",
402 return ( mCount != 0 );
405 void KMSystemTray::slotSelectCollection(QAction *act)
407 const Akonadi::Collection::Id
id = act->data().value<Akonadi::Collection::Id>();
408 kmkernel->selectCollectionFromId(
id );
412 QWidget *mainWin = mainWidget->window();
413 if ( mainWin && !mainWin->isVisible() )
419 initListOfCollection();
422 void KMSystemTray::slotCollectionStatisticsChanged( Akonadi::Collection::Id
id,
const Akonadi::CollectionStatistics & )
426 if ( CommonKernel->outboxCollectionFolder().id() ==
id ||
427 CommonKernel->sentCollectionFolder().id() ==
id ||
428 CommonKernel->templatesCollectionFolder().id() ==
id ||
429 CommonKernel->trashCollectionFolder().id() ==
id ||
430 CommonKernel->draftsCollectionFolder().id() == id ) {
433 initListOfCollection();
436 bool KMSystemTray::excludeFolder(
const Akonadi::Collection& collection )
const
438 if (!collection.isValid()) {
441 if (!collection.contentMimeTypes().contains(KMime::Message::mimeType())) {
444 if ( CommonKernel->outboxCollectionFolder() == collection ||
445 CommonKernel->sentCollectionFolder() == collection ||
446 CommonKernel->templatesCollectionFolder() == collection ||
447 CommonKernel->trashCollectionFolder() == collection ||
448 CommonKernel->draftsCollectionFolder() == collection ) {
452 if ( MailCommon::Util::isVirtualCollection( collection ) )
457 bool KMSystemTray::ignoreNewMailInFolder(
const Akonadi::Collection &collection)
459 if ( collection.hasAttribute<NewMailNotifierAttribute>() ) {
460 if (collection.attribute<NewMailNotifierAttribute>()->ignoreNewMail()) {
468 #include "kmsystemtray.moc"
QAction * action(const QString &name)
~KMSystemTray()
destructor
void setSystrayIconNotificationsEnabled(bool enable)
Use this method to disable any systray icon changing.
bool hasUnreadMail() const
void setShowUnreadCount(bool showUnreadCount)
KAction * sendQueuedAction() const
KActionMenu * sendQueueViaMenu() const