Logo Search packages:      
Sourcecode: kmess version File versions

kmess.cpp

/***************************************************************************
                          kmess.cpp  -  description
                             -------------------
    begin                : Sun Jan  5 15:18:36 CST 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 "kmess.h"

#include <qdir.h>

#include <kaction.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klistview.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kpopupmenu.h>
#include <krun.h>
#include <kstandarddirs.h>
#include <kurl.h>

#if KDE_IS_VERSION(3,2,0)
#include <kinputdialog.h>
#else
#include <klineeditdlg.h>
#endif

#include "actions/accountaction.h"
#include "chat/chatmaster.h"
#include "chat/chatwindow.h"
#include "contact/contact.h"
#include "contact/contactlist.h"
#include "contact/group.h"
#include "dialogs/contactaddeduserdialoginterface.h"
#include "dialogs/contactaddeduserdialog.h"
#include "dialogs/awaymessagedialog.h"
#include "dialogs/networkwindow.h"
#include "dialogs/transferwindow.h"
#include "network/msnnotificationconnection.h"
#include "notification/chatnotification.h"
#include "notification/contactofflinenotification.h"
#include "notification/contactonlinenotification.h"
#include "notification/emailnotification.h"
#include "notification/balloonwidget.h"
#include "settings/settingsdialog.h"
#include "account.h"
#include "autologinview.h"
#include "currentaccount.h"
#include "idletimer.h"
#include "initialview.h"
#include "kmessdebug.h"
#include "kmessinterface.h"
#include "kmessview.h"
#include "nowlisteningclient.h"
#include "systemtraywidget.h"

// The constructor
KMess::KMess(QWidget *parent, const char *name)
 : KMessInterface(parent, name),
   autologinView_(0),
   chatMaster_(0),
   chatNotification_(0),
   contactOfflineNotification_(0),
   contactOnlineNotification_(0),
   currentStatus_("FLN"),
   emailNotification_(0),
   idleTimer_(0),
   initialized_(false),
   initialView_(0),
   msnNotificationConnection_(0),
   view_(0)
{

}



// The destructor
KMess::~KMess()
{
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess destructor: shutting down KMess..." << endl;
#endif

  Account *account;

  /*
   * The destructor is called after closeEvent(),
   * when KMess is quit by the user.
   *
   * If the KDE session ends, the destructor won't be called.
   * only saveProperties() will be called, and the execution ends.
   */


  // Saving properties manually.
  saveProperties( kapp->config() );

  // Delete all chat windows
  if(chatMaster_ != 0)
  {
    chatMaster_->disconnected();
    chatMaster_->deleteLater();
    chatMaster_ = 0;
  }

  // Disconnect main connection so views can clean up/save properties.
  if(msnNotificationConnection_->isConnected())
  {
    // Make sure KMess::disconnected() does attempt to update
    // the user interface when we're trying to kill it
    disconnect(msnNotificationConnection_, SIGNAL(disconnected()), this, SLOT(disconnected()) );

    // This also destroys all contacts
    msnNotificationConnection_->closeConnection();
  }

  // Delete other created objects
  delete idleTimer_;
  delete view_;
  delete initialView_;
  delete autologinView_;
  delete balloonWidget_;
  delete chatNotification_;
  delete contactOfflineNotification_;
  delete contactOnlineNotification_;
  delete emailNotification_;
  delete systemTrayWidget_;
  delete msnNotificationConnection_;
  CurrentAccount::destroy();

  // Delete the accounts
  for ( account = accounts_.first(); account; account = accounts_.next() )
  {
    delete account;
  }
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "DESTROYED KMess" << endl;
#endif
}



// The account changed it's status to invisible
void KMess::accountInvisible()
{
  // Disable the now listening detection
  nowListeningClient_->setEnabled( false );

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess: account went invisible, disabled now listening detection." << endl;
#endif
}



// The account changed it's status to offline
void KMess::accountOffline()
{
  // Disable the now listening detection
  nowListeningClient_->setEnabled( false );

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess: account went offline, disabled now listening detection." << endl;
#endif
}



// The account changed it's status to online
void KMess::accountOnline()
{
  // Enable the now listening detection if needed.
  nowListeningClient_->setEnabled( currentAccount_->getShowNowListening() );

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess: account went online. Now listening is "
            << ( currentAccount_->getShowNowListening() ? "enabled" : "disabled") << "." << endl;
#endif
}



// Add the account and create the GUI elements
void KMess::addAccount(Account *account)
{
  AccountAction *accountAction;
  QString handle = account->getHandle();

  // Append account
  accounts_.append(account);

  // Make the action for the "Connect..." menu
  accountAction = new AccountAction( account, this, account->getHandle() );
  connectActionMenu_->insert( accountAction );
  connectMenuItems_.insert( handle, accountAction );

  connect( accountAction, SIGNAL(          activated(Account*) ),
           this,          SLOT  ( connectWithAccount(Account*) ) );


  // Make the action for the "Settings..." menu
  accountAction = new AccountAction( account, this,  account->getHandle() );
  settingsActionMenu_->insert( accountAction );
  settingsMenuItems_.insert( handle, accountAction );

  connect( accountAction, SIGNAL(              activated(Account*) ),
           this,          SLOT  ( showSettingsForAccount(Account*) ) );


  // Add the account to the initial view's dropdown list.
  initialView_->addAccount( account );
}



// "Add a new contact" was selected from the menu.
void KMess::addNewContact()
{
#ifdef KMESSTEST
  ASSERT( msnNotificationConnection_ != 0 );
#endif
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::addNewContact()" << endl;
#endif
  QString newHandle;
  bool    okPressed = false;

  // Launch a dialog to get a new group name
#if KDE_IS_VERSION(3,2,0)
  newHandle = KInputDialog::getText(i18n("Add a contact"),
                                    i18n("Enter the email address of the person you wish to add:"),
                                    newHandle, &okPressed, this);
#else
  newHandle = KLineEditDlg::getText(i18n("Add a contact"),
                                    i18n("Enter the email address of the person you wish to add:"),
                                    newHandle, &okPressed, this);
#endif

  if(okPressed)
  {
    // Ask the server to add the contact
    msnNotificationConnection_->addNewContact(newHandle);
  }
}



