/*************************************************************************** chatnotification.cpp - notifies when a contact communicates with the user ------------------- begin : Tuesday April 10 2007 copyright : (C) 2007 by Valerio Pilo email : valerio@kmess.org ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "chatnotification.h" #include "../chat/chat.h" #include "../chat/chatwindow.h" #include "../contact/contactextension.h" #include "../contact/invitedcontact.h" #include "../model/contactlist.h" #include "../network/chatmessage.h" #include "../kmessdebug.h" #include "../currentaccount.h" #include "notificationmanager.h" #include <QPixmap> #include <KNotification> #include <KWindowSystem> // How long a message can be without being cropped away #define MAX_BALLOON_MESSAGE_SIZE 64 // Class constructor ChatNotification::ChatNotification( NotificationManager* manager ) : manager_(manager) { // Connect the activation signal to process notification actions connect( manager_, SIGNAL( eventActivated(NotificationManager::EventSettings,NotificationManager::Buttons) ), this, SLOT ( activate(NotificationManager::EventSettings,NotificationManager::Buttons) ) ); } // Execute the action triggered in a notification void ChatNotification::activate( NotificationManager::EventSettings settings, NotificationManager::Buttons button ) { // The signal wasn't meant for us if( settings.sender != this ) { return; } switch( button ) { case NotificationManager::BUTTON_VIEW_MESSAGE: #ifdef KMESSDEBUG_CHATNOTIFICATION kDebug() << "Raising chat with" << settings.contact->getHandle(); #endif emit raiseChat( static_cast<Chat*>( settings.widget ), true ); break; case NotificationManager::BUTTON_HIDE: #ifdef KMESSDEBUG_CHATNOTIFICATION kDebug() << "Hiding chat notification"; #endif // Do nothing break; default: #ifdef KMESSDEBUG_CHATNOTIFICATION kDebug() << "Invalid button" << button; #endif return; } } // Notify the user about this event (a contact has contacted the user) void ChatNotification::notify( const ChatMessage &message, Chat *chat ) { // End if the event is coming from us instead of from a contact if( ! message.isIncoming() ) { #ifdef KMESSDEBUG_CHATNOTIFICATION kDebug() << "Not displaying a popup for an outgoing message."; #endif return; } // Check the chat pointer, we need it if( ! chat ) { #ifdef KMESSDEBUG_CHATNOTIFICATION kDebug() << "Invalid pointer to chat window."; #endif return; } // Verify if the chat is active, and if so don't notify anything if( KWindowSystem::activeWindow() == chat->getChatWindow()->winId() && chat == chat->getChatWindow()->getCurrentChat() ) { #ifdef KMESSDEBUG_CHATNOTIFICATION kDebug() << "Window is active, skipping."; #endif return; } QString text; int messageType = message.getType(); QString body( message.getBody() ); const QString &handle = message.getContactHandle(); CurrentAccount *currentAccount = CurrentAccount::instance(); ContactBase *contact; Contact *contactDetail = currentAccount->getContactList()->getContactByHandle( handle ); if( contactDetail != 0 ) { if( contactDetail->getExtension()->getDisableNotifications() ) { kDebug() << "The contact: " << handle << " has the notification disabled, skip it"; return; } contact = static_cast<ContactBase*> (contactDetail); } else { contact = currentAccount->getContactByHandle( handle ); } // When the contact doesn't exist, only use the handle if( contact == 0 ) { contact = currentAccount->addInvitedContact( handle ); } const QString& friendlyName( contact->getFriendlyName( STRING_LIST_SETTING_ESCAPED ) ); #ifdef KMESSDEBUG_CHATNOTIFICATION kDebug() << "Contact" << handle; #endif // Truncate the message so it doesn't make the balloon too big if( body.length() > MAX_BALLOON_MESSAGE_SIZE ) { body.truncate( MAX_BALLOON_MESSAGE_SIZE ); body += " ..."; } // Parse the emoticons in the message if( ! message.hasHtmlBody() ) { RichTextParser::parseMsnString( body, true, true, false, false ); } // Set the balloon text to a generic message, which will be overridden with more useful messages, if available switch( messageType ) { case ChatMessage::TYPE_PRESENCE: case ChatMessage::TYPE_NOTIFICATION: text = i18n( "<html>In <b>%1</b>'s chat:<br/>%2</html>", friendlyName, body ); break; case ChatMessage::TYPE_INCOMING: text = i18n( "<html><b>%1</b> says:<br/>'%2'</html>", friendlyName, body ); break; case ChatMessage::TYPE_OFFLINE_INCOMING: text = i18n( "<html><b>%1</b> has sent you an offline message:<br/>'%2'</html>", friendlyName, body ); break; case ChatMessage::TYPE_APPLICATION: case ChatMessage::TYPE_APPLICATION_FILE: text = i18n( "<html>%1's chat requests attention!</html>", friendlyName ); break; case ChatMessage::TYPE_SYSTEM: default: text = i18n( "<html><b>%1</b>:<br/>%2</html>", friendlyName, body ); break; } switch( message.getContentsClass() ) { case ChatMessage::CONTENT_MESSAGE_INK: text = i18n( "<html><b>%1</b> has sent you a handwritten message!</html>", friendlyName ); break; case ChatMessage::CONTENT_NOTIFICATION_NUDGE: text = i18n( "<html><b>%1</b> has sent you a nudge!</html>", friendlyName ); break; case ChatMessage::CONTENT_NOTIFICATION_WINK: text = i18n( "<html><b>%1</b> has sent you a wink!</html>", friendlyName ); break; case ChatMessage::CONTENT_APP_INVITE: switch( messageType ) { case ChatMessage::TYPE_APPLICATION_FILE: text = i18n( "<html><b>%1</b> is sending you a file!</html>", friendlyName ); break; default: text = i18n( "<html><b>%1</b> has sent you an invitation!</html>", friendlyName ); break; } break; case ChatMessage::CONTENT_APP_CANCELED: switch( messageType ) { case ChatMessage::TYPE_APPLICATION_FILE: text = i18n( "<html><b>%1</b> has canceled the file transfer!</html>", friendlyName ); break; default: text = i18n( "<html><b>%1</b>'s activity has been canceled!</html>", friendlyName ); break; } break; case ChatMessage::CONTENT_APP_STARTED: switch( messageType ) { case ChatMessage::TYPE_APPLICATION_FILE: text = i18n( "<html><b>%1</b> has accepted the file transfer!</html>", friendlyName ); break; default: text = i18n( "<html><b>%1</b> has accepted your invitation!</html>", friendlyName ); break; } break; case ChatMessage::CONTENT_APP_ENDED: switch( messageType ) { case ChatMessage::TYPE_APPLICATION_FILE: text = i18n( "<html>The file transfer with <b>%1</b> is done!</html>", friendlyName ); break; default: text = i18n( "<html><b>%1</b>'s activity has ended!</html>", friendlyName ); break; } break; case ChatMessage::CONTENT_APP_FAILED: switch( messageType ) { case ChatMessage::TYPE_APPLICATION_FILE: text = i18n( "<html>The file transfer with <b>%1</b> has failed!</html>", friendlyName ); break; default: text = i18n( "<html><b>%1</b>'s activity has ended with an error!</html>", friendlyName ); break; } break; default: break; } QString eventName; if( message.getContentsClass() == ChatMessage::CONTENT_NOTIFICATION_NUDGE ) { eventName = "nudge"; } else if( messageType == ChatMessage::TYPE_INCOMING && chat->isChatFirstMessage() ) { eventName = "chat start"; } else { eventName = "new message"; } NotificationManager::EventSettings settings; settings.sender = this; settings.widget = chat; settings.contact = contact; settings.buttons = NotificationManager::BUTTON_HIDE | NotificationManager::BUTTON_VIEW_MESSAGE; manager_->notify( eventName, text, settings ); } #include "chatnotification.moc"