Files
kmess/src/initialview.cpp
T
2008-08-10 11:56:25 +00:00

516 lines
15 KiB
C++

/***************************************************************************
initialview.cpp - description
-------------------
begin : Sun Jan 12 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 "initialview.h"
#include "utils/kmessconfig.h"
#include "accountsmanager.h"
#include "account.h"
#include "kmessdebug.h"
#include <QTimer>
#include <kdeversion.h>
#include <KIconLoader>
#include <KLocale>
#include <KStandardDirs>
// The constructor
InitialView::InitialView( QWidget *parent )
: QWidget( parent )
, Ui::InitialView()
, isConnecting_( false )
{
// Set up the UI first
setupUi( this );
// Set the username box with the last used email address
config_ = KMessConfig::instance()->getGlobalConfig( "InitialView" );
defaultHandle_ = config_.readEntry( "defaultHandle", "me@hotmail.com" );
// Enable auto completion
handleCombobox_->setCompletionMode( KGlobalSettings::CompletionPopup );
// Select an image to load into the main screen.. mmmm, eggs!
QString imageName;
QDate currentDate = QDate::currentDate();
if( currentDate.month() == 12 && currentDate.day() > 15 )
{
imageName = "kmesslogo2";
}
else
{
imageName = "kmesslogo";
}
// Load the chosen icon
loader_ = KIconLoader::global();
QPixmap icon = loader_->loadIcon( imageName, KIconLoader::User );
kmessLogo_->setPixmap( icon );
kmessLogo_->setMinimumSize( icon.width(), icon.height() );
// Add the items to the initial status combo box
QStringList states;
states << i18n("Online")
<< i18n("Away")
<< i18n("Be Right Back")
<< i18n("Busy")
<< i18n("Out to Lunch")
<< i18n("On the Phone")
<< i18n("Invisible");
initialStatus_->insertItems( 0, states );
// Load the accounts list into our combo box
const QList<Account*> accountsList = AccountsManager::instance()->getAccounts();
foreach( Account *account, accountsList )
{
addAccount( account );
}
// Initially hide the options box
optionsBox_->hide();
// Connect the remaining signals
connect( handleCombobox_, SIGNAL( editTextChanged(const QString&) ),
this, SLOT ( updateView() ) );
#if KDE_IS_VERSION(4,0,70)
connect( handleCombobox_, SIGNAL( returnPressed() ),
connectButton_, SLOT ( animateClick() ) );
#else
connect( handleCombobox_->lineEdit(), SIGNAL( returnPressed() ),
connectButton_, SLOT ( animateClick() ) );
#endif
connect( connectButton_, SIGNAL( clicked() ),
this, SLOT ( slotConnectClicked() ) );
connect( rememberAccountCheckBox_, SIGNAL( stateChanged(int) ),
this, SLOT ( rememberAccountStateChanged(int) ) );
connect( optionsLabel_, SIGNAL( leftClickedUrl(QString) ),
this, SLOT ( toggleOptionsBox() ) );
// When an account is edited, reflect the changes in the accounts list
connect( AccountsManager::instance(), SIGNAL( accountChanged(Account*,QString,QString) ),
this, SLOT ( updateView() ) );
// When (if!) the passwords have been read from the user's password wallet, show them
connect( AccountsManager::instance(), SIGNAL( passwordsReady() ),
this, SLOT ( updateView() ) );
// The status is needed only later
statusLabel_->hide();
// Force an update of the view
setEnabled( true );
updateView();
// Use Solid to find out whether we're connected or not, and apply the status immediately
connect( Solid::Networking::notifier(), SIGNAL( statusChanged(Solid::Networking::Status) ),
this, SLOT ( slotConnectionStatusChanged(Solid::Networking::Status) ) );
slotConnectionStatusChanged( Solid::Networking::status() );
}
// The destructor
InitialView::~InitialView()
{
#ifdef KMESSDEBUG_INITIALVIEW
kDebug() << "DESTROYED.";
#endif
}
// Add an account to the list of displayed accounts from which the user can choose
void InitialView::addAccount(Account *account)
{
const QString &handle = account->getHandle();
// Add account to internal list
accounts_.insert( handle, account );
// Add an entry for the account to the dropdown list
handleCombobox_->addItem( handle );
handleCombobox_->completionObject()->addItem( handle );
// Select the account in the combobox if it's the default account.
if( handle == defaultHandle_ )
{
handleCombobox_->setCurrentItem( defaultHandle_ );
updateView();
}
}
// Modify an account in the list of displayed accounts from which the user can choose
void InitialView::changedAccount( QString oldName, QString newName )
{
if( accounts_[ oldName ] == 0 )
{
return;
}
Account *account = accounts_[ oldName ];
accounts_.remove( oldName );
accounts_.insert( newName, account );
// Change completion box entry
handleCombobox_->completionObject()->removeItem( oldName );
handleCombobox_->completionObject()->addItem( newName );
// Remove account from qcombobox
bool foundItem = false;
for( int i = 0; i < handleCombobox_->count(); i++ )
{
if( handleCombobox_->itemText(i).toLower() == oldName.toLower() )
{
handleCombobox_->removeItem(i);
foundItem = true;
break;
}
}
handleCombobox_->addItem( newName );
if( ! foundItem )
{
kWarning() << "Account not found in pulldown list!";
}
}
/**
* @brief Update the view when the network connection status changes
*
* This method receives KDE's Solid network connection status changes, and updates the view's widgets
* to reflect it.
*
* @param newStatus The new status of the network connection
*/
void InitialView::slotConnectionStatusChanged( Solid::Networking::Status newStatus )
{
// If Solid is unable to retrieve the status, assume we're connected
bool isConnected = ( newStatus == Solid::Networking::Connected || newStatus == Solid::Networking::Unknown );
connectButton_->setEnabled( isConnected );
if( isConnected && ! isConnecting_ )
{
statusLabel_->setVisible( false );
statusMessage( QString() );
}
else
{
if( isConnecting_ )
{
// Force a disconnection
connectButton_->click();
}
statusLabel_->setVisible( true );
statusMessage( i18n("Internet connection not available.") );
}
}
// The account was deleted
void InitialView::deleteAccount(Account *account)
{
// Remove account from hashmap.
QString handle = account->getHandle();
accounts_.remove(handle);
// Remove account from completionbox (extended qlistbox)
handleCombobox_->completionObject()->removeItem( handle );
// Remove account from qcombobox
bool foundItem = false;
for( int i = 0; i < handleCombobox_->count(); i++ )
{
if( handleCombobox_->itemText(i).toLower() == handle.toLower() )
{
handleCombobox_->removeItem(i);
foundItem = true;
break;
}
}
if( ! foundItem )
{
kWarning() << "Account not found in pulldown list!";
}
}
// Get the currently selected handle
QString InitialView::getSelectedHandle() const
{
// Get handle, remove appended friendlyname if present
QString handle = handleCombobox_->currentText();
if( handle.contains(' ') )
{
handle = handle.section(' ', 0, 0);
}
return handle.toLower();
}
// A profile was selected from the drop-down list, or written manually.
void InitialView::updateView()
{
Account *account = accounts_[ getSelectedHandle() ];
if( account != 0 )
{
// User typed the full account name without using autocompletion.
if( account->getPassword().isEmpty() || ! account->getSavePassword() )
{
rememberPasswordCheckBox_->setChecked( false );
passwordEdit_->setText( QString() );
}
else
{
rememberPasswordCheckBox_->setChecked( true );
passwordEdit_->setText( account->getPassword() );
}
// Set the current account picture
QPixmap picture( account->getPicturePath() );
if( ! picture.isNull() )
{
pictureLabel_->setPixmap( picture );
}
rememberAccountCheckBox_->setChecked( ! account->isGuestAccount() );
rememberAccountCheckBox_->setDisabled( ! account->isGuestAccount() );
// Make sure the drop down list matches the user's initial status
int index;
switch( account->getInitialStatus() )
{
case STATUS_AWAY: index = 1; break;
case STATUS_BE_RIGHT_BACK: index = 2; break;
case STATUS_BUSY: index = 3; break;
case STATUS_INVISIBLE: index = 6; break;
case STATUS_ON_THE_PHONE: index = 5; break;
case STATUS_OUT_TO_LUNCH: index = 4; break;
case STATUS_ONLINE:
default: index = 0; break;
}
initialStatus_->setCurrentIndex( index );
}
else
{
// User typed a new account name
// Set the default picture
KStandardDirs *dirs = KGlobal::dirs();
QPixmap picture( dirs->findResource( "data", "kmess/pics/kmesspic.png" ) );
if( ! picture.isNull() )
{
pictureLabel_->setPixmap( picture );
}
// Set the default options
rememberAccountCheckBox_ ->setDisabled( false );
rememberPasswordCheckBox_->setDisabled( false );
rememberAccountCheckBox_ ->setChecked ( true );
rememberPasswordCheckBox_->setChecked ( false );
// Clear password again
passwordEdit_->setText( QString::null );
initialStatus_->setCurrentIndex( 0 );
}
// Put the attention back to the email field
handleCombobox_->setFocus();
}
// Called when "remember account" change its state
void InitialView::rememberAccountStateChanged( int state )
{
if( state == Qt::Unchecked )
{
rememberPasswordCheckBox_->setCheckState( Qt::Unchecked );
rememberPasswordCheckBox_->setEnabled( false );
}
else
{
rememberPasswordCheckBox_->setEnabled( true );
}
}
// Enable or disable the widgets when we're waiting or connecting
void InitialView::setEnabled( bool isEnabled )
{
loginBox_ ->setEnabled( isEnabled );
optionsBox_ ->setEnabled( isEnabled );
optionsLabel_ ->setVisible( isEnabled );
initialStatusLabel_->setEnabled( isEnabled );
initialStatus_ ->setEnabled( isEnabled );
statusLabel_ ->setVisible( ! isEnabled );
// Switch the button's look
if( isEnabled )
{
connectButton_->setText( i18n( "Connect" ) );
connectButton_->setIcon( loader_->loadIcon( "network-connect", KIconLoader::Small, KIconLoader::SizeMedium ) );
}
else
{
connectButton_->setText( i18n( "Disconnect" ) );
connectButton_->setIcon( loader_->loadIcon( "network-disconnect", KIconLoader::Small, KIconLoader::SizeMedium ) );
}
}
// The connect/disconnect button has been clicked
void InitialView::slotConnectClicked()
{
#ifdef KMESSDEBUG_INITIALVIEW
kDebug() << "Connect button clicked," << (isConnecting_?"disconnecting":"connecting");
#endif
// The button was acting as Disconnect button when it was clicked
if( isConnecting_ )
{
isConnecting_ = false;
// Enable back the widgets to allow connecting again
setEnabled( true );
emit disconnectClicked();
return;
}
// The button was acting as Connect button when it was clicked
QString handle = getSelectedHandle();
// Avoid connecting with empty fields
if( handle.isEmpty() || passwordEdit_->text().isEmpty() )
{
return;
}
// Also don't connect if the handle is invalid
if( ! Account::isValidEmail( handle ) )
{
handleCombobox_->setFocus();
return;
}
// Set the UI options for the selected handle
handleCombobox_->setEditText( handle );
isConnecting_ = true;
// Disable the widgets to start connecting
setEnabled( false );
// Save the currently selected account for the next logins
defaultHandle_ = handle;
config_.writeEntry( "defaultHandle", handle );
// Find out what status has been chosen
Status initialStatus;
switch( initialStatus_->currentIndex() )
{
case 1: initialStatus = STATUS_AWAY; break;
case 2: initialStatus = STATUS_BE_RIGHT_BACK; break;
case 3: initialStatus = STATUS_BUSY; break;
case 4: initialStatus = STATUS_OUT_TO_LUNCH; break;
case 5: initialStatus = STATUS_ON_THE_PHONE; break;
case 6: initialStatus = STATUS_INVISIBLE; break;
case 0:
default: initialStatus = STATUS_ONLINE; break;
}
// Inform parent with the account information
emit connectWithAccount( handle, passwordEdit_->text(), rememberAccountCheckBox_->isChecked(),
rememberPasswordCheckBox_->isChecked(), initialStatus );
}
// Start connecting with a specified account
void InitialView::startedConnecting( const QString handle )
{
// Do nothing if an invalid or no account has been selected
if( handle.isEmpty() || ! accounts_.contains( handle ) )
{
#ifdef KMESSDEBUG_INITIALVIEW
kDebug() << "Not updating view for invalid handle" << handle;
#endif
return;
}
#ifdef KMESSDEBUG_INITIALVIEW
kDebug() << "Updating UI for" << handle;
#endif
// Set the UI options for the selected handle
handleCombobox_->setEditText( handle );
isConnecting_ = true;
// Disable the widgets to start connecting
setEnabled( false );
// Save the currently selected account for the next logins
defaultHandle_ = handle;
config_.writeEntry( "defaultHandle", handle );
}
// Change the connection status text
void InitialView::statusMessage( QString text )
{
statusLabel_->setText( text );
}
// Toggle displaying the Options box, which allows remembering accounts & passwords
void InitialView::toggleOptionsBox()
{
if( optionsBox_->isHidden() )
{
optionsBox_->show();
optionsLabel_->setText( i18nc( "Clickable label on login screen", "Less options..." ) );
}
else
{
optionsBox_->hide();
optionsLabel_->setText( i18nc( "Clickable label on login screen", "More options..." ) );
}
}
#include "initialview.moc"