// "Add a new group" was selected from the menu.
void KMess::addNewGroup()
{
#ifdef KMESSTEST
  ASSERT( msnNotificationConnection_ != 0 );
#endif
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::addNewGroup()" << endl;
#endif
  QString newGroupName;
  bool    okPressed = false;

  // Set a default group name
  newGroupName = "New Group";

  // Launch a dialog to get a new group name
#if KDE_IS_VERSION(3,2,0)
  newGroupName = KInputDialog::getText(i18n("Add a group"),
                                       i18n("Enter the new name for this group:"),
                                       newGroupName, &okPressed, this);
#else
  newGroupName = KLineEditDlg::getText(i18n("Add a group"),
                                       i18n("Enter the new name for this group:"),
                                       newGroupName, &okPressed, this);
#endif

  if(okPressed)
  {
    // Ask the server to add the group
    msnNotificationConnection_->addGroup( newGroupName );
  }
}



// The application is closing, after queryExit() was approved
void KMess::applicationClosing()
{
  if(chatMaster_ != 0)
  {
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess::applicationClosing: destroying chat master" << endl;
#endif

    // Close the chat windows earlier, so logs are saved.
    chatMaster_->disconnected();
    chatMaster_->deleteLater();
    chatMaster_ = 0;
  }
}



// A status was selected from the menu.
void KMess::changeStatus(const QString &statusName)
{
  QString            newStatus = "";
  bool               useAutoreply;
  AwayMessageDialog *awayMessageDialog;
  QString            awayMessage;

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "Selected status " << statusName << endl;
#endif
  currentAccount_->setAutoreply( false );
  if ( statusName == i18n("Away") )
  { // Change status to AWAY
    newStatus = "AWY";
  }
  else if ( statusName == i18n("Away with auto-reply") )
  { // Change status to AWAY
    newStatus = "AWY";
    // Create the away message dialog
    awayMessageDialog = new AwayMessageDialog( this, "awaymessagedialog" );
    // Confirm the auto-away message with the user
    awayMessage = CurrentAccount::instance()->getAutoreplyMessage();
    useAutoreply = false;
    useAutoreply = awayMessageDialog->useMessage( awayMessage );
    if ( useAutoreply )
    {
      // Tell the account to respond with an autoreply message
      CurrentAccount::instance()->setAutoreplyMessage( awayMessage );
      CurrentAccount::instance()->setAutoreply( true );
    }
    delete awayMessageDialog;
  }
  else if ( statusName == i18n("Be Right Back") )
  { // Change status to BE RIGHT BACK
    newStatus = "BRB";
  }
  else if ( statusName == i18n("Busy") )
  { // Change status to BUSY
    newStatus = "BSY";
  }
  else if ( statusName == i18n("Invisible") )
  { // Change status to INVISIBLE
    newStatus = "HDN";
  }
  else if ( statusName == i18n("Out to Lunch") )
  { // Change status to OUT TO LUNCH
    newStatus = "LUN";
  }
  else if ( statusName == i18n("Online") )
  { // Change status to ONLINE
    newStatus = "NLN";
  }
  else if ( statusName == i18n("On the Phone") )
  { // Change status to ON THE PHONE
    newStatus = "PHN";
  }
  if ( newStatus != "" )
  {
    msnNotificationConnection_->changeStatus( newStatus );
  }
}



// The current now listening settings have changed.
void KMess::changedNowListeningSettings()
{
  // Enable now listening if current account is online and likes to enable now listening.
  QString status = currentAccount_->getStatus();
  bool isOnline = status != "FLN" && status != "HDN";  // not offline or invisible.
  nowListeningClient_->setEnabled( currentAccount_->getShowNowListening() && isOnline );

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess: now listening settings changed. Now listening is "
            << ( currentAccount_->getShowNowListening() ? "enabled" : "disabled") << endl;
#endif
}



// The currently playing song was changed.
void KMess::changedSong( const QString &artist, const QString &album, const QString &track, bool playing )
{
  if( msnNotificationConnection_->isConnected() )
  {
    if( ! playing )
    {
      // Update notification connection and KMessView.
      msnNotificationConnection_->removeCurrentMedia();
    }
    else
    {
      // Update notification connection.
      QStringList arguments;
      arguments << track << artist << album << "" << "";
      msnNotificationConnection_->changeCurrentMedia( "", "Music", true, "{0} - {1}", arguments );
    }

    // Update KMessView
    view_->changedSong( artist, album, track, playing );
  }
}



// The status was changed
void KMess::changedStatus()
{
  int item = -1;
  QString newStatus;

  if ( currentAccount_ != 0 )
  {
    newStatus = currentAccount_->getStatus();
  }
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - Changed status to " << newStatus << " from " << currentStatus_ << ". "
            << "Autoreply is " <<  currentAccount_->getAutoreply() << endl;
#endif

  // Make sure the drop down list matches the user's status
  if ( newStatus == "AWY" )
  {
    if ( !currentAccount_->getAutoreply() )
    {
      // Change status to AWAY
      item = 1;
    }
    else
    {
      // Change status to AWAY with autoreply
      item = 2;
    }
  }
  else if ( newStatus == "BRB" )
  { // Change status to BE RIGHT BACK
    item = 3;
  }
  else if ( newStatus == "BSY" )
  { // Change status to BUSY
    item = 4;
  }
  else if ( newStatus == "HDN" )
  { // Change status to INVISIBLE
    item = 7;
  }
  else if ( newStatus == "LUN" )
  { // Change status to OUT TO LUNCH
    item = 5;
  }
  else if ( newStatus == "NLN" )
  { // Change status to ONLINE
    item = 0;
  }
  else if ( newStatus == "PHN" )
  { // Change status to ON THE PHONE
    item = 6;
  }

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - Changed the select status to item " << item << endl;
#endif

  if ( item >= 0 )
  {
    status_->setCurrentItem( item );
  }
}



// A view mode has been selected from the menu.
void KMess::changeViewMode(int mode)
{
#ifdef KMESSTEST
  ASSERT( ( mode == 0 ) || ( mode == 1 ) );
#endif
  if ( mode == 0 )
  {
    CurrentAccount::instance()->setShowContactsByGroup( true );
  }
  else if ( mode == 1 )
  {
    CurrentAccount::instance()->setShowContactsByGroup( false );
  }
  else
  {
    kdDebug() << "KMess - changeViewMode() - WARNING - Invalid view mode = " << mode << endl;
  }
}



// Show a "Contact added you" dialog
void KMess::showContactAddedUserDialog(const Contact *contact)
{
  // Note that this function isn't well tested because the case where
  //  somebody adds you to their contact list doesn't occur very often,
  //  not when you've been using messenger for a while.
  QString                 handle;
  ContactAddedUserDialog *dialog;
  int                     returnValue;

  handle = contact->getHandle();
  dialog = new ContactAddedUserDialog();

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "Contact added user" << endl;
#endif

  // Show a dialog and let the user choose whether to add, allow,
  //  or block the contact.
  returnValue = dialog->launch(handle, contact->getFriendlyName());
  delete dialog;

  if ( returnValue == ContactAddedUserDialog::ADD )
  {
    // Add the contact to the allowed and friends lists
    msnNotificationConnection_->addNewContact(handle);
  }
  else if ( returnValue == ContactAddedUserDialog::ALLOW )
  {
    // Add the contact to the allowed list
    msnNotificationConnection_->allowContact(handle);
  }
  else if ( returnValue == ContactAddedUserDialog::BLOCK )
  {
    // Add the contact to the blocked list.
    msnNotificationConnection_->blockContact(handle);
  }
}


