/*************************************************************************** currentaccount.cpp - description ------------------- begin : Sun Jan 5 2003 copyright : (C) 2003 by Mike K. Bennett email : mkb137b@hotmail.com ***************************************************************************/ /*************************************************************************** * * * 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 "currentaccount.h" #include <stdio.h> #include <stdlib.h> #include <time.h> #include <qdir.h> #include <qfile.h> #include <qregexp.h> #include <qstringlist.h> #include <qtimer.h> #include <kapplication.h> #include <kdebug.h> #include <klocale.h> #include <kmdcodec.h> #include <kmessagebox.h> #include <kprocess.h> #include <krun.h> #include "kmessdebug.h" #include "contact/contactlist.h" #include "contact/contact.h" #include "contact/invitedcontact.h" // Initialize the instance to zero CurrentAccount* CurrentAccount::instance_(0); // The constructor CurrentAccount::CurrentAccount() : autoreply_(false), contactList_(0), externalPort_(0), loginTime_(0), noEmails_(0), status_("FLN") { } // The destructor CurrentAccount::~CurrentAccount() { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "DESTROYED CurrentAccount " << endl; #endif // Delete all remaining invited contacts invitedContacts_.setAutoDelete(true); invitedContacts_.clear(); instance_ = 0; } // Add an unknown contact to the invited contact list InvitedContact * CurrentAccount::addInvitedContact( const QString &handle, const QString &friendlyName, const uint capabilities ) { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount::addInvitedContact " << handle << endl; #endif #ifdef KMESSTEST ASSERT( ! handle.isEmpty() ); #endif if(getContactByHandle(handle) != 0) { kdWarning() << "CurrentAccount::addInvitedContact: attempted to add contact " << handle << " twice." << endl; return 0; } if(handle.isEmpty()) { return 0; } // Create the contact InvitedContact *contact = new InvitedContact( handle, friendlyName, capabilities ); invitedContacts_.append( contact ); // Connect signals. // Remove the contact when it left all chats. connect( contact, SIGNAL( leftAllChats(ContactBase*) ), this, SLOT ( slotInvitedContactLeftAllChats(ContactBase*) )); return contact; } // Receive notice that some emails were added or deleted void CurrentAccount::changeNoEmails( int change ) { #ifdef KMESSTEST int oldNoEmails = noEmails_; #endif setNoEmails( noEmails_ + change ); #ifdef KMESSTEST ASSERT( ( noEmails_ == ( oldNoEmails + change ) ) || ( noEmails_ == 0 ) ); #endif } // Copy an account void CurrentAccount::copyAccount( const Account *account ) { // Do the ancestor's copying Account::copyAccount( account ); } // Delete the instance of the contact list void CurrentAccount::destroy() { delete instance_; instance_ = 0; } // Return whether or not to autoreply to messages bool CurrentAccount::getAutoreply() const { return autoreply_; } // Return the compose command. const QString& CurrentAccount::getComposeCommand() const { return composeCommand_; } // Return a contact by handle ContactBase * CurrentAccount::getContactByHandle(const QString &handle) const { // Return value can't be const, some objects (like ContactFrame) // want to connect to the object signals. // First see if the contact is listed in our MSN contact list. ContactBase *contact = 0; if(! KMESS_NULL(contactList_)) { contact = contactList_->getContactByHandle(handle); } // Next, see if the contact was invited to a chat. if(contact == 0) { contact = getInvitedContactByHandle(handle); } return contact; } // Return a contact's name by handle QString CurrentAccount::getContactFriendlyNameByHandle(const QString &handle) const { ContactBase *contact = getContactByHandle(handle); if( contact == 0 ) { return QString::null; } else { return contact->getFriendlyName(); } } // Return the contact last dragged const ContactBase* CurrentAccount::getContactLastDragged() const { // currently a stub return 0; } // Return the contact list as read-only const ContactList * CurrentAccount::getContactList() const { return contactList_; } // Return the email URL const QString& CurrentAccount::getEmailUrl() const { return emailUrl_; } // Return the external IP const QString& CurrentAccount::getExternalIp() const { return externalIp_; } // Return the external port uint CurrentAccount::getExternalPort() const { return externalPort_; } // Return the inbox command. const QString& CurrentAccount::getInboxCommand() const { return inboxCommand_; } // Find an invited contact by handle InvitedContact * CurrentAccount::getInvitedContactByHandle(const QString &handle) const { QPtrListIterator<ContactBase> it( invitedContacts_ ); while( it.current() != 0 ) { if( it.current()->getHandle() == handle ) { return static_cast<InvitedContact*>( it.current() ); } ++it; } return 0; } // Return the local IP. const QString& CurrentAccount::getLocalIp() const { return localIp_; } // Return the number of email in the inbox int CurrentAccount::getNoEmails() const { return noEmails_; } // Read property of int sessionLength. int CurrentAccount::getSessionLength() const { time_t currentTimeT, t; int currentTime, elapsedTime; // int sessionLength; currentTimeT = time(&t); currentTime = static_cast<int>(currentTimeT); // Calculate the time the user's been connected by local reckoning elapsedTime = currentTime - loginTime_; return elapsedTime; } // Return the user's staus QString CurrentAccount::getStatus() const { return status_; } // Return whether the given contact exists in the contact list. bool CurrentAccount::hasContactInList(const QString &handle) const { return ( contactList_->getContactByHandle(handle) != 0 ); } // Return a singleton instance of the current account CurrentAccount* CurrentAccount::instance() { // If the instance is null, create a new current account and return that. if ( instance_ == 0 ) { instance_ = new CurrentAccount(); } return instance_; } // Open mail with the given command, url, and folder void CurrentAccount::openMail( const QString& command, const QString& folder, const QString& url ) { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount::openMail()" << endl; #endif if( getUseHotmail() ) { if( url == "" ) { KMessageBox::error( 0, i18n( "This account does not have an Hotmail inbox!" ) ); return; } QString login = getHandle(); QString sl; sl.sprintf( "%d", getSessionLength() ); KMD5 context( authorization_ + sl + getPassword() ); QString credentials = context.hexDigest(); QString linkUrl = url + "&mode=ttl" + "&login=" + login.left( login.find("@") ) + "&username=" + login + "&sid=" + sid_ + "&id=" + command + "&sl=" + sl + "&rru=" + folder + "&auth=" + authorization_ + "&creds=" + credentials + "&svc=mail" + "&js=yes"; new KRun( linkUrl ); } else { startProcess( getEmailCommand() ); } } // Open e-mail at the compose page with the given contact handle void CurrentAccount::openMailAtCompose( QString contactHandle ) { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount::openMailAtCompose()" << endl; #endif QString contactEmail, folder; if( getUseHotmail() ) { // The contact's email has to have the @ and . changed. contactEmail = contactHandle.replace( QRegExp( "@" ), "%40" ); contactEmail = contactEmail.replace( QRegExp( "\\." ), "%2e" ); // For a compose message, the folder had to include the address of the contact folder = composeFolder_ + "?mailto=1&to=" + contactEmail; // Launch the html openMail( composeCommand_, folder, composeUrl_ ); } else { startProcess( getEmailCommand() + " " + contactHandle ); } } // Open e-mail at the user's inbox void CurrentAccount::openMailAtInbox() { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount::openMailAtInbox()" << endl; #endif if( getUseHotmail() ) { openMail( inboxCommand_, inboxFolder_, inboxUrl_ ); } else { startProcess( getEmailCommand() ); } } // Set some account information void CurrentAccount::setAccountInformation( QString authorization, QString preferredEmail, QString sid, bool emailSupported, QString externalIp, uint externalPort, QString localIp) { time_t currentTime, t; #ifdef KMESSTEST bool goodSid; sid.toInt(&goodSid); ASSERT( goodSid ); #endif authorization_ = authorization; preferredEmail_ = preferredEmail; sid_ = sid; externalIp_ = externalIp; externalPort_ = externalPort; localIp_ = localIp; // protected method call setEmailSupported(emailSupported); // Set the local login time by getting the current time currentTime = time(&t); loginTime_ = static_cast<uint>(currentTime); } // Set whether or not to autoreply to a contact's chat message. void CurrentAccount::setAutoreply(bool autoreply) { autoreply_ = autoreply; } // Set compose properties void CurrentAccount::setComposeInformation( QString command, QString folder, QString url ) { composeCommand_ = command; composeFolder_ = folder; composeUrl_ = url; } // Set inbox properties. void CurrentAccount::setInboxInformation( QString command, QString folder, QString url ) { inboxCommand_ = command; inboxFolder_ = folder; inboxUrl_ = url; } // Store the contact list, maintained by the MsnNotificationConnection class. // Allows other classes to access the contact list from this central class. void CurrentAccount::setContactList(const ContactList *contactList) { contactList_ = contactList; } // Set initial email information void CurrentAccount::setInitialEmailInformation( int noEmailsInInbox, int noEmailsInOtherFolders ) { #ifdef KMESSTEST ASSERT( noEmails_ == 0 ); ASSERT( noEmailsInInbox >= 0 ); ASSERT( noEmailsInOtherFolders >= 0 ); #else Q_UNUSED( noEmailsInOtherFolders ); // Avoid compiler warning #endif setNoEmails( noEmailsInInbox ); } // Set the e-mail post url void CurrentAccount::setEmailUrl( QString postUrl ) { emailUrl_ = postUrl; } // Set the number of emails void CurrentAccount::setNoEmails( int noEmails ) { #ifdef KMESSTEST ASSERT( noEmails >= 0 ); #endif noEmails_ = noEmails; if ( noEmails_ < 0 ) { noEmails_ = 0; } emit changedNoEmails(); } // Set the user's status void CurrentAccount::setStatus( QString status ) { #ifdef KMESSTEST ASSERT( ( status == "AWY" ) || ( status == "BRB" ) || ( status == "BSY" ) || ( status == "FLN" ) || ( status == "HDN" ) || ( status == "IDL" ) || ( status == "LUN" ) || ( status == "NLN" ) || ( status == "PHN" ) ); #endif if ( ( status == "AWY" ) || ( status == "BRB" ) || ( status == "BSY" ) || ( status == "FLN" ) || ( status == "HDN" ) || ( status == "IDL" ) || ( status == "LUN" ) || ( status == "NLN" ) || ( status == "PHN" ) ) { QString oldStatus = status_; status_ = status; #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount: Status set to " << status_ << "." << endl; #endif emit changedStatus(); if( status_ != oldStatus ) { // Check if the contact went offline if( status_ == "FLN" ) { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount: Account went offline." << endl; #endif emit accountOffline(); } // Check if the account went invisible if( status == "HDN" ) { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount: Account went invisible." << endl; #endif emit accountInvisible(); } // Check if the contact went online else if( oldStatus == "FLN" || oldStatus == "HDN" ) { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount: Account went online." << endl; #endif emit accountOnline(); } } } } // An invited contact left all chats. void CurrentAccount::slotInvitedContactLeftAllChats( ContactBase *contact ) { if(KMESS_NULL(contact)) return; #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount: invited contact " << contact->getHandle() << " left all chats, delete contact." << endl; #endif // Remove from list bool removed = invitedContacts_.removeRef(contact); if( ! removed ) { kdWarning() << "CurrentAccount: could not remove invited contact '" << contact->getHandle() << "' from the list!" << endl; } // Delete after all slots are processed. contact->deleteLater(); } // Start a process void CurrentAccount::startProcess( QString command ) { #ifdef KMESSDEBUG_CURRENTACCOUNT kdDebug() << "CurrentAccount::startProcess: starting '" << getEmailCommand() << "'." << endl; #endif // Construct a command by simply attaching a the email address to the program name KProcess *process = new KProcess(); // auto deletes // Add all parameters separately QStringList commandItems = QStringList::split(" ", command, false); for( QStringList::Iterator it = commandItems.begin(); it != commandItems.end(); ++it ) { *process << *it; } // Launch it bool started = process->start(KProcess::DontCare); if(! started) { kdWarning() << "Failed to start '" << getEmailCommand() << "'!" << endl; } } #include "currentaccount.moc"