void AIMContact::userInfoUpdated( const QString& contact, const UserDetails& details )
{
    if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
        return;

    kDebug(OSCAR_ICQ_DEBUG) << contact;

    //if they don't have an SSI alias, make sure we use the capitalization from the
    //server so their contact id looks all pretty.
    QString nickname = property( Kopete::Global::Properties::self()->nickName() ).value().toString();
    if ( nickname.isEmpty() || Oscar::normalize( nickname ) == Oscar::normalize( contact ) )
        setNickName( contact );

    kDebug( OSCAR_ICQ_DEBUG ) << "extendedStatus is " << details.extendedStatus();
    Oscar::Presence presence = mProtocol->statusManager()->presenceOf( details.extendedStatus(), details.userClass() );
    setPresenceTarget( presence );

    m_mobile = ( presence.flags() & Oscar::Presence::Wireless );

    setAwayMessage( details.personalMessage() );
    if ( presence.type() != Oscar::Presence::Online && m_details.awaySinceTime() < details.awaySinceTime() ) //prevent cyclic away message requests
    {
        mAccount->engine()->requestAIMAwayMessage( contactId() );
    }

    OscarContact::userInfoUpdated( contact, details );
}
Exemple #2
0
void
PeerInfo::setAvatar( const QPixmap& avatar )
{
    Q_D( PeerInfo );

    QByteArray ba;
    QBuffer buffer( &ba );
    buffer.open( QIODevice::WriteOnly );
    avatar.save( &buffer, "PNG" );

    // Check if the avatar is different by comparing a hash of the first 4096 bytes
    const QByteArray hash = QCryptographicHash::hash( ba.left( 4096 ), QCryptographicHash::Sha1 );
    if ( d->avatarHash == hash )
        return;

    d->avatarHash = hash;
    d->avatarBuffer = ba;

    delete d->avatar;
    delete d->fancyAvatar;
    d->avatar = 0;
    d->fancyAvatar = 0;

    Q_ASSERT( !contactId().isEmpty() );
    TomahawkUtils::Cache::instance()->putData( "Sources", 7776000000 /* 90 days */, contactId(), ba );
}
void AIMContact::requestBuddyIcon()
{
	kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Updating buddy icon for " << contactId() << endl;
	if ( m_details.buddyIconHash().size() > 0 )
	{
		account()->engine()->requestBuddyIcon( contactId(), m_details.buddyIconHash(),
		                                       m_details.iconCheckSumType() );
	}
}
Exemple #4
0
const QPixmap
PeerInfo::avatar( TomahawkUtils::ImageMode style, const QSize& size ) const
{
    Q_D( const PeerInfo );

    if ( !d->avatar )
    {
        tDebug() << "Avatar for:" << id();
        Q_ASSERT( !contactId().isEmpty() );
        if ( d->avatarBuffer.isEmpty() && !contactId().isEmpty() )
            d->avatarBuffer = TomahawkUtils::Cache::instance()->getData( "Sources", contactId() ).toByteArray();

        d->avatar = new QPixmap();
        if ( !d->avatarBuffer.isEmpty() )
            d->avatar->loadFromData( d->avatarBuffer );

        d->avatarBuffer.clear();
    }

    if ( style == TomahawkUtils::RoundedCorners && d->avatar && !d->avatar->isNull() && !d->fancyAvatar )
        d->fancyAvatar = new QPixmap( TomahawkUtils::createRoundedImage( QPixmap( *d->avatar ), QSize( 0, 0 ) ) );

    QPixmap pixmap;
    if ( style == TomahawkUtils::RoundedCorners && d->fancyAvatar )
    {
        pixmap = *d->fancyAvatar;
    }
    else if ( d->avatar && !d->avatar->isNull() )
    {
        pixmap = *d->avatar;
    }

    if ( !pixmap.isNull() && !size.isEmpty() )
    {
        if ( d->coverCache[ style ].contains( size.width() ) )
        {
            return d->coverCache[ style ].value( size.width() );
        }

        QPixmap scaledCover;
        scaledCover = pixmap.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );

        QHash< int, QPixmap > innerCache = d->coverCache[ style ];
        innerCache.insert( size.width(), scaledCover );
        d->coverCache[ style ] = innerCache;

        return scaledCover;
    }

    return pixmap;
}
void AIMContact::haveIcon( const QString& user, QByteArray icon )
{
	if ( Oscar::normalize( user ) != Oscar::normalize( contactId() ) )
		return;

	kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Updating icon for " << contactId() << endl;
	QImage buddyIcon( icon );
	if ( buddyIcon.isNull() )
	{
		kdWarning(OSCAR_AIM_DEBUG) << k_funcinfo << "Failed to convert buddy icon to QImage" << endl;
		return;
	}

	setProperty( Kopete::Global::Properties::self()->photo(), buddyIcon );
}
void AIMContact::updateAwayMessage( const QString& contact, const QString& message )
{
	if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
		return;
	else
	{
		if ( message.isEmpty() )
		{
			removeProperty( mProtocol->awayMessage );
			if ( !m_mobile )
				setOnlineStatus( mProtocol->statusOnline );
			else
				setOnlineStatus( mProtocol->statusWirelessOnline );
			m_haveAwayMessage = false;
		}
		else
		{
			m_haveAwayMessage = true;
			setAwayMessage( message );
			if ( !m_mobile )
				setOnlineStatus( mProtocol->statusAway );
			else
				setOnlineStatus( mProtocol->statusWirelessAway );
		}
	}

	emit updatedProfile();
}
void WlmContact::slotUserInfo()
{
    QPointer <KDialog> infoDialog = new KDialog;
    infoDialog->setButtons( KDialog::Close);
    infoDialog->setDefaultButton(KDialog::Close);
    const QString name = displayName();
    const QString personalMessage = statusMessage().message();
    Ui::WLMInfo info;
    info.setupUi(infoDialog->mainWidget());
    info.m_id->setText(contactId());
    info.m_displayName->setText(name);
    info.m_personalMessage->setText(personalMessage);
//     info.m_phh->setText(m_phoneHome); //TODO enable and fill
//     info.m_phw->setText(m_phoneWork);
//     info.m_phm->setText(m_phoneMobile);
//     info.m_reversed->setChecked(m_reversed);

//     connect( info.m_reversed, SIGNAL(toggled(bool)) , this, SLOT(slotUserInfoDialogReversedToggled()));

    info.groupBox->setVisible(false);
    info.m_reversed->setVisible(false);

    infoDialog->setCaption(name);
    infoDialog->exec();
    delete infoDialog;
}
void WlmContact::blockContact(bool block)
{
    if (!m_account->isConnected())
        return;

    m_account->blockContact(contactId(), block);
}
Exemple #9
0
/**
 * JabberContact constructor
 */