#ifdef KMESS_NETWORK_WINDOW
// Opens the network window
void KMess::showNetworkWindow()
{
  NetworkWindow::instance()->show();
}
#endif


// Show a dialog before removing the contact
void KMess::showRemoveContactDialog(QString handle)
{
  QString message = i18n( "<qt>Are you sure you want to remove the contact <b>%1</b> from your contact list?</qt>" )
                    .arg(handle);

  int result = KMessageBox::warningContinueCancel( this, message, i18n( "Remove contact" ),
                                                   KGuiItem(i18n("Remove"), "editdelete"), 0
#if KDE_IS_VERSION(3,2,0)
                                                   , KMessageBox::Dangerous
#endif
                                                  );

  if(result == KMessageBox::Continue)
  {
    // TODO: include a checkbox with the option "Also block this contact".
    msnNotificationConnection_->removeContact(handle, false);
  }
}


// Show a dialog before removing the group
void KMess::showRemoveGroupDialog(QString groupId)
{
  Group *group = currentAccount_->getContactList()->getGroupById(groupId);
 
  // If the group was found
  if(group == 0)
  {
    kdDebug() << "KMess::showRemoveGroupDialog() - Couldn't find a matching group." << endl;
    return;
  }

  QString message = i18n( "<qt>Are you sure you want to remove the group <b>%1</b> from your contact list?</qt>" )
                    .arg(group->getName());

  int result = KMessageBox::warningContinueCancel( this, message, i18n( "Remove group" ),
                                                   KGuiItem(i18n("Remove"), "editdelete"), 0
#if KDE_IS_VERSION(3,2,0)
                                                   , KMessageBox::Dangerous
#endif
                                                  );

  if(result == KMessageBox::Continue)
  {
    msnNotificationConnection_->removeGroup(groupId);
  }
}


// Show a "Rename group" dialog
void KMess::showRenameGroupDialog(QString groupId)
{
  Group  *group = currentAccount_->getContactList()->getGroupById(groupId);
  QString newGroupName;
  bool    okPressed = false;

  // If the group was found
  if ( group == 0 )
  {
    kdDebug() << "KMess::showRenameGroupDialog() - Couldn't find a matching group." << endl;
    return;
  }

  // If the group is not a special group...
  if(group->isSpecialGroup())
  {
    // Show a message that it can't be deleted
    KMessageBox::error( 0, i18n("This is a special group and can't be changed.") );
    return;
  }
  else
  {
    // Otherwise, get the new group name..
    newGroupName = group->getName();

    // Launch a dialog to get a new group name
#if KDE_IS_VERSION(3,2,0)
  newGroupName = KInputDialog::getText(i18n("Rename group"),
                                       i18n("Enter the new name for this group:"),
                                       newGroupName, &okPressed, this);
#else
  newGroupName = KLineEditDlg::getText(i18n("Rename group"),
                                       i18n("Enter the new name for this group:"),
                                       newGroupName, &okPressed, this);
#endif

    if(okPressed)
    {
      // Request that the group be renamed
      msnNotificationConnection_->renameGroup(groupId, newGroupName);
    }
  }
}


// Opens the transfer manager
void KMess::showTransferWindow()
{
  TransferWindow *transferWindow = TransferWindow::instance();
  transferWindow->show();
}


// Autologin with the first account that has autologin enabled
void KMess::checkAutologin(QString handle)
{
  Account *loginAccount = 0;

  // If no handle was given...
  if ( handle.isEmpty() )
  {
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess::checkAutologin: No handle was given, find an account that uses autologin." << endl;
#endif
    for ( Account *account = accounts_.first(); account; account = accounts_.next() )
    {
      // For completeness, also test for guest accounts.
      if( account->isGuestAccount() )
      {
        continue;
      }

#ifdef KMESSDEBUG_KMESS
      kdDebug() << "KMess: Account " << account->getHandle()
                << " useAutologin = " << account->getUseAutologin() << "." << endl;
#endif
      if ( account->getUseAutologin() )
      {
        loginAccount = account;
        break;
      }
    }
  }
  else
  {
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::checkAutologin finding account: " << handle << "." << endl;
#endif
    loginAccount = getAccountByHandle(handle);
  }

  if ( loginAccount != 0 )
  {
    // Use the autologin view as the main view
    //initialView_->hide();
    //autologinView_->show();
    setCentralWidget( autologinView_ );
    connectWithAccount( loginAccount );
  }
}



// A connection has been made with the notification server.
void KMess::connected()
{
#ifdef KMESSTEST
  ASSERT( view_ != 0 );
  ASSERT( initialView_ != 0 );
  ASSERT( autologinView_ != 0 );
#endif
  // Disable the disconnected button
  // Enable/disable the menus
  enableMenus( true );
  // Set up the toggle and view mode tools to match the account settings
  showAllowedAction_->setChecked( currentAccount_->getShowAllowedContacts() );
  showOfflineAction_->setChecked( currentAccount_->getShowOfflineContacts() );
  showRemovedAction_->setChecked( currentAccount_->getShowRemovedContacts() );
  if ( currentAccount_->getShowContactsByGroup() )
  {
    viewMode_->setCurrentItem( 0 );
  }
  else
  {
    viewMode_->setCurrentItem( 1 );
  }
  // Show the connected message
  statusMessage( i18n("Connected"), 1 );
  // Give the view widget some info
  view_->connected();
  // Swap the initial and main views
  initialView_->hide();
  autologinView_->hide();
  view_->show();
  // Set it as the application's main widget
  setCentralWidget( view_ );
  // Set the caption
  setCaptionToUser();
}



