25 #include "util/mailutil.h"
26 #include "mailcommon/kernel/mailkernel.h"
27 #include "mailcommon/folder/foldertreeview.h"
28 #include "mailcommon/collectionpage/attributes/newmailnotifierattribute.h"
30 #include <kiconloader.h>
31 #include <kcolorscheme.h>
32 #include <kwindowsystem.h>
35 #include <KLocalizedString>
37 #include <KActionMenu>
39 #include <KActionCollection>
43 #include <Akonadi/ChangeRecorder>
44 #include <Akonadi/EntityTreeModel>
45 #include <Akonadi/CollectionModel>
46 #include <Akonadi/EntityMimeTypeFilterModel>
48 using namespace MailCommon;
62 KMSystemTray::KMSystemTray(
QObject *parent)
64 mDesktopOfMainWin( 0 ),
67 mShowUnreadMailCount( true ),
68 mIconNotificationsEnabled( true ),
69 mNewMessagesPopup( 0 ),
72 kDebug() <<
"Initting systray";
73 setToolTipTitle( i18n(
"KMail") );
82 mDesktopOfMainWin = KWindowSystem::windowInfo( mainWin->
winId(),
83 NET::WMDesktop ).desktop();
88 connect( KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
this, SLOT(slotGeneralPaletteChanged()));
89 connect( KGlobalSettings::self(), SIGNAL(kdisplayFontChanged()),
this, SLOT(slotGeneralFontChanged()) );
91 connect(
this, SIGNAL(activateRequested(
bool,
QPoint)),
92 this, SLOT(slotActivated()) );
93 connect( contextMenu(), SIGNAL(aboutToShow()),
94 this, SLOT(slotContextMenuAboutToShow()) );
96 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)), SLOT(slotCollectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)) );
98 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)),
this, SLOT(initListOfCollection()) );
99 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionRemoved(Akonadi::Collection)),
this, SLOT(initListOfCollection()) );
100 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionSubscribed(Akonadi::Collection,Akonadi::Collection)),SLOT(initListOfCollection()) );
101 connect(
kmkernel->folderCollectionMonitor(), SIGNAL(collectionUnsubscribed(Akonadi::Collection)),SLOT(initListOfCollection()) );
103 initListOfCollection();
107 bool KMSystemTray::buildPopupMenu()
110 if ( !mainWidget ||
kmkernel->shuttingDown() ) {
114 if ( !contextMenu() ) {
115 setContextMenu(
new KMenu() );
118 contextMenu()->clear();
120 contextMenu()->addTitle(qApp->windowIcon(), i18n(
"KMail"));
123 contextMenu()->addAction( action );
125 contextMenu()->addAction( action );
128 contextMenu()->addAction( mSendQueued );
131 contextMenu()->addSeparator();
133 contextMenu()->addAction( action );
135 contextMenu()->addAction( action );
136 contextMenu()->addSeparator();
138 contextMenu()->addAction( action );
139 contextMenu()->addSeparator();
141 if ( ( action = actionCollection()->action(
QLatin1String(
"file_quit")) ) )
142 contextMenu()->addAction( action );
153 if (mShowUnreadMailCount == showUnreadCount)
155 mShowUnreadMailCount = showUnreadCount;
161 if (newMode == mMode)
164 kDebug() <<
"Setting systray mMode to" << newMode;
168 case GlobalSettings::EnumSystemTrayPolicy::ShowAlways:
169 setStatus( KStatusNotifierItem::Active );
171 case GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread:
172 setStatus( mCount > 0 ? KStatusNotifierItem::Active : KStatusNotifierItem::Passive );
175 kDebug() <<
"Unknown systray mode" << mMode;
184 void KMSystemTray::slotGeneralFontChanged()
189 void KMSystemTray::slotGeneralPaletteChanged()
191 const KColorScheme scheme( QPalette::Active, KColorScheme::View );
192 mTextColor = scheme.foreground( KColorScheme::LinkText ).color();
202 void KMSystemTray::updateCount()
204 if (mCount == 0 || !mIconNotificationsEnabled) {
208 if (mShowUnreadMailCount) {
209 int overlaySize = KIconLoader::SizeSmallMedium;
210 if (!mIcon.availableSizes().isEmpty()) {
211 overlaySize = mIcon.availableSizes().at(0).width();
215 QFont countFont = KGlobalSettings::generalFont();
222 const int width = qfm.width( countString );
223 if ( width > (overlaySize - 2) ) {
224 countFontSize *= float( overlaySize - 2 ) / float( width );
229 QPixmap overlayPixmap( overlaySize, overlaySize );
230 overlayPixmap.fill( Qt::transparent );
233 p.setFont( countFont );
235 slotGeneralPaletteChanged();
238 p.setBrush( Qt::NoBrush );
239 p.setPen( mTextColor );
241 p.drawText( overlayPixmap.rect(),Qt::AlignCenter, countString );
244 QPixmap iconPixmap = mIcon.pixmap(overlaySize, overlaySize);
247 pp.drawPixmap(0, 0, overlayPixmap);
250 setIconByPixmap( iconPixmap );
252 setIconByPixmap( mIcon );
258 if ( enabled != mIconNotificationsEnabled ) {
259 mIconNotificationsEnabled = enabled;
268 void KMSystemTray::slotActivated()
278 KWindowInfo cur = KWindowSystem::windowInfo( mainWin->
winId(), NET::WMDesktop );
280 const int currentDesktop = KWindowSystem::currentDesktop();
281 const bool wasMinimized = cur.isMinimized();
284 mDesktopOfMainWin = cur.desktop();
286 if (wasMinimized && (currentDesktop != mDesktopOfMainWin) && ( mDesktopOfMainWin == NET::OnAllDesktops ))
287 KWindowSystem::setOnDesktop(mainWin->
winId(), currentDesktop);
289 if ( mDesktopOfMainWin == NET::OnAllDesktops )
290 KWindowSystem::setOnAllDesktops( mainWin->
winId(), true );
292 KWindowSystem::activateWindow( mainWin->
winId() );
298 void KMSystemTray::slotContextMenuAboutToShow()
302 if ( !buildPopupMenu() ) {
306 if ( mNewMessagesPopup != 0 ) {
307 contextMenu()->removeAction( mNewMessagesPopup->
menuAction() );
308 delete mNewMessagesPopup;
309 mNewMessagesPopup = 0;
311 mNewMessagesPopup =
new KMenu();
312 fillFoldersMenu( mNewMessagesPopup,
kmkernel->treeviewModelSelection() );
314 connect( mNewMessagesPopup, SIGNAL(triggered(
QAction*)),
this,
315 SLOT(slotSelectCollection(
QAction*)) );
319 mNewMessagesPopup->
setTitle( i18n(
"New Messages In") );
320 contextMenu()->insertAction( mSendQueued, mNewMessagesPopup->
menuAction() );
326 const int rowCount = model->
rowCount( parentIndex );
327 for (
int row = 0; row < rowCount; ++row ) {
329 const Akonadi::Collection collection = model->
data( index, Akonadi::CollectionModel::CollectionRole ).
value<Akonadi::Collection>();
331 if ( !excludeFolder( collection ) ) {
332 Akonadi::CollectionStatistics statistics = collection.statistics();
333 count = qMax( 0LL, statistics.unreadCount() );
335 if (ignoreNewMailInFolder(collection)) {
348 action->
setData( collection.id() );
350 if ( model->
rowCount( index ) > 0 ) {
351 fillFoldersMenu( menu, model, label, index );
364 mDesktopOfMainWin = KWindowSystem::windowInfo( mainWin->
winId(),
365 NET::WMDesktop ).desktop();
367 KWindowSystem::minimizeWindow( mainWin->
winId() );
372 void KMSystemTray::initListOfCollection()
382 if ( mMode == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread ) {
383 if (status() == KStatusNotifierItem::Passive && (mCount > 0)) {
384 setStatus( KStatusNotifierItem::Active );
385 }
else if ( status() == KStatusNotifierItem::Active && (mCount == 0) ) {
386 setStatus( KStatusNotifierItem::Passive );
396 const int rowCount = model->
rowCount( parentIndex );
397 for (
int row = 0; row < rowCount; ++row ) {
399 const Akonadi::Collection collection = model->
data( index, Akonadi::CollectionModel::CollectionRole ).
value<Akonadi::Collection>();
401 if ( !excludeFolder( collection ) ) {
403 const Akonadi::CollectionStatistics statistics = collection.statistics();
404 const qint64 count = qMax( 0LL, statistics.unreadCount() );
407 if (!ignoreNewMailInFolder(collection)) {
412 if ( model->
rowCount( index ) > 0 ) {
413 unreadMail( model, index );
417 setToolTipSubTitle( mCount == 0 ? i18n(
"There are no unread messages")
418 : i18np(
"1 unread message",
419 "%1 unread messages",
425 return ( mCount != 0 );
428 void KMSystemTray::slotSelectCollection(
QAction *act)
430 const Akonadi::Collection::Id
id = act->
data().
value<Akonadi::Collection::Id>();
431 kmkernel->selectCollectionFromId(
id );
442 initListOfCollection();
445 void KMSystemTray::slotCollectionStatisticsChanged( Akonadi::Collection::Id
id,
const Akonadi::CollectionStatistics & )
449 if ( CommonKernel->outboxCollectionFolder().id() ==
id ||
450 CommonKernel->sentCollectionFolder().id() ==
id ||
451 CommonKernel->templatesCollectionFolder().id() ==
id ||
452 CommonKernel->trashCollectionFolder().id() ==
id ||
453 CommonKernel->draftsCollectionFolder().id() == id ) {
456 initListOfCollection();
459 bool KMSystemTray::excludeFolder(
const Akonadi::Collection& collection )
const
461 if (!collection.isValid()) {
464 if (!collection.contentMimeTypes().contains(KMime::Message::mimeType())) {
467 if ( CommonKernel->outboxCollectionFolder() == collection ||
468 CommonKernel->sentCollectionFolder() == collection ||
469 CommonKernel->templatesCollectionFolder() == collection ||
470 CommonKernel->trashCollectionFolder() == collection ||
471 CommonKernel->draftsCollectionFolder() == collection ) {
475 if ( MailCommon::Util::isVirtualCollection( collection ) )
480 bool KMSystemTray::ignoreNewMailInFolder(
const Akonadi::Collection &collection)
482 if ( collection.hasAttribute<NewMailNotifierAttribute>() ) {
483 if (collection.attribute<NewMailNotifierAttribute>()->ignoreNewMail()) {
QAction * action(const QString &name)
virtual int rowCount(const QModelIndex &parent) const =0
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
~KMSystemTray()
destructor
void setSystrayIconNotificationsEnabled(bool enable)
Use this method to disable any systray icon changing.
void setBold(bool enable)
QString number(int n, int base)
virtual QVariant data(const QModelIndex &index, int role) const =0
void setData(const QVariant &userData)
bool hasUnreadMail() const
KActionMenuTransport * sendQueueViaMenu() const
void setPointSizeF(qreal pointSize)
QString & replace(int position, int n, QChar after)
void setShowUnreadCount(bool showUnreadCount)
KAction * sendQueuedAction() const