JabberContact::JabberContact (const XMPP::RosterItem &rosterItem, Kopete::Account *_account, Kopete::MetaContact * mc, const QString &legacyId)
	: JabberBaseContact ( rosterItem, _account, mc, legacyId)  , mDiscoDone(false), m_syncTimer(0L)
{
	kDebug(JABBER_DEBUG_GLOBAL) << contactId() << "  is created  - " << this;
	// this contact is able to transfer files
	setFileCapable ( true );

	/*
	 * Catch when we're going online for the first time to
	 * update our properties from a vCard. (properties are
	 * not available during startup, so we need to read
	 * them later - this also serves as a random update
	 * feature)
	 * Note: The only time account->myself() could be a
	 * NULL pointer is if this contact here is the myself()
	 * instance itself. Since in that case we wouldn't
	 * get updates at all, we need to treat that as a
	 * special case.
	 */

	mVCardUpdateInProgress = false;

	if ( !account()->myself () )
	{
		// this contact is a regular contact
		connect ( this,
				  SIGNAL (onlineStatusChanged(Kopete::Contact*,Kopete::OnlineStatus,Kopete::OnlineStatus)),
				  this, SLOT (slotCheckVCard()) );
	}
Exemple #10
0
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    KLocalizedString::setApplicationDomain("ktp-log-viewer");

    KAboutData aboutData("ktp-log-viewer",
                         i18n("KDE IM Log Viewer"),
                         QStringLiteral(KTP_TEXT_UI_VERSION_STRING));
    aboutData.addAuthor(i18n("David Edmundson"), i18n("Developer"), "*****@*****.**");
    aboutData.addAuthor(i18n("Daniele E. Domenichelli"), i18n("Developer"), "*****@*****.**");
    aboutData.addAuthor(i18n("Dan Vrátil"), i18n("Developer"), "*****@*****.**");
    aboutData.setProductName("telepathy/log-viewer"); //set the correct name for bug reporting
    aboutData.setOrganizationDomain(QByteArray("kde.org"));
    aboutData.setLicense(KAboutLicense::GPL_V2);

    KAboutData::setApplicationData(aboutData);

    // register to DBus
    const KDBusService dbusService(KDBusService::Multiple);

    QCommandLineParser parser;
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption accountId(QStringLiteral("accountID"), i18n("The UID of the account to preselect"));
    QCommandLineOption contactId(QStringLiteral("contactID"), i18n("The UID of the contact to preselect"));

    parser.addOption(accountId);
    parser.addOption(contactId);

    parser.process(app);

    Tp::registerTypes();

    Tp::AccountFactoryPtr  accountFactory = Tp::AccountFactory::create(
                                                QDBusConnection::sessionBus(),
                                                Tp::Features() << Tp::Account::FeatureCore
                                                    << Tp::Account::FeatureAvatar
                                                    << Tp::Account::FeatureProfile);

    Tp::ConnectionFactoryPtr connectionFactory = Tp::ConnectionFactory::create(
                                                QDBusConnection::sessionBus(),
                                                Tp::Features() << Tp::Connection::FeatureCore
                                                    << Tp::Connection::FeatureSelfContact
                                                    << Tp::Connection::FeatureRoster);

    Tp::ContactFactoryPtr contactFactory = KTp::ContactFactory::create(
                                                Tp::Features()  << Tp::Contact::FeatureAlias
                                                    << Tp::Contact::FeatureAvatarData
                                                    << Tp::Contact::FeatureSimplePresence
                                                    << Tp::Contact::FeatureCapabilities);

    Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(QDBusConnection::sessionBus());

    LogViewer *logViewer = new LogViewer(accountFactory, connectionFactory, channelFactory, contactFactory);
    logViewer->show();

    return app.exec();
}
void AIMContact::userOnline( const QString& userId )
{
	if ( Oscar::normalize( userId ) == Oscar::normalize( contactId() ) )
	{
		kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Getting more contact info" << endl;
		setOnlineStatus( mProtocol->statusOnline );
	}
}
void AIMContact::updateProfile( const QString& contact, const QString& profile )
{
	if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
		return;

	setProperty( mProtocol->clientProfile, profile );
	emit updatedProfile();
}
void AIMContact::userOffline( const QString& userId )
{
	if ( Oscar::normalize( userId ) == Oscar::normalize( contactId() ) )
	{
		setOnlineStatus( mProtocol->statusOffline );
		removeProperty( mProtocol->awayMessage );
	}
}
void AIMContact::userOnline( const QString& userId )
{
	if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) )
		return;

	kDebug(OSCAR_ICQ_DEBUG) << "Setting " << userId << " online";
	setPresenceTarget( Oscar::Presence( Oscar::Presence::Online, Oscar::Presence::AIM ) );
}
void AIMContact::gotWarning( const QString& contact, Q_UINT16 increase, Q_UINT16 newLevel )
{
	//somebody just got bitchslapped! :O
	Q_UNUSED( increase );
	if ( Oscar::normalize( contact ) == Oscar::normalize( contactId() ) )
		m_warningLevel = newLevel;

	//TODO add a KNotify event after merge to HEAD
}
void AIMContact::slotUserInfo()
{
	if ( !m_infoDialog)
	{
		m_infoDialog = new AIMUserInfoDialog( this, static_cast<AIMAccount*>( account() ), false, Kopete::UI::Global::mainWidget(), 0 );
		if( !m_infoDialog )
			return;
		connect( m_infoDialog, SIGNAL( finished() ), this, SLOT( closeUserInfoDialog() ) );
		m_infoDialog->show();
		if ( mAccount->isConnected() )
		{
			mAccount->engine()->requestAIMProfile( contactId() );
			mAccount->engine()->requestAIMAwayMessage( contactId() );
		}
	}
	else
		m_infoDialog->raise();
}
void AIMContact::warnUser()
{
	QString nick = property( Kopete::Global::Properties::self()->nickName() ).value().toString();
	QString message = i18n( "<qt>Would you like to warn %1 anonymously or with your name?<br>" \
	                        "(Warning a user on AIM will result in a \"Warning Level\"" \
	                        " increasing for the user you warn. Once this level has reached a" \
	                        " certain point, they will not be able to sign on. Please do not abuse" \
	                        " this function, it is meant for legitimate practices.)</qt>" ).arg( nick );


	int result = KMessageBox::questionYesNoCancel( Kopete::UI::Global::mainWidget(), message,
	                                               i18n( "Warn User %1?" ).arg( nick ),
	                                               i18n( "Warn Anonymously" ), i18n( "Warn" ) );

	if ( result == KMessageBox::Yes )
		mAccount->engine()->sendWarning( contactId(), true);
	else if ( result == KMessageBox::No )
		mAccount->engine()->sendWarning( contactId(), false);
}
bool CntSimStorePrivate::read(int index, int numSlots, QContactManager::Error *error)
{
    if (IsActive()) {
        *error = QContactManager::LockedError;
        return false;
    }
    
    // ON store requires different read approach.
    // fetch ON contacts synchronously since there are usually only couple of them  
    if (m_storeInfo.m_storeName == KParameterValueSimStoreNameOn) {

        TRequestStatus status;
        QList<QContact> fetchedContacts; 
        for (int i = index; i <= numSlots; i++) {
            RMobileONStore::TMobileONEntryV1 onEntry;
            onEntry.iIndex = i;         
            RMobileONStore::TMobileONEntryV1Pckg onEntryPkg(onEntry);
            m_etelOnStore.Read(status, onEntryPkg);
            User::WaitForRequest(status);
            if (status.Int() == KErrNone) {
                QContact c;
                c.setType(QContactType::TypeContact);
                QContactName name;
                name.setCustomLabel(QString::fromUtf16(onEntry.iText.Ptr(),
                        onEntry.iText.Length()));
                c.saveDetail(&name);
                
                QContactPhoneNumber number;
                number.setNumber(QString::fromUtf16(onEntry.iNumber.iTelNumber.Ptr(),
                        onEntry.iNumber.iTelNumber.Length()));
                c.saveDetail(&number);
                
                QScopedPointer<QContactId> contactId(new QContactId());
                contactId->setLocalId(i);
                contactId->setManagerUri(m_managerUri);
                c.setId(*contactId);
                fetchedContacts.append(c);
            }
        }
        emit m_simStore.readComplete(fetchedContacts, QContactManager::NoError);
        *error = QContactManager::NoError;
        return true;
    }        
    
    // start reading
    m_buffer.Zero();
    m_buffer.ReAlloc(KOneSimContactBufferSize*numSlots);
    m_etelStore.Read(iStatus, index, numSlots, m_buffer);
    
    SetActive();
    m_state = ReadState;
    
    *error = QContactManager::NoError;
    return true;
}
KMenu* Contact::popupMenu()
{
	KMenu *menu = new KMenu();

	QString titleText;
	const QString nick = nickName();
	if( nick == contactId() )
		titleText = QString::fromLatin1( "%1 (%2)" ).arg( contactId(), onlineStatus().description() );
	else
		titleText = QString::fromLatin1( "%1 <%2> (%3)" ).arg( nick, contactId(), onlineStatus().description() );
	menu->addTitle( titleText );

	if( metaContact() && metaContact()->isTemporary() && contactId() != account()->myself()->contactId() )
	{
		KAction *actionAddContact = new KAction( KIcon("list-add-user"), i18n( "&Add to Your Contact List" ), menu );
		connect( actionAddContact, SIGNAL(triggered(bool)), this, SLOT(slotAddContact()) );

		menu->addAction(actionAddContact);
		menu->addSeparator();
	}
void FacebookContact::setDisplayPicture( const QImage &image )
{
    Kopete::AvatarManager::AvatarEntry entry;
    entry.name = contactId();
    entry.category = Kopete::AvatarManager::Contact;
    entry.contact = this;
    entry.image = image;
    entry = Kopete::AvatarManager::self()->add(entry);
    removeProperty (Kopete::Global::Properties::self()->photo ());
    setProperty (Kopete::Global::Properties::self()->photo (), image);
    //emit displayPictureChanged();
}
void AIMContact::userInfoUpdated( const QString& contact, const UserDetails& details )
{
	if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
		return;

	kDebug(OSCAR_ICQ_DEBUG) << contact;

	setNickName( contact );

	kDebug( OSCAR_ICQ_DEBUG ) << "extendedStatus is " << details.extendedStatus();
	Oscar::Presence presence = mProtocol->statusManager()->presenceOf( details.extendedStatus(), details.userClass() );
	setPresenceTarget( presence );

	m_mobile = ( presence.flags() & Oscar::Presence::Wireless );

	setAwayMessage( details.personalMessage() );
	if ( presence.type() != Oscar::Presence::Online && m_details.awaySinceTime() < details.awaySinceTime() ) //prevent cyclic away message requests
	{
		mAccount->engine()->requestAIMAwayMessage( contactId() );
	}

	OscarContact::userInfoUpdated( contact, details );
}
void AIMContact::setAwayMessage(const QString &message)
{
	kdDebug(14152) << k_funcinfo <<
		"Called for '" << contactId() << "', away msg='" << message << "'" << endl;
	QString filteredMessage = message;
	filteredMessage.replace(
		QRegExp(QString::fromLatin1("<[hH][tT][mM][lL].*>(.*)</[hH][tT][mM][lL]>")),
		QString::fromLatin1("\\1"));
	filteredMessage.replace(
		QRegExp(QString::fromLatin1("<[bB][oO][dD][yY].*>(.*)</[bB][oO][dD][yY]>")),
		QString::fromLatin1("\\1") );
	QRegExp fontRemover( QString::fromLatin1("<[fF][oO][nN][tT].*>(.*)</[fF][oO][nN][tT]>") );
	fontRemover.setMinimal(true);
	while ( filteredMessage.find( fontRemover ) != -1 )
		filteredMessage.replace( fontRemover, QString::fromLatin1("\\1") );
	setProperty(mProtocol->awayMessage, filteredMessage);
}
void
WlmContact::deleteContact ()
{
    if (account ()->isConnected ())
    {
        qobject_cast <WlmAccount *>(account ())->server ()->mainConnection->
            delFromAddressBook (m_contactSerial.toLatin1 ().constData (), contactId ().toLatin1 ().constData ());
        deleteLater ();
    }
    else
    {
        KMessageBox::error (Kopete::UI::Global::mainWidget (),
                            i18n
                            ("<qt>You need to go online to remove a contact from your contact list. This contact will appear again when you reconnect.</qt>"),
                            i18n ("WLM Plugin"));
    }
}
void
WlmContact::slotUpdateDisplayPicture()
{
    if(!account()->isConnected())
        return;

	WlmAccount* acc = qobject_cast<WlmAccount*>(account());
    if(!acc)
        return;

    if ((onlineStatus() != WlmProtocol::protocol ()->wlmOffline)
           && (onlineStatus() != WlmProtocol::protocol ()->wlmInvisible)
           && (onlineStatus() != WlmProtocol::protocol ()->wlmUnknown))
    {
        acc->chatManager ()->requestDisplayPicture (contactId());
    }

}
QList < KAction * >* WlmContact::customContextMenuActions ()     //OBSOLETE
{
    QList<KAction*> *actions = new QList<KAction*>();

    m_actionBlockContact->setEnabled(m_account->isConnected());
    m_actionBlockContact->setChecked(m_account->isContactBlocked(contactId()));
    actions->append(m_actionBlockContact);
    actions->append(m_actionShowProfile);
    actions->append(m_actionUpdateDisplayPicture);
    actions->append(m_actionDontShowEmoticons);

    // temporary action collection, used to apply Kiosk policy to the actions
    KActionCollection tempCollection((QObject*)0);
    tempCollection.addAction(QLatin1String("contactBlock"), m_actionBlockContact);
    tempCollection.addAction(QLatin1String("contactViewProfile"), m_actionShowProfile);
    tempCollection.addAction(QLatin1String("updateDisplayPicture"), m_actionUpdateDisplayPicture);
    tempCollection.addAction(QLatin1String("dontShowEmoticons"), m_actionDontShowEmoticons);

    return actions;
}
/*!
    \qmlproperty url Contact::thumbnail

    This property holds the thumbnail URL of the Contact object.
*/
QUrl QDeclarativeContact::thumbnail() const
{
    //Just let the imager provider deal with it
    return QUrl(QString("image://thumbnail/%1.%2").arg(manager()).arg(contactId()).toLatin1());
}
/*! Parses SIM contacts in TLV format.
 *
 * \param rawData SIM contacts in TLV format.
 * \return List of contacts.
*/
QList<QContact> CntSimStorePrivate::decodeSimContactsL(TDes8& rawData) const
{
    PbkPrintToLog(_L("CntSymbianSimEngine::decodeSimContactsL() - IN"));
    QList<QContact> fetchedContacts;
    QContact currentContact;

    TBuf16<KDataClientBuf> buffer;
    TPtrC16 bufPtr(buffer);

    TUint8 tagValue(0);
    CPhoneBookBuffer::TPhBkTagType dataType;

    bool isAdditionalNumber = false;

    CPhoneBookBuffer* pbBuffer = new(ELeave) CPhoneBookBuffer();
    CleanupStack::PushL(pbBuffer);
    pbBuffer->Set(&rawData);
    pbBuffer->StartRead();

    while (pbBuffer->GetTagAndType(tagValue, dataType) == KErrNone) {
        switch (tagValue)
        {
            case RMobilePhoneBookStore::ETagPBAdnIndex:
            {
                //save contact's id (SIM card index) and manager's name
                TUint16  index;
                if (pbBuffer->GetValue(index) == KErrNone) {
                    QScopedPointer<QContactId> contactId(new QContactId());
                    contactId->setLocalId(index);
                    contactId->setManagerUri(m_managerUri);
                    currentContact.setId(*contactId);
                }
                isAdditionalNumber = false;
                break;
            }
            case RMobilePhoneBookStore::ETagPBTonNpi:
            {
                // Note, that TON info can be incorporated into the phone number by Etel
                // implementation (TSY). E.g. this is the case with Nokia TSY.
                // Here general case is implemented.

                // Check number type, we are only interested if it's international or not.
                // We assume here that ETagPBTonNpi always comes after ETagPBNumber, not before.
                TUint8  tonNpi;
                if (pbBuffer->GetValue(tonNpi) == KErrNone) {
                    TUint8  intFlag = (tonNpi & KEtsiTonPosition) >> 4;
                    if (intFlag == 1) {
                        //international number format, append "+" to the last
                        //saved number
                        QList<QContactDetail> phoneNumbers = currentContact.details(
                                QContactPhoneNumber::DefinitionName);
                        if (phoneNumbers.count() > 0) {
                            QContactPhoneNumber lastNumber = static_cast<QContactPhoneNumber>(
                                phoneNumbers.at(phoneNumbers.count() - 1));
                            QString number = lastNumber.number();
                            number.insert(0, "+");
                            lastNumber.setNumber(number);
                            if (m_storeInfo.m_readOnlyAccess)
                                m_engine.setReadOnlyAccessConstraint(&lastNumber);
                            currentContact.saveDetail(&lastNumber);
                        }
                    }
                }

                // We have rearched to the end of the number,
                // invalidate additional number flag.
                isAdditionalNumber = false;
                break;
            }
            case RMobilePhoneBookStore::ETagPBText:
            {
                if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                    if (isAdditionalNumber) {
                        // For additional number bufPtr contains number alpha string,
                        // this is ignored currently
                    }
                    else {
                        // Contact name otherwise
                        QContactName name;
                        QString nameString = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                        name.setCustomLabel(nameString);
                        if (m_storeInfo.m_readOnlyAccess)
                            m_engine.setReadOnlyAccessConstraint(&name);
                        currentContact.saveDetail(&name);
                        QContactManager::Error error(QContactManager::NoError);
                        m_engine.setContactDisplayLabel(&currentContact, m_engine.synthesizedDisplayLabel(currentContact, &error));
                    }
                }
                break;
            }
            case RMobilePhoneBookStore::ETagPBSecondName:
            {
                if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                    QContactNickname nickName;
                    QString name = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                    nickName.setNickname(name);
                    if (m_storeInfo.m_readOnlyAccess)
                        m_engine.setReadOnlyAccessConstraint(&nickName);
                    currentContact.saveDetail(&nickName);
                }
                break;
            }
            case RMobilePhoneBookStore::ETagPBNumber:
            {
                if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                    QContactPhoneNumber phoneNumber;
                    QString number = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                    phoneNumber.setNumber(number);
                    if (m_storeInfo.m_readOnlyAccess)
                        m_engine.setReadOnlyAccessConstraint(&phoneNumber);
                    currentContact.saveDetail(&phoneNumber);
                }
                break;
            }
            case RMobilePhoneBookStore::ETagPBAnrStart:
            {
                // This tag should precede every additional number entry
                isAdditionalNumber = true;
                break;
            }
            case RMobilePhoneBookStore::ETagPBEmailAddress:
            {
                if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                    QContactEmailAddress email;
                    QString emailAddress = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                    email.setEmailAddress(emailAddress);
                    if (m_storeInfo.m_readOnlyAccess)
                        m_engine.setReadOnlyAccessConstraint(&email);
                    currentContact.saveDetail(&email);
                }
                break;
            }
            case RMobilePhoneBookStore::ETagPBNewEntry:
            {
                // This signals the end of the entry and is a special case
                // which will be handled below.
                break;
            }
            default:
            {
                // An unsupported field type - just skip this value
                pbBuffer->SkipValue(dataType);
                break;
            }
        } //switch

        // save contact to the array of contact to be returned if the whole entry was extracted
        if ((tagValue == RMobilePhoneBookStore::ETagPBNewEntry && currentContact.localId() > 0) ||
            (pbBuffer->RemainingReadLength() == 0 && currentContact.localId() > 0)) {
            fetchedContacts.append(currentContact);
            //clear current contact
            currentContact.clearDetails();
            QScopedPointer<QContactId> contactId(new QContactId());
            contactId->setLocalId(0);
            contactId->setManagerUri(QString());
            currentContact.setId(*contactId);
        }
    } //while