// Connect to the server with the given account
void KMess::connectWithAccount(Account *account)
{
  if(KMESS_NULL(account)) return;
  bool            connected;
  QString         errorMessage;

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::connectWithAccount: " << account->getHandle() << "." << endl;
#endif

  // First disconnect, to unregister all contacts
  if(msnNotificationConnection_->isConnected())
  {
    msnNotificationConnection_->closeConnection();
  }

  // Swap widget.
  initialView_->hide();
  autologinView_->show();
  setCentralWidget( autologinView_ );

  // Copy the account to the current account
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess: copying account data for '" << account->getHandle() << "' to the CurrentAccount object." << endl;
#endif
  currentAccount_->copyAccount( account );

  // Allow users to cancel the login attempt
  disconnect_->setEnabled( true  );

  // Connect to the server.
  connected = msnNotificationConnection_->openConnection();
  if ( !connected )
  {
    // Notify the user.
    errorMessage = i18n("The connection to the server failed.") + "\r\n";
    errorMessage += i18n("You may not be connected to the internet.");
    KMessageBox::error( 0, errorMessage );
  }
}



// Connect to the server with the given account, possibly temporary or new.
void KMess::connectWithAccount(QString handle, QString password, bool rememberMe)
{
  // Try to find an existing account
  Account *account = getAccountByHandle(handle);
  if( account != 0 )
  {
    // Found an existing account.
    // The user may enter a new password at the login dialog.
    // When the login succeeds, save the new temporary password as new account password.
    account->setTemporaryPassword( password );
    connectWithAccount( account );
    return;
  }

  // No account found, create a new account.
  account = new Account();
  account->setLoginInformation( handle, handle, password );
  account->setGuestAccount( ! rememberMe);
  addAccount( account );

  // Connect
  connectWithAccount( account );
}



// Create the program's default directories in .kde/share/apps/
bool KMess::createDirectories()
{
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - Creating default directories." << endl;
#endif
  KStandardDirs *dirs   = KGlobal::dirs();
  QString        localKdeDir;
  QDir           appsDir, kmessDir, emoticonsDir, picsDir;

  localKdeDir = dirs->localkdedir();
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - Local KDE dir is " << localKdeDir << "." << endl;
#endif
  appsDir.setPath( localKdeDir + "/share/apps" );

  if ( appsDir.exists() )
  {
    kmessDir.setPath( appsDir.absPath() + "/kmess" );
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess - kmess dir should be at " << kmessDir.absPath() << "." << endl;
#endif
    if ( !kmessDir.exists() )
    {
#ifdef KMESSDEBUG_KMESS
      kdDebug() << "KMess - Creating kmess dir." << endl;
#endif
      appsDir.mkdir( kmessDir.absPath(), true );
    }
    // Create the pics and emoticons directories
    emoticonsDir.setPath( kmessDir.absPath() + "/emoticons" );
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess - emoticons dir should be at " << emoticonsDir.absPath() << "." << endl;
#endif
    if ( !emoticonsDir.exists() )
    {
#ifdef KMESSDEBUG_KMESS
      kdDebug() << "KMess - Creating emoticons dir." << endl;
#endif
      kmessDir.mkdir( emoticonsDir.absPath(), true );
    }
    picsDir.setPath( kmessDir.absPath() + "/pics" );
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess - pics dir should be at " << picsDir.absPath() << "." << endl;
#endif
    if ( !picsDir.exists() )
    {
#ifdef KMESSDEBUG_KMESS
      kdDebug() << "KMess - Creating pics dir." << endl;
#endif
      kmessDir.mkdir( picsDir.absPath(), true );
    }
  }
#ifdef KMESSDEBUG_KMESS
  else
  {
    kdDebug() << "KMess - " << appsDir.absPath() << " doesn't exist!" << endl;
  }
#endif
#ifdef KMESSTEST
  ASSERT(     kmessDir.exists() );
  ASSERT( emoticonsDir.exists() );
  ASSERT(      picsDir.exists() );
#endif
  return true;
}



// "Add new account" has been selected from the menu.
void KMess::createNewAccount()
{
  Account *account;
  // If there are no profiles, create a "default" account
  // Create an account to store the profile information
  account = new Account();

  // Assume the user *does* want to save it's settings,
  // otherwise he/she would have used the main login dialog.
  account->setGuestAccount(false);

  // Show the settings dialog for the new account
  showSettingsForAccount( account );

  // Make sure the account handle was changed off the default
  if ( account->getHandle() != i18n("you@hotmail.com") )
  {
    // Add the account to the account list.
    addAccount(account);
  }
  else
  {
    // The account wasn't changed, so delete it.
    delete account;
  }
}



// The current account changed its name, so set the corresponding account's name
void KMess::currentAccountChangedName()
{
  Account *account = getAccountByHandle( currentAccount_->getHandle() );
  if( account != 0 )
  {
    // Set the account's name to the current account's name
    account->setFriendlyName( currentAccount_->getFriendlyName() );
  }

  // Set the caption to the account's new name
  setCaptionToUser();
}



// Delete the given account
void KMess::deleteAccount(Account *account)
{
  AccountAction *accountAction;
  if( KMESS_NULL(account) ) return;

  QString handle = account->getHandle();
  if( handle == currentAccount_->getHandle() && msnNotificationConnection_->isConnected() )
  {
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::deleteAccount: Not deleting account " << account->getHandle() << " yet." << endl;
#endif

    // Already delete account data.
    // NOTE: when more classes have an Account* object, consider creating a setDeleted(true)
    // method, and let deleteAccountData() fire a deleteAccount(this) signal.
    account->deleteAccountData();
    return;
  }

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess: Deleting account for " << handle << "." << endl;
#endif

  // Remove the account from the list of accounts
  if( ! accounts_.remove( account ) )
  {
    kdWarning() << "KMess::deleteAccount: account not found in collection!" << endl;
  }

  // Remove from other GUI parts
  initialView_->deleteAccount(account);

  // Remove from connect menu.
  accountAction = connectMenuItems_[handle];
  if( ! KMESS_NULL(accountAction) )
  {
    connectActionMenu_->remove(accountAction);
    connectMenuItems_.remove(handle);
  }

  // Remove from settings menu.
  // This can't be done from AccountAction, because the menu item should
  // remain accessable when you're logged in.
  accountAction = settingsMenuItems_[handle];
  if( ! KMESS_NULL(accountAction) )
  {
    settingsActionMenu_->remove(accountAction);
    settingsMenuItems_.remove(handle);
  }

  // Delete here as this class maintains the collection.
  // No need to call deleteAccountData(), it triggered this slot.
  account->deleteAccountData();
  account->deleteLater();
}



// Disconnect was selected from the menu.
void KMess::disconnectClicked()
{
#ifdef KMESSTEST
  ASSERT( msnNotificationConnection_ != 0 );
#endif
#ifdef KMESSDEBUG_KMESSINTERFACE
  kdDebug() << "KMess: Disconnecting." << endl;
#endif
  msnNotificationConnection_->closeConnection();
}



