bool KABCPersistence::syncWithKABC( MetaContact * mc ) { kDebug(14010) ; bool contactAdded = false; // check whether the dontShowAgain was checked KABC::AddressBook* ab = addressBook(); KABC::Addressee addr = ab->findByUid( mc->kabcId() ); if ( !addr.isEmpty() ) // if we are associated with KABC { // load the set of addresses from KABC const QStringList customs = addr.customs(); QStringList::ConstIterator it; for ( it = customs.constBegin(); it != customs.constEnd(); ++it ) { QString app, name, value; splitField( *it, app, name, value ); kDebug( 14010 ) << "app=" << app << " name=" << name << " value=" << value; if ( app.startsWith( QLatin1String( "messaging/" ) ) ) { if ( name == QLatin1String( "All" ) ) { kDebug( 14010 ) << " syncing \"" << app << ":" << name << " with contact list "; // Get the protocol name from the custom field // by chopping the 'messaging/' prefix from the custom field app name QString protocolName = app.right( app.length() - 10 ); // munge Jabber hack if ( protocolName == QLatin1String( "xmpp" ) ) protocolName = QLatin1String( "jabber" ); // Check Kopete supports it Protocol * proto = dynamic_cast<Protocol*>( PluginManager::self()->loadPlugin( QLatin1String( "kopete_" ) + protocolName ) ); if ( !proto ) { KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, i18n( "<qt>\"%1\" is not supported by Kopete.</qt>", protocolName ), i18n( "Could Not Sync with KDE Address Book" ) ); continue; } // See if we need to add each contact in this protocol QStringList addresses = value.split( QChar( 0xE000 ), QString::SkipEmptyParts ); QStringList::iterator end = addresses.end(); for ( QStringList::iterator it = addresses.begin(); it != end; ++it ) { // check whether each one is present in Kopete // Is it in the contact list? // First discard anything after an 0xE120, this is used by IRC to separate nick and server group name, but // IRC doesn't support this properly yet, so the user will have to select an appropriate account manually int separatorPos = (*it).indexOf( QChar( 0xE120 ) ); if ( separatorPos != -1 ) *it = (*it).left( separatorPos ); Kopete::MetaContact *otherMc = 0; foreach( Kopete::Account *act, Kopete::AccountManager::self()->accounts() ) { if( act->protocol() != proto ) continue; Kopete::Contact *c= act->contacts().value(*it); if(c) { otherMc=c->metaContact(); break; } } if ( otherMc ) // Is it in another metacontact? { // Is it already in this metacontact? If so, we needn't do anything if ( otherMc == mc ) { kDebug( 14010 ) << *it << " already a child of this metacontact."; continue; } kDebug( 14010 ) << *it << " already exists in OTHER metacontact, move here?"; // find the Kopete::Contact and attempt to move it to this metacontact. otherMc->findContact( proto->pluginId(), QString(), *it )->setMetaContact( mc ); } else { // if not, prompt to add it kDebug( 14010 ) << proto->pluginId() << "://" << *it << " was not found in the contact list. Prompting to add..."; if ( KMessageBox::Yes == KMessageBox::questionYesNo( Kopete::UI::Global::mainWidget(), i18n( "<qt>An address was added to this contact by another application.<br />Would you like to use it in Kopete?<br /><b>Protocol:</b> %1<br /><b>Address:</b> %2</qt>", proto->displayName(), *it ), i18n( "Import Address From Address Book" ), KGuiItem( i18n("Use") ), KGuiItem( i18n("Do Not Use") ), QLatin1String( "ImportFromKABC" ) ) ) { // Check the accounts for this protocol are all connected // Most protocols do not allow you to add contacts while offline // Would be better to have a virtual bool Kopete::Account::readyToAddContact() int accountcount=0; bool allAccountsConnected = true; Kopete::Account *chosen = 0; foreach( Kopete::Account *act, Kopete::AccountManager::self()->accounts() ) { if( act->protocol() == proto) { accountcount++; if(!act->isConnected()) { allAccountsConnected=false; break; } chosen=act; } } if ( !allAccountsConnected ) { KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, i18n( "<qt>One or more of your accounts using %1 are offline. Most systems have to be connected to add contacts. Please connect these accounts and try again.</qt>", protocolName ), i18n( "Not Connected" ) ); continue; } // we have got a contact to add, our accounts are connected, so add it. // Do we need to choose an account if ( accountcount > 1 ) { // if we have >1 account in this protocol, prompt for the protocol. KDialog *chooser = new KDialog(0); chooser->setCaption( i18n("Choose Account") ); chooser->setButtons( KDialog::Ok | KDialog::Cancel ); AccountSelector *accSelector = new AccountSelector(proto, chooser); accSelector->setObjectName( QLatin1String("accSelector") ); chooser->setMainWidget(accSelector); if ( chooser->exec() == QDialog::Rejected ) continue; chosen = accSelector->selectedItem(); delete chooser; } else if ( accountcount == 0 ) { KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, i18n( "<qt>You do not have an account configured for <b>%1</b> yet. Please create an account, connect it, and try again.</qt>", protocolName ), i18n( "No Account Found" ) ); continue; } // add the contact to the chosen account if ( chosen ) { kDebug( 14010 ) << "Adding " << *it << " to " << chosen->accountId(); if ( chosen->addContact( *it, mc ) ) contactAdded = true; else KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, i18n( "<qt>It was not possible to add the contact.</qt>" ), i18n( "Could Not Add Contact") ) ; } } else kDebug( 14010 ) << " user declined to add " << *it << " to contact list "; } } kDebug( 14010 ) << " all " << addresses.count() << " contacts in " << proto->pluginId() << " checked "; } else
void CustomFieldsEditWidget::loadContact( const KABC::Addressee &contact ) { CustomField::List externalCustomFields; CustomField::List globalCustomFields = CustomFieldManager::globalCustomFieldDescriptions(); const QStringList customs = contact.customs(); foreach ( const QString &custom, customs ) { QString app, name, value; splitCustomField( custom, app, name, value ); // skip all well-known fields that have separated editor widgets if ( custom.startsWith( QLatin1String( "messaging/" ) ) ) { // IM addresses continue; } if ( app == QLatin1String( "KADDRESSBOOK" ) ) { static QSet<QString> blacklist; if ( blacklist.isEmpty() ) { blacklist << QLatin1String( "BlogFeed" ) << QLatin1String( "X-IMAddress" ) << QLatin1String( "X-Profession" ) << QLatin1String( "X-Office" ) << QLatin1String( "X-ManagersName" ) << QLatin1String( "X-AssistantsName" ) << QLatin1String( "X-Anniversary" ) << QLatin1String( "X-ANNIVERSARY" ) << QLatin1String( "X-SpousesName" ) << QLatin1String( "X-Profession" ) << QLatin1String( "MailPreferedFormatting") << QLatin1String( "MailAllowToRemoteContent") << QLatin1String( "CRYPTOPROTOPREF" ) << QLatin1String( "OPENPGPFP" ) << QLatin1String( "SMIMEFP" ) << QLatin1String( "CRYPTOSIGNPREF" ) << QLatin1String( "CRYPTOENCRYPTPREF" ); } if ( blacklist.contains( name ) ) { // several KAddressBook specific fields continue; } } // check whether it correspond to a local custom field bool isLocalCustomField = false; for ( int i = 0; i < mLocalCustomFields.count(); ++i ) { if ( mLocalCustomFields[ i ].key() == name ) { mLocalCustomFields[ i ].setValue( value ); isLocalCustomField = true; break; } } // check whether it correspond to a global custom field bool isGlobalCustomField = false; for ( int i = 0; i < globalCustomFields.count(); ++i ) { if ( globalCustomFields[ i ].key() == name ) { globalCustomFields[ i ].setValue( value ); isGlobalCustomField = true; break; } } // if not local and not global it must be external if ( !isLocalCustomField && !isGlobalCustomField ) { if ( app == QLatin1String( "KADDRESSBOOK" ) ) { // however if it starts with our prefix it might be that this is an outdated // global custom field, in this case treat it as local field of type text CustomField customField( name, name, CustomField::TextType, CustomField::LocalScope ); customField.setValue( value ); mLocalCustomFields << customField; } else { // it is really an external custom field const QString key = app + QLatin1Char( '-' ) + name; CustomField customField( key, key, CustomField::TextType, CustomField::ExternalScope ); customField.setValue( value ); externalCustomFields << customField; } } }