void AIMContact::slotInvisibleTo()
{
	account()->engine()->setInvisibleTo( contactId(), m_actionInvisibleTo->isChecked() );
}
void AIMContact::userInfoUpdated( const QString& contact, const UserDetails& details )
{
	if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
		return;

	kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << contact << endl;

	//if they don't have an SSI alias, make sure we use the capitalization from the
	//server so their contact id looks all pretty.
	QString nickname = property( Kopete::Global::Properties::self()->nickName() ).value().toString();
	if ( nickname.isEmpty() || Oscar::normalize( nickname ) == Oscar::normalize( contact ) )
		setNickName( contact );

	( details.userClass() & CLASS_WIRELESS ) ? m_mobile = true : m_mobile = false;

	if ( ( details.userClass() & CLASS_AWAY ) == STATUS_ONLINE )
	{
		if ( m_mobile ) 
		{
			kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is mobile-online." << endl;
			setOnlineStatus( mProtocol->statusWirelessOnline );
    	}
		else 
		{
			kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is online." << endl;
			setOnlineStatus( mProtocol->statusOnline ); //we're online
		}
		removeProperty( mProtocol->awayMessage );
		m_haveAwayMessage = false;
	}
	else if ( ( details.userClass() & CLASS_AWAY ) ) // STATUS_AWAY
	{
		if ( m_mobile ) 
		{
			kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is mobile-away." << endl;
			setOnlineStatus( mProtocol->statusWirelessOnline );
		}
		else 
		{
			kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is away." << endl;
			setOnlineStatus( mProtocol->statusAway ); //we're away
		}
		if ( !m_haveAwayMessage ) //prevent cyclic away message requests
		{
			mAccount->engine()->requestAIMAwayMessage( contactId() );
			m_haveAwayMessage = true;
		}
	}
	else
	{
        kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " class " << details.userClass() << " is unhandled... defaulting to away." << endl;
		setOnlineStatus( mProtocol->statusAway ); //we're away
		if ( !m_haveAwayMessage ) //prevent cyclic away message requests
		{
			mAccount->engine()->requestAIMAwayMessage( contactId() );
			m_haveAwayMessage = true;
		}
	}

	if ( details.buddyIconHash().size() > 0 && details.buddyIconHash() != m_details.buddyIconHash() )
	{
        if ( !mAccount->engine()->hasIconConnection() )
            mAccount->engine()->requestServerRedirect( 0x0010 );

		int time = ( KApplication::random() % 10 ) * 1000;
		kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "updating buddy icon in " << time/1000 << " seconds" << endl;
		QTimer::singleShot( time, this, SLOT( requestBuddyIcon() ) );
	}

	OscarContact::userInfoUpdated( contact, details );
}
void AIMContact::slotIgnore()
{
	account()->engine()->setIgnore( contactId(), m_actionIgnore->isChecked() );
}