// The program is not connected (initially) or no longer connected (after a disconnect) to the notification server.
void KMess::disconnected()
{
#ifdef KMESSTEST
  ASSERT( view_ != 0 );
  ASSERT( chatMaster_ != 0 );
  ASSERT( initialView_ != 0 );
  ASSERT( autologinView_ != 0 );
#endif
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - Disconnected." << endl;
#endif

  // this method is also called when initializing the GUI, avoid manging the settings at that point.
  if( initialized_ )
  {
    // ContactList is saved by the MsnNotificationConnection already.
    // A nice alternative would be currentAccount_->disconnected() saving the list,
    // however CurrentAccount has a const reference to the list
    // because MsnNotificationConnection maintains the list instead.

    // Transfer account settings that are made in the GUI.
    Account *account = getAccountByHandle(currentAccount_->getHandle());
    if( ! KMESS_NULL(account) )
    {
      if( account->isDeleted() )
      {
#ifdef KMESSDEBUG_KMESS
        kdDebug() << "KMess::disconnected: account was deleted, removing menu items." << endl;
#endif
        deleteAccount(account);
      }
      else
      {
#ifdef KMESSDEBUG_KMESS
        kdDebug() << "KMess::disconnected: copying global user-interface settings from CurrentAccount to the Account object." << endl;
#endif

        account->copyAccountUISettings( currentAccount_ );
      }
    }
  }

  // Update the GUI
  disconnect_->setEnabled( false );
  enableMenus(false);
  statusMessage( i18n("Disconnected"), 3 );

  // Inform other classes we're disconnected
  view_->disconnected();
  chatMaster_->disconnected();

  // Update the current account
  currentAccount_->setStatus( "FLN" );
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - Swap views." << endl;
#endif

  // Swap the initial and main views
  initialView_->show();
  view_->hide();
  autologinView_->hide();
  // Set it as the application's main widget
  setCentralWidget( initialView_ );

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - Blank the caption." << endl;
#endif
  // Set the caption
  setCaption( QString::null );
}



// Initialize the class
bool KMess::initialize()
{
  if ( initialized_ )
  {
    kdDebug() << "KMess - Already initialized." << endl;
    return false;
  }

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::initialize: initializing main class." << endl;
#endif

  // Create current account instance
  currentAccount_ = CurrentAccount::instance();
  if ( currentAccount_ == 0 )
  {
    kdDebug() << "KMess - Couldn't get a pointer to the instance of the current account." << endl;
    return false;
  }
  if ( !KMessInterface::initialize() )
  {
    kdDebug() << "KMess - Couldn't initialize ancestor." << endl;
    return false;
  }
  if ( !initMsnNotificationConnection() )
  {
    kdDebug() << "KMess - Couldn't initialize the MsnNotificationConnection class." << endl;
    return false;
  }
  if ( !initIdleTimer() )
  {
    kdDebug() << "KMess - Couldn't initialize the IdleTimer class." << endl;
    return false;
  }
  if ( !initAutologinView() )
  {
    kdDebug() << "KMess - Couldn't initialize the AutologinView widget." << endl;
    return false;
  }
  if ( !initInitialView() )
  {
    kdDebug() << "KMess - Couldn't initialize the InitialView widget." << endl;
    return false;
  }
  if ( !initKMessView() )
  {
    kdDebug() << "KMess - Couldn't initialize the KMessView widget." << endl;
    return false;
  }
  if ( !initSystemTrayWidget() )
  {
    kdDebug() << "KMess - Couldn't initialize the system tray widget." << endl;
    return false;
  }
  if ( !initChatMaster() )
  {
    kdDebug() << "KMess - Couldn't initialize the Chat master." << endl;
    return false;
  }
  if ( !initNotifications() )
  {
    kdDebug() << "KMess - Couldn't initialize the notifications." << endl;
    return false;
  }
  if ( !initNowListening() )
  {
    kdDebug() << "KMess - Couldn't initialize the now listening support." << endl;
    return false;
  }
  if ( !createDirectories() )
  {
    kdDebug() << "KMess - Couldn't create local KDE directories." << endl;
    return false;
  }


  // Start reading the properties
  readProperties( kapp->config() );


  // Connect current account
  connect( currentAccount_, SIGNAL(            accountInvisible() ),
           this,            SLOT  (            accountInvisible() ));
  connect( currentAccount_, SIGNAL(              accountOffline() ),
           this,            SLOT  (              accountOffline() ));
  connect( currentAccount_, SIGNAL(               accountOnline() ),
           this,            SLOT  (               accountOnline() ));
  connect( currentAccount_, SIGNAL(         changedFriendlyName() ),
           this,            SLOT  (   currentAccountChangedName() ));
  connect( currentAccount_, SIGNAL( changedNowListeningSettings() ),
           this,            SLOT  ( changedNowListeningSettings() ));
  connect( currentAccount_, SIGNAL(               changedStatus() ),
           this,            SLOT  (               changedStatus() ));
  connect( currentAccount_, SIGNAL(            changedMsnObject() ),
           msnNotificationConnection_, SLOT(   changedMsnObject() ));

  // connect a shutDown() signal
  connect( KApplication::kApplication(),  SIGNAL(    shutDown() ),
           this,                          SLOT  (    shutDown() ) );


  // Start disconnected.
  // Added debug here because this has a potential to cause problems..
  // It would be better if each class got things right from it's construtor or initialize method.
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::initialize: faking disconnect signal." << endl;
#endif
  disconnected();


  // All done, mark as initialized
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::initialize: main class is initialized." << endl;
#endif

  initialized_ = true;
  return true;
}



// Return the account for a given handle
Account * KMess::getAccountByHandle( const QString &handle )
{
  Account *account = 0;
  QPtrListIterator<Account> it( accounts_ );
  while( it.current() != 0 )
  {
    account = it.current();
    if( account->getHandle() == handle )
    {
      return account;
    }

    ++it;
  }

  return 0;
}


// Initialize the autologin view
bool KMess::initAutologinView()
{
  autologinView_ = new AutologinView( this, "autologinView" );
  if ( autologinView_ == 0 )
  {
    kdDebug() << "KMess - Couldn't create the autologin view" << endl;
    return false;
  }
  autologinView_->hide();
  return true;
}



// Initialize the chat master
bool KMess::initChatMaster()
{
#ifdef KMESSTEST
  ASSERT( chatMaster_ == 0 );
#endif
  if ( msnNotificationConnection_ == 0 )
  {
    kdDebug() << "KMess - The notification connection must be initialized before the chat master." << endl;
    return false;
  }
  chatMaster_ = new ChatMaster( this );
  if ( chatMaster_ == 0 )
  {
    kdDebug() << "KMess - Couldn't create the chat master." << endl;
    return false;
  }
  if ( !chatMaster_->initialize() )
  {
    kdDebug() << "KMess - Couldn't initialize the chat master." << endl;
    return false;
  }

  // Make the chat master's connections
  connect( msnNotificationConnection_, SIGNAL(       startChat(const ChatInformation&) ),
           chatMaster_,                SLOT  (       startChat(const ChatInformation&) ) );
  connect( chatMaster_,                SIGNAL(     requestChat(QString) ),
           msnNotificationConnection_, SLOT  (     requestChat(QString) ));
  connect( msnNotificationConnection_, SIGNAL(     chatMessage(const ChatMessage&) ),
           chatMaster_,                SLOT  ( showChatMessage(const ChatMessage&) ));

#ifdef KMESSTEST
  ASSERT( chatMaster_ != 0 );
#endif
  return true;
}



// Initialize the idle timer
bool KMess::initIdleTimer()
{
#ifdef KMESSTEST
  ASSERT( idleTimer_ == 0 );
#endif
  idleTimer_ = new IdleTimer();
  if ( idleTimer_ == 0 )
  {
    kdDebug() << "KMess - Couldn't create the idle timer." << endl;
    return false;
  }
  // Connect the timer to signal when the user is away.
  connect( idleTimer_, SIGNAL( timeout()       ),
           this,       SLOT  ( userIsIdle() )    );
  connect( idleTimer_, SIGNAL( activity()      ),
           this,       SLOT  ( userIsNotIdle() ) );
#ifdef KMESSTEST
  ASSERT( idleTimer_ != 0 );
#endif
  return true;
}



// Initialize the initial view
bool KMess::initInitialView()
{
  initialView_ = new InitialView( this, "initialview" );
  initialView_->show();

  connect( initialView_, SIGNAL( connectWithAccount(QString,QString,bool) ),
           this,         SLOT  ( connectWithAccount(QString,QString,bool) ) );

  return true;
}



// Initialize the main view
bool KMess::initKMessView()
{
  bool initialized;

  if ( msnNotificationConnection_ == 0 )
  {
    kdDebug() << "KMess - MsnNotificationConnection must be initialized before KMessView" << endl;
    return false;
  }

  view_        = new KMessView(this, "kmessview");

  initialized  = view_->initialize();
  if ( !initialized )
  {
    kdDebug() << "KMess - Couldn't initialize KMessView." << endl;
    return false;
  }


  // Connect other signals to msnNotificationConnection
  connect( view_,                      SIGNAL(    addContact(QString)                   ),   // Add a contact
           msnNotificationConnection_, SLOT  (addExistingContact(QString)               ) );
  connect( view_,                      SIGNAL(  allowContact(QString)                   ),   // Allow the contact
           msnNotificationConnection_, SLOT  (  allowContact(QString)                   ) );
  connect( view_,                      SIGNAL(  blockContact(QString)                   ),   // Block the contact
           msnNotificationConnection_, SLOT  (  blockContact(QString)                   ) );
  connect( view_,                      SIGNAL( changePersonalMessage(QString)           ),   // Change the personal message.
           msnNotificationConnection_, SLOT  ( changePersonalMessage(QString)           ) );
  connect( view_,                      SIGNAL( copyContact(Contact*, QString)           ),                                msnNotificationConnection_, SLOT  ( copyContactToGroup(Contact*, QString)    ) );
  connect( view_,                      SIGNAL( moveContact(QString, QString, QString)   ),   // Move the contact
           msnNotificationConnection_, SLOT  ( moveContact(QString, QString, QString)   ) );
  connect( view_,                      SIGNAL( showSettings()                           ),   // Show settings
           this,                       SLOT  ( showSettingsForCurrentAccount()          ) );
  connect( view_,                      SIGNAL( startChat(QString)                       ),   // Start a chat
           msnNotificationConnection_, SLOT  ( requestChat(QString)                     ) );
  connect( view_,                      SIGNAL( removeContact(QString)                   ),   // Remove the contact
           this,                       SLOT  (showRemoveContactDialog(QString)          ) );
  connect( view_,                      SIGNAL( removeContactFromGroup(Contact*, QString)),                                msnNotificationConnection_, SLOT  (removeContactFromGroup(Contact*, QString) ) );
  connect( view_,                      SIGNAL(   removeGroup(QString)                   ),   // Remove the group
           this,                       SLOT  (showRemoveGroupDialog(QString)            ) );
  connect( view_,                      SIGNAL(   renameGroup(QString)                   ),   // Rename the group
           this,                       SLOT  (showRenameGroupDialog(QString)            ) );
  connect( view_,                      SIGNAL(unblockContact(QString)                   ),   // Unblock the contact
           msnNotificationConnection_, SLOT  (unblockContact(QString)                   ) );

  view_->hide();
  return true;
}



// Initialize the MSN notification connection
bool KMess::initMsnNotificationConnection()
{
  bool initialized;
  
  msnNotificationConnection_ = new MsnNotificationConnection();

  initialized = msnNotificationConnection_->initialize();
  if ( !initialized )
  {
    kdDebug() << "KMess - Couldn't initialize MsnNotificationConnection." << endl;
    return false;
  }

  // Connect the signals
  connect( msnNotificationConnection_, SIGNAL(     connected()                          ),   // Connected to msn
           this,                       SLOT  (     connected()                          ) );
  connect( msnNotificationConnection_, SIGNAL(  disconnected()                          ),   // Disconnected from msn
           this,                       SLOT  (  disconnected()                          ) );
  connect( msnNotificationConnection_, SIGNAL(contactAddedUser(const Contact*)          ),   // Contact added user
           this,                       SLOT  (showContactAddedUserDialog(const Contact*)) );
  connect( msnNotificationConnection_, SIGNAL( statusMessage(QString, int)              ),   // Display a status message
           this,                       SLOT  ( statusMessage(QString, int)              ) );

  return true;
}



// Initialize notification objects
bool KMess::initNotifications()
{
#ifdef KMESSTEST
  ASSERT( currentAccount_             != 0 );
  ASSERT( systemTrayWidget_           != 0 );
  ASSERT( msnNotificationConnection_  != 0 );

  ASSERT( contactOfflineNotification_ == 0 );
  ASSERT( contactOnlineNotification_  == 0 );
  ASSERT( emailNotification_          == 0 );
#endif

  const ContactList *contactList;
  

  if ( systemTrayWidget_ == 0 )
  {
    kdDebug() << "KMess - The system tray widget must be initialized before the notifications!" << endl;
    return false;
  }
  if ( msnNotificationConnection_ == 0 )
  {
    kdDebug() << "KMess - The notification connection must be initialized before the notifications!" << endl;
    return false;
  }


  // Add check whether the 'eventsrc' file can be found.
  // The warning is a bit obtruisive, but should help to user to fix the problem.
  if( KGlobal::dirs()->findResource( "config", "kmess.eventsrc" ).isNull() )
  {
    QString dirs = KGlobal::dirs()->findDirs( "config", QString::null ).join("<br>- ");
    if( dirs.isEmpty() )
    {
      dirs = "(none)";
    }
    else
    {
      dirs = "<br>- " + dirs;
    }

    // Always show warning at the console.
    kdWarning() << "Sounds and notifications will not be available, kmess.eventsrc could not be found." << endl;

    // Show the message in the GUI as well.
    // Allow to user to choose "don't show this message again", in case he/she doesn't know how to fix it.
    KMessageBox::information( this, i18n( "<qt><p>KMess will not be able to play sounds and notifications.</p>"
                                          "<p>The file 'kmess.eventsrc' could not be found in one of the following  folders: %1</p>"
                                          "<p>Please verify your installation, and copy the missing file to one of the listed folders.</p>"
                                          "</qt>" ).arg( dirs ),
                                    i18n( "Error with notifications" ),
                                    "eventsrcNotFound" );
  }


  contactList = currentAccount_->getContactList();

  balloonWidget_ = new BalloonWidget();
  balloonWidget_->setAnchorWidget( systemTrayWidget_ );


  // Connect the "Chat notification" signals
  chatNotification_           = new ChatNotification(balloonWidget_);
  connect( chatMaster_,                 SIGNAL(        newChat(const ContactBase*, QString, ChatWindow*) ),
           chatNotification_,           SLOT  (        newChat(const ContactBase*, QString, ChatWindow*) ) );

  // Connect the "offline notification" signals
  contactOfflineNotification_ = new ContactOfflineNotification(balloonWidget_);
  connect( contactList,                 SIGNAL( contactOffline(Contact*,bool)  ),
           contactOfflineNotification_, SLOT  ( contactOffline(Contact*,bool)  ) );

  // Connect the "online notification" signals
  contactOnlineNotification_  = new ContactOnlineNotification(balloonWidget_);
  connect( contactList,                 SIGNAL(  contactOnline(Contact*,bool)  ),
           contactOnlineNotification_,  SLOT  (  contactOnline(Contact*,bool)  ) );
  connect( contactOnlineNotification_,  SIGNAL(      startChat(QString)        ),
           msnNotificationConnection_,  SLOT  (    requestChat(QString)        ) );

  // Connect the "email notification" signals
  emailNotification_          = new EmailNotification(balloonWidget_);
  connect( msnNotificationConnection_,  SIGNAL(       newEmail(QString, QString, bool, QString, QString, QString) ),
           emailNotification_,          SLOT  (       newEmail(QString, QString, bool, QString, QString, QString) ) );

#ifdef KMESSTEST
  ASSERT( contactOfflineNotification_ != 0 );
  ASSERT( contactOnlineNotification_  != 0 );
  ASSERT( emailNotification_          != 0 );
#endif

  return true;
}



// Initialize the now listening support.
bool KMess::initNowListening()
{
  if ( msnNotificationConnection_ == 0 )
  {
    kdDebug() << "KMess - The notification connection must be initialized before the now listening support!" << endl;
    return false;
  }

  // Create and connect client.
  nowListeningClient_ = new NowListeningClient();
  connect( nowListeningClient_, SIGNAL( changedSong( const QString&, const QString&, const QString&, bool ) ),
           this,                SLOT  ( changedSong( const QString&, const QString&, const QString&, bool ) ));
  
  return true;
}


// Initialize the system tray widget
bool KMess::initSystemTrayWidget()
{
  bool initialized;

  // Create the widget
  systemTrayWidget_ = new SystemTrayWidget( this, "systemtraywidget" ) ;
  if ( systemTrayWidget_ == 0 )
  {
    kdDebug() << "KMess - Couldn't create system tray widget." << endl;
    return false;
  }

  // Initialize the widget
  initialized = systemTrayWidget_->initialize();
  if ( !initialized )
  {
    kdDebug() << "KMess - Couldn't initialize system tray widget." << endl;
    return false;
  }

  // Plug some of the menu actions into the system tray widget's menu.
  connectActionMenu_-> plug( systemTrayWidget_->menu() );
  disconnect_->        plug( systemTrayWidget_->menu() );
  systemTrayWidget_->  menu()->insertSeparator();
  status_->            plug( systemTrayWidget_->menu() );
  systemTrayWidget_->  menu()->insertSeparator();
  settingsActionMenu_->plug( systemTrayWidget_->menu() );

  // Make the connections for the system tray widget
  connect( systemTrayWidget_, SIGNAL( quitSelected() ),
           this,              SLOT  (     menuQuit() ) );

  systemTrayWidget_->show();
#ifdef KMESSTEST
  ASSERT( systemTrayWidget_ != 0 );
  ASSERT( systemTrayWidget_->isVisible() );
#endif
  return true;
}



// Read in account and other properties
void KMess::readProperties(KConfig *config)
{
  KMessInterface::readProperties(config);

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - reading properties" << endl;
#endif

  QStringList  accountList;
  Account     *account;

  // Get a list of the profiles stored in the configuration file
  config->setGroup("Profiles");
  accountList = config->readListEntry( "Profiles" );

  // For each listed account, create an account and have it read in its settings
  for ( unsigned int i = 0; i < accountList.count(); i++ )
  {
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess::readProperties: initializing account " << accountList[i] << "." << endl;
#endif

    account = new Account();
    account->readProperties( config, accountList[i] );
    addAccount( account );
  }
}



// Save account and other properties
void KMess::saveProperties(KConfig *config)
{
#ifdef KMESSDEBUG_KMESS
  if(config != kapp->config())
  {
    kdDebug() << "For some reason saveProperties(config) != kapp->config(), using kapp->config()." << endl;
  }
#endif

  config = kapp->config();   // Hack, but it seams to work
  KMessInterface::saveProperties(config);

#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess - saving properties" << endl;
#endif

  QStringList  accountList;
  Account *account;

  // Have all the accounts save their properties
  for ( account = accounts_.first(); account; account = accounts_.next() )
  {
    // Avoid saving guest accounts
    if( account->isGuestAccount() || account->isDeleted() ) 
    {
      continue;
    }

    // If the account is the current account...
    if ( account->getHandle() == currentAccount_->getHandle() )
    {
      // Move some settings from the current account to the account that are set by the user interface
#ifdef KMESSDEBUG_KMESS
      kdDebug() << "KMess::saveProperties: copying global user-interface settings from CurrentAccount to the Account object." << endl;
#endif
      account->copyAccountUISettings( currentAccount_ );
    }

    // Save properties of accounts (also saves the contactlist for the current account).
    account->saveProperties( config );
    accountList.append( account->getHandle() );
  }

  // Save the list of profiles
  config->setGroup("Profiles");
  config->writeEntry( "Profiles", accountList );

  // Save the the contact list properties
  // (getContactList returns a "const ContactList", which is a good thing!)
  msnNotificationConnection_->saveProperties( config );

  // Write data now!
  config->sync();
}



// Set the caption
void KMess::setCaptionToUser()
{
  if ( currentAccount_ != 0 )
  {
    // Set the caption
    setCaption( currentAccount_->getFriendlyName() );
  }
}



// Show the settings dialog for a given account
void KMess::showSettingsForAccount(Account *account)
{
#ifdef KMESSDEBUG_KMESS
  kdDebug() << "KMess::showSettingsForAccount: opening settings for " << account->getHandle() << endl;
#endif
#ifdef KMESSTEST
  ASSERT( msnNotificationConnection_ != 0 );
#endif
  QString oldFriendlyName;
  bool isCurrentAccount = false;
  bool isConnectedCurrentAccount = false;

  if ( msnNotificationConnection_ != 0 )
  {
    isCurrentAccount          = ( account->getHandle() == currentAccount_->getHandle() );
    isConnectedCurrentAccount = isCurrentAccount && ( msnNotificationConnection_->isConnected() );
  }

  // Save the account's friendly name
  oldFriendlyName = account->getFriendlyName();

  // Show the settings dialog
  SettingsDialog *settingsDialog = new SettingsDialog(this, "settings");
  connect( settingsDialog, SIGNAL( deleteAccount(Account*) ),
           this,           SLOT  ( deleteAccount(Account*) ));

  // If it's the current account, copy some UI settings from the current account to the account
  if( isCurrentAccount )
  {
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess::showSettingsForAccount: copying global user-interface settings from CurrentAccount to the Account object." << endl;
#endif
    account->copyAccountUISettings( currentAccount_ );

    if( ! account->isVerified() )
    {
      // TODO: display uninteruptive "account not verified" popup in AccountsWidgetInterface.
      KMessageBox::information( 0, i18n("You can't change your friendly name because your passport e-mail address is not verified."),
                                   i18n("Passport not verified"), "passportNotVerified" );
    }
  }

  settingsDialog->changeAccountSettings( account, isConnectedCurrentAccount );

  // If the account matches the current account..
  if( isCurrentAccount )
  {
    // If the friendly name was changed, ask the server to change it
    if ( account->isVerified() && account->getFriendlyName() != oldFriendlyName )
    {
      msnNotificationConnection_->changeFriendlyName( account->getFriendlyName() );
    }

    // Copy the account settings to the current account
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess::showSettingsForAccount: copying modified Account settings to CurrentAccount." << endl;
#endif
    currentAccount_->copyAccount( account );
  }

  // If the account is set to use autologin, make sure that all other accounts are not
  if( ! account->isDeleted() && account->getUseAutologin() )
  {
    QPtrListIterator<Account>  it(accounts_);
    while ( it.current() != 0 )
    {
      // For each account that is not the account just changed...
      if ( it.current() != account )
      {
        it.current()->setUseAutologin( false );
      }
      ++it;
    }
  }
}



// Show the settings dialog for the current account.
void KMess::showSettingsForCurrentAccount()
{
  // Use the Account object so it's consistent with the other AccountAction events.
  Account *accountData = getAccountByHandle( CurrentAccount::instance()->getHandle() );
  if( KMESS_NULL(accountData) ) return;
  showSettingsForAccount( accountData );
}



// Show the user's MSN profile.
void KMess::showUserProfile()
{
  QString       urlPath;
  KURL          *url;
  KRun          *run;

  if ( currentAccount_ != 0 )
  {
    // Set a path to the msn profile page.  Unfortunately, this isn't
    //  internationalized.
    urlPath = "http://members.msn.com/default.msnw?mem=" + currentAccount_->getHandle();
    // Create a URL to the given path
    url = new KURL( urlPath );
    // Launch the default html program for the given URL
    run = new KRun( *url );
  }
}



// We're about to shutdown, apparently
//  make sure we die, rather than just close the main window
void KMess::shutDown()
{
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess::shutDown: forcing quit from shutdown signal." << endl;
#endif

  // Called when the app is killed with 'xkill' for example.
  // No user-interaction is possible at this point.

  KApplication::kApplication()->quit();
}



// The "show allowed contacts" menu item has been toggled.
void KMess::toggleShowAllowed(bool show)
{
  currentAccount_->setShowAllowedContacts( show );
}



// The "show offline contacts" menu item has been toggled.
void KMess::toggleShowOffline(bool show)
{
  currentAccount_->setShowOfflineContacts( show );
}



// The "show removed contacts" menu item has been toggled.
void KMess::toggleShowRemoved(bool show)
{
  currentAccount_->setShowRemovedContacts( show );
}



// The user has gone idle
void KMess::userIsIdle()
{
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess::userIsIdle()" << endl;
#endif
  if ( ( currentAccount_ != 0 ) && ( msnNotificationConnection_ != 0 ) )
  {
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KM:   Current status is " << currentAccount_->getStatus() << "." << endl;
#endif
    // Only change the state if the user is currently set as online
    if ( currentAccount_->getStatus() == "NLN" )
    {
#ifdef KMESSDEBUG_KMESS
      kdDebug() << "KM:   Change status to IDL." << endl;
#endif
      // Request a status change to "IDL"
      msnNotificationConnection_->changeStatus("IDL");
    }
  }
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KM:   Done userIsIdle()." << endl;
#endif
}



// The user is no longer idle
void KMess::userIsNotIdle()
{
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KMess::userIsNotIdle()" << endl;
#endif
  if ( ( currentAccount_ != 0 ) && ( msnNotificationConnection_ != 0 ) )
  {
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KM:   User is no longer idle, current status is " << currentAccount_->getStatus() << endl;
#endif
    // Only change the state if the user is currently set as idle
    if ( currentAccount_->getStatus() == "IDL" )
    {
#ifdef KMESSDEBUG_KMESS
      kdDebug() << "KM:   Change status to NLN" << endl;
#endif
      // Request a status change to "NLN"
      msnNotificationConnection_->changeStatus("NLN");
    }
  }
#ifdef KMESSDEBUG_KMESS
    kdDebug() << "KM:   Done userIsNotIdle()." << endl;
#endif
}

#include "kmess.moc"

Generated by  Doxygen 1.6.0   